diff options
author | Graydon Hoare <graydon@redhat.com> | 2004-10-04 16:45:49 +0000 |
---|---|---|
committer | Graydon Hoare <graydon@redhat.com> | 2004-10-04 16:45:49 +0000 |
commit | 03f0d7f95f40e80a68a48b5da7842c6a9291007b (patch) | |
tree | 46d8c59127cd9ee8ed30ebe951128559fefe1b56 /libjava | |
parent | 2f8ae58586a073d773e55876f308befff072d4a3 (diff) |
2004-09-30 Graydon Hoare <graydon@redhat.com>
* Makefile.am
(jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c)
(jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.c)
(gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java)
(gnu/java/awt/peer/gtk/GdkClasspathFontPeerMetrics.java): Remove.
(jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c)
(jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c)
(gnu/java/awt/peer/gtk/GdkTextLayout.java)
(gnu/java/awt/peer/gtk/GdkFontPeer.java)
(gnu/java/awt/peer/ClasspathTextLayoutPeer.java): Add
* Makefile.in: Regenerate.
* gnu/awt/xlib/XToolkit.java
(getClasspathTextLayoutPeer): Add stub.
* gnu/java/awt/ClasspathToolkit.java
(getClasspathTextLayoutPeer) Add.
* gnu/java/awt/peer/ClasspathFontPeer.java
(copyStyleToAttrs)
(copySizeToAttrs): Make public.
* gnu/java/awt/peer/ClasspathTextLayoutPeer.java: New file.
* gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java: Remove.
* gnu/java/awt/peer/gtk/GdkClasspathFontPeerMetrics.java: Remove.
* gnu/java/awt/peer/gtk/GdkFontMetrics.java: Rewrite.
* gnu/java/awt/peer/gtk/GdkFontPeer.java: New file.
* gnu/java/awt/peer/gtk/GdkGlyphVector.java: Adjust type names.
* gnu/java/awt/peer/gtk/GdkGraphics.java
(getFontPeer): New function.
(drawString): Pass font peer to native side.
* gnu/java/awt/peer/gtk/GdkGraphics2D.java
(cairoSetFont)
(cairoShowGlyphs)
(PainterThread): Remove.
(GdkGraphics2D): Set hints during construction.
(shifted)
(walkPath)
(draw)
(setRenderingHint)
(setRenderingHints): Reimplement normalization logic.
(getDefaultHints)
(updateBufferedImage)
(isBufferedImageGraphics)
(updateImagePixels)
(drawImage): Make final.
(drawImage): Always paint synchronously.
(drawString)
(drawGlyphVector): Rewrite.
(releasePeerGraphicResource)
(getPeerTextMetrics)
(getPeerFontMetrics)
(drawGdkGlyphVector)
(drawGdkTextLayout)
(cairoDrawGdkGlyphVector)
(cairoDrawGdkTextLayout)
(cairoDrawString)
(getFontPeer): New functions.
* gnu/java/awt/peer/gtk/GdkTextLayout.java: New file.
* gnu/java/awt/peer/gtk/GtkComponentPeer.java
(getFontMetrics): Get metrics via toolkit, to hit cache.
* gnu/java/awt/peer/gtk/GtkTextAreaPeer.java: Use getFontMetrics.
* gnu/java/awt/peer/gtk/GtkTextFieldPeer.java: Likewise.
* gnu/java/awt/peer/gtk/GtkToolkit.java (LRUCache): New class.
(fontCache)
(metricsCache)
(imageCache): New members.
(getFontMetrics)
(getImage)
(getClasspathFontPeer): Use caches.
(getFontPeer): Route through getClasspathFontPeer.
* java/awt/Font.java (attrsToMap): Remove, adjust ctors.
* java/awt/font/TextLayout.java: Implement in terms of peer.
* javax/swing/plaf/basic/BasicSliderUI.java
(paintThumb): Use polyline rather than polygon.
* javax/swing/plaf/basic/BasicGraphicsUtils.java:
Update comment but, alas, still do not switch to using TextLayouts.
* javax/swing/text/Utilities.java (drawTabbedText):
Draw text run-at-a-time, not char-at-a-time.
* jni/gtk-peer/gdkfont.h: Publicize some of the font interface, add
layout table.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c:
* jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.c:
Remove files.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontMetrics.c: Rewrite to
incorporate brains of old GdkClasspathFontPeerMetrics.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c: Rewrite to
incorporate brains of old GdkClasspathFontPeer.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c: New file.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c
(drawString): Rewrite to use persistent layout in peer font.
Comment out extraneous gdk_flush calls.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
(metrics_cairo)
(metrics_surface): New static variables.
(paint_glyph_run)
(install_font_peer): New helper functions.
(releasePeerGraphicResource)
(getPeerTextMetrics)
(getPeerFontMetrics)
(cairoDrawGdkTextLayout)
(cairoDrawGdkGlyphVector): New native methods.
(cairoDrawString): Rewrite, leaving layout-based version
commented out for the time being.
* jni/gtk-peer/gtkpeer.h (graphics): Add fields for pango stuff.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/java-gui-branch@88515 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava')
31 files changed, 1890 insertions, 1148 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 872a8ebb890..55f1076f9f9 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,107 @@ +2004-09-30 Graydon Hoare <graydon@redhat.com> + + * Makefile.am + (jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c) + (jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.c) + (gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java) + (gnu/java/awt/peer/gtk/GdkClasspathFontPeerMetrics.java): Remove. + (jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c) + (jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c) + (gnu/java/awt/peer/gtk/GdkTextLayout.java) + (gnu/java/awt/peer/gtk/GdkFontPeer.java) + (gnu/java/awt/peer/ClasspathTextLayoutPeer.java): Add + * Makefile.in: Regenerate. + * gnu/awt/xlib/XToolkit.java + (getClasspathTextLayoutPeer): Add stub. + * gnu/java/awt/ClasspathToolkit.java + (getClasspathTextLayoutPeer) Add. + * gnu/java/awt/peer/ClasspathFontPeer.java + (copyStyleToAttrs) + (copySizeToAttrs): Make public. + * gnu/java/awt/peer/ClasspathTextLayoutPeer.java: New file. + * gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java: Remove. + * gnu/java/awt/peer/gtk/GdkClasspathFontPeerMetrics.java: Remove. + * gnu/java/awt/peer/gtk/GdkFontMetrics.java: Rewrite. + * gnu/java/awt/peer/gtk/GdkFontPeer.java: New file. + * gnu/java/awt/peer/gtk/GdkGlyphVector.java: Adjust type names. + * gnu/java/awt/peer/gtk/GdkGraphics.java + (getFontPeer): New function. + (drawString): Pass font peer to native side. + * gnu/java/awt/peer/gtk/GdkGraphics2D.java + (cairoSetFont) + (cairoShowGlyphs) + (PainterThread): Remove. + (GdkGraphics2D): Set hints during construction. + (shifted) + (walkPath) + (draw) + (setRenderingHint) + (setRenderingHints): Reimplement normalization logic. + (getDefaultHints) + (updateBufferedImage) + (isBufferedImageGraphics) + (updateImagePixels) + (drawImage): Make final. + (drawImage): Always paint synchronously. + (drawString) + (drawGlyphVector): Rewrite. + (releasePeerGraphicResource) + (getPeerTextMetrics) + (getPeerFontMetrics) + (drawGdkGlyphVector) + (drawGdkTextLayout) + (cairoDrawGdkGlyphVector) + (cairoDrawGdkTextLayout) + (cairoDrawString) + (getFontPeer): New functions. + * gnu/java/awt/peer/gtk/GdkTextLayout.java: New file. + * gnu/java/awt/peer/gtk/GtkComponentPeer.java + (getFontMetrics): Get metrics via toolkit, to hit cache. + * gnu/java/awt/peer/gtk/GtkTextAreaPeer.java: Use getFontMetrics. + * gnu/java/awt/peer/gtk/GtkTextFieldPeer.java: Likewise. + * gnu/java/awt/peer/gtk/GtkToolkit.java (LRUCache): New class. + (fontCache) + (metricsCache) + (imageCache): New members. + (getFontMetrics) + (getImage) + (getClasspathFontPeer): Use caches. + (getFontPeer): Route through getClasspathFontPeer. + * java/awt/Font.java (attrsToMap): Remove, adjust ctors. + * java/awt/font/TextLayout.java: Implement in terms of peer. + * javax/swing/plaf/basic/BasicSliderUI.java + (paintThumb): Use polyline rather than polygon. + * javax/swing/plaf/basic/BasicGraphicsUtils.java: + Update comment but, alas, still do not switch to using TextLayouts. + * javax/swing/text/Utilities.java (drawTabbedText): + Draw text run-at-a-time, not char-at-a-time. + * jni/gtk-peer/gdkfont.h: Publicize some of the font interface, add + layout table. + * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c: + * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.c: + Remove files. + * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontMetrics.c: Rewrite to + incorporate brains of old GdkClasspathFontPeerMetrics. + * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c: Rewrite to + incorporate brains of old GdkClasspathFontPeer. + * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c: New file. + * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c + (drawString): Rewrite to use persistent layout in peer font. + Comment out extraneous gdk_flush calls. + * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c + (metrics_cairo) + (metrics_surface): New static variables. + (paint_glyph_run) + (install_font_peer): New helper functions. + (releasePeerGraphicResource) + (getPeerTextMetrics) + (getPeerFontMetrics) + (cairoDrawGdkTextLayout) + (cairoDrawGdkGlyphVector): New native methods. + (cairoDrawString): Rewrite, leaving layout-based version + commented out for the time being. + * jni/gtk-peer/gtkpeer.h (graphics): Add fields for pango stuff. + 2004-10-01 David Gilbert <david.gilbert@object-refinery.com> * java/awt/geom/AffineTransform.java: diff --git a/libjava/Makefile.am b/libjava/Makefile.am index be2f2466702..e0c38af8761 100644 --- a/libjava/Makefile.am +++ b/libjava/Makefile.am @@ -178,9 +178,6 @@ libgcj_la_LINK = $(LIBLINK) # Gtk/Cairo JNI sources. if GTK_CAIRO gtk_cairo_c_source_files = \ -jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c \ -jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.c \ -jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c \ jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c else gtk_cairo_c_source_files = @@ -189,7 +186,10 @@ endif ## Gtk JNI sources. gtk_c_source_files = \ $(gtk_cairo_c_source_files) \ +jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c \ jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontMetrics.c \ +jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c \ +jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c \ jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c \ jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c \ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c \ @@ -231,9 +231,9 @@ jni/classpath/primlib.c ## Java sources for Gtk peers. gtk_awt_peer_sources = \ -gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java \ -gnu/java/awt/peer/gtk/GdkClasspathFontPeerMetrics.java \ +gnu/java/awt/peer/gtk/GdkTextLayout.java \ gnu/java/awt/peer/gtk/GdkFontMetrics.java \ +gnu/java/awt/peer/gtk/GdkFontPeer.java \ gnu/java/awt/peer/gtk/GdkGlyphVector.java \ gnu/java/awt/peer/gtk/GdkGraphics.java \ gnu/java/awt/peer/gtk/GdkGraphics2D.java \ @@ -251,7 +251,6 @@ gnu/java/awt/peer/gtk/GtkContainerPeer.java \ gnu/java/awt/peer/gtk/GtkDialogPeer.java \ gnu/java/awt/peer/gtk/GtkEmbeddedWindowPeer.java \ gnu/java/awt/peer/gtk/GtkFileDialogPeer.java \ -gnu/java/awt/peer/gtk/GtkFontPeer.java \ gnu/java/awt/peer/gtk/GtkFramePeer.java \ gnu/java/awt/peer/gtk/GtkGenericPeer.java \ gnu/java/awt/peer/gtk/GtkImage.java \ @@ -970,6 +969,7 @@ gnu/java/awt/image/XBMDecoder.java \ gnu/java/awt/peer/EmbeddedWindowPeer.java \ gnu/java/awt/peer/GLightweightPeer.java \ gnu/java/awt/peer/ClasspathFontPeer.java \ +gnu/java/awt/peer/ClasspathTextLayoutPeer.java \ java/awt/AWTError.java \ java/awt/AWTEvent.java \ java/awt/AWTEventMulticaster.java \ diff --git a/libjava/Makefile.in b/libjava/Makefile.in index 5a23984b88e..7e0e6a6aa43 100644 --- a/libjava/Makefile.in +++ b/libjava/Makefile.in @@ -272,15 +272,15 @@ libgcj_la_LDFLAGS = -rpath $(toolexeclibdir) $(THREADLDFLAGS) $(THREADLIBS) \ libgcj_la_LINK = $(LIBLINK) @GTK_CAIRO_TRUE@gtk_cairo_c_source_files = @GTK_CAIRO_TRUE@\ -@GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c \ -@GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.c \ -@GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c \ @GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c @GTK_CAIRO_FALSE@gtk_cairo_c_source_files = gtk_c_source_files = \ $(gtk_cairo_c_source_files) \ +jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c \ jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontMetrics.c \ +jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c \ +jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c \ jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c \ jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c \ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c \ @@ -322,9 +322,9 @@ jni/classpath/primlib.c gtk_awt_peer_sources = \ -gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java \ -gnu/java/awt/peer/gtk/GdkClasspathFontPeerMetrics.java \ +gnu/java/awt/peer/gtk/GdkTextLayout.java \ gnu/java/awt/peer/gtk/GdkFontMetrics.java \ +gnu/java/awt/peer/gtk/GdkFontPeer.java \ gnu/java/awt/peer/gtk/GdkGlyphVector.java \ gnu/java/awt/peer/gtk/GdkGraphics.java \ gnu/java/awt/peer/gtk/GdkGraphics2D.java \ @@ -342,7 +342,6 @@ gnu/java/awt/peer/gtk/GtkContainerPeer.java \ gnu/java/awt/peer/gtk/GtkDialogPeer.java \ gnu/java/awt/peer/gtk/GtkEmbeddedWindowPeer.java \ gnu/java/awt/peer/gtk/GtkFileDialogPeer.java \ -gnu/java/awt/peer/gtk/GtkFontPeer.java \ gnu/java/awt/peer/gtk/GtkFramePeer.java \ gnu/java/awt/peer/gtk/GtkGenericPeer.java \ gnu/java/awt/peer/gtk/GtkImage.java \ @@ -647,6 +646,7 @@ gnu/java/awt/image/XBMDecoder.java \ gnu/java/awt/peer/EmbeddedWindowPeer.java \ gnu/java/awt/peer/GLightweightPeer.java \ gnu/java/awt/peer/ClasspathFontPeer.java \ +gnu/java/awt/peer/ClasspathTextLayoutPeer.java \ java/awt/AWTError.java \ java/awt/AWTEvent.java \ java/awt/AWTEventMulticaster.java \ @@ -2962,7 +2962,8 @@ gnu/java/awt/EmbeddedWindowSupport.lo gnu/java/awt/EventModifier.lo \ gnu/java/awt/image/ImageDecoder.lo gnu/java/awt/image/XBMDecoder.lo \ gnu/java/awt/peer/EmbeddedWindowPeer.lo \ gnu/java/awt/peer/GLightweightPeer.lo \ -gnu/java/awt/peer/ClasspathFontPeer.lo java/awt/AWTError.lo \ +gnu/java/awt/peer/ClasspathFontPeer.lo \ +gnu/java/awt/peer/ClasspathTextLayoutPeer.lo java/awt/AWTError.lo \ java/awt/AWTEvent.lo java/awt/AWTEventMulticaster.lo \ java/awt/AWTException.lo java/awt/ActiveEvent.lo java/awt/Adjustable.lo \ java/awt/BorderLayout.lo java/awt/Button.lo java/awt/Canvas.lo \ @@ -3543,9 +3544,9 @@ javax/accessibility/AccessibleText.lo \ javax/accessibility/AccessibleValue.lo lib_gnu_java_awt_peer_gtk_la_DEPENDENCIES = @GTK_CAIRO_FALSE@lib_gnu_java_awt_peer_gtk_la_OBJECTS = \ -@GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GdkClasspathFontPeer.lo \ -@GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GdkClasspathFontPeerMetrics.lo \ +@GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GdkTextLayout.lo \ @GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GdkFontMetrics.lo \ +@GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GdkFontPeer.lo \ @GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GdkGlyphVector.lo \ @GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GdkGraphics.lo \ @GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GdkGraphics2D.lo \ @@ -3563,7 +3564,6 @@ lib_gnu_java_awt_peer_gtk_la_DEPENDENCIES = @GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GtkDialogPeer.lo \ @GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GtkEmbeddedWindowPeer.lo \ @GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GtkFileDialogPeer.lo \ -@GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GtkFontPeer.lo \ @GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GtkFramePeer.lo \ @GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GtkGenericPeer.lo \ @GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GtkImage.lo \ @@ -3587,7 +3587,10 @@ lib_gnu_java_awt_peer_gtk_la_DEPENDENCIES = @GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GtkWindowPeer.lo \ @GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GThreadMutex.lo \ @GTK_CAIRO_FALSE@gnu/java/awt/peer/gtk/GThreadNativeMethodRunner.lo \ +@GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.lo \ @GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontMetrics.lo \ +@GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.lo \ +@GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.lo \ @GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.lo \ @GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.lo \ @GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.lo \ @@ -3625,9 +3628,9 @@ lib_gnu_java_awt_peer_gtk_la_DEPENDENCIES = @GTK_CAIRO_FALSE@jni/classpath/jnilink.lo jni/classpath/native_state.lo \ @GTK_CAIRO_FALSE@jni/classpath/primlib.lo @GTK_CAIRO_TRUE@lib_gnu_java_awt_peer_gtk_la_OBJECTS = \ -@GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GdkClasspathFontPeer.lo \ -@GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GdkClasspathFontPeerMetrics.lo \ +@GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GdkTextLayout.lo \ @GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GdkFontMetrics.lo \ +@GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GdkFontPeer.lo \ @GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GdkGlyphVector.lo \ @GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GdkGraphics.lo \ @GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GdkGraphics2D.lo \ @@ -3645,7 +3648,6 @@ lib_gnu_java_awt_peer_gtk_la_DEPENDENCIES = @GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GtkDialogPeer.lo \ @GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GtkEmbeddedWindowPeer.lo \ @GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GtkFileDialogPeer.lo \ -@GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GtkFontPeer.lo \ @GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GtkFramePeer.lo \ @GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GtkGenericPeer.lo \ @GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GtkImage.lo \ @@ -3669,11 +3671,11 @@ lib_gnu_java_awt_peer_gtk_la_DEPENDENCIES = @GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GtkWindowPeer.lo \ @GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GThreadMutex.lo \ @GTK_CAIRO_TRUE@gnu/java/awt/peer/gtk/GThreadNativeMethodRunner.lo \ -@GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.lo \ -@GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.lo \ -@GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.lo \ @GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.lo \ +@GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.lo \ @GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontMetrics.lo \ +@GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.lo \ +@GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.lo \ @GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.lo \ @GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.lo \ @GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.lo \ @@ -3848,18 +3850,19 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \ .deps/gnu/java/awt/image/ImageDecoder.P \ .deps/gnu/java/awt/image/XBMDecoder.P \ .deps/gnu/java/awt/peer/ClasspathFontPeer.P \ +.deps/gnu/java/awt/peer/ClasspathTextLayoutPeer.P \ .deps/gnu/java/awt/peer/EmbeddedWindowPeer.P \ .deps/gnu/java/awt/peer/GLightweightPeer.P \ .deps/gnu/java/awt/peer/gtk/GThreadMutex.P \ .deps/gnu/java/awt/peer/gtk/GThreadNativeMethodRunner.P \ -.deps/gnu/java/awt/peer/gtk/GdkClasspathFontPeer.P \ -.deps/gnu/java/awt/peer/gtk/GdkClasspathFontPeerMetrics.P \ .deps/gnu/java/awt/peer/gtk/GdkFontMetrics.P \ +.deps/gnu/java/awt/peer/gtk/GdkFontPeer.P \ .deps/gnu/java/awt/peer/gtk/GdkGlyphVector.P \ .deps/gnu/java/awt/peer/gtk/GdkGraphics.P \ .deps/gnu/java/awt/peer/gtk/GdkGraphics2D.P \ .deps/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.P \ .deps/gnu/java/awt/peer/gtk/GdkPixbufDecoder.P \ +.deps/gnu/java/awt/peer/gtk/GdkTextLayout.P \ .deps/gnu/java/awt/peer/gtk/GtkButtonPeer.P \ .deps/gnu/java/awt/peer/gtk/GtkCanvasPeer.P \ .deps/gnu/java/awt/peer/gtk/GtkCheckboxGroupPeer.P \ @@ -3872,7 +3875,6 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \ .deps/gnu/java/awt/peer/gtk/GtkDialogPeer.P \ .deps/gnu/java/awt/peer/gtk/GtkEmbeddedWindowPeer.P \ .deps/gnu/java/awt/peer/gtk/GtkFileDialogPeer.P \ -.deps/gnu/java/awt/peer/gtk/GtkFontPeer.P \ .deps/gnu/java/awt/peer/gtk/GtkFramePeer.P \ .deps/gnu/java/awt/peer/gtk/GtkGenericPeer.P \ .deps/gnu/java/awt/peer/gtk/GtkImage.P \ @@ -5502,13 +5504,13 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \ .deps/jni/classpath/jnilink.P .deps/jni/classpath/native_state.P \ .deps/jni/classpath/primlib.P \ .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.P \ -.deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.P \ -.deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.P \ .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontMetrics.P \ +.deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.P \ .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.P \ .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.P \ .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.P \ .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.P \ +.deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.P \ .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.P \ .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.P \ .deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.P \ diff --git a/libjava/gnu/awt/xlib/XToolkit.java b/libjava/gnu/awt/xlib/XToolkit.java index 1856d97fe53..a1d2440eef5 100644 --- a/libjava/gnu/awt/xlib/XToolkit.java +++ b/libjava/gnu/awt/xlib/XToolkit.java @@ -19,6 +19,7 @@ import java.awt.image.ImageObserver; import java.net.*; import java.awt.datatransfer.Clipboard; import java.io.InputStream; +import java.text.AttributedString; import java.util.Map; import java.util.Properties; import gnu.gcj.xlib.Display; @@ -26,6 +27,7 @@ import gnu.gcj.xlib.Screen; import gnu.gcj.xlib.Visual; import gnu.java.awt.ClasspathToolkit; import gnu.java.awt.peer.ClasspathFontPeer; +import gnu.java.awt.peer.ClasspathTextLayoutPeer; public class XToolkit extends ClasspathToolkit { @@ -400,6 +402,12 @@ public class XToolkit extends ClasspathToolkit return new XFontPeer (name,style,size); } + + public ClasspathTextLayoutPeer + getClasspathTextLayoutPeer (AttributedString str, FontRenderContext frc) + { + throw new Error("not implemented"); + } /** Creates a font, reading the glyph definitions from a stream. * diff --git a/libjava/gnu/java/awt/ClasspathToolkit.java b/libjava/gnu/java/awt/ClasspathToolkit.java index 92934593d39..545e6535697 100644 --- a/libjava/gnu/java/awt/ClasspathToolkit.java +++ b/libjava/gnu/java/awt/ClasspathToolkit.java @@ -47,6 +47,7 @@ import java.awt.FontMetrics; import java.awt.GraphicsEnvironment; import java.awt.HeadlessException; import java.awt.Toolkit; +import java.awt.font.FontRenderContext; import java.awt.image.ColorModel; import java.awt.image.ImageProducer; import java.io.File; @@ -54,10 +55,12 @@ import java.io.InputStream; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; +import java.text.AttributedString; import java.util.HashMap; import java.util.Map; import gnu.java.awt.peer.ClasspathFontPeer; +import gnu.java.awt.peer.ClasspathTextLayoutPeer; /** @@ -171,6 +174,9 @@ public abstract class ClasspathToolkit public abstract ClasspathFontPeer getClasspathFontPeer (String name, Map attrs); + public abstract ClasspathTextLayoutPeer + getClasspathTextLayoutPeer (AttributedString str, FontRenderContext frc); + /** * Creates a {@link Font}, in a platform-specific manner. diff --git a/libjava/gnu/java/awt/peer/ClasspathFontPeer.java b/libjava/gnu/java/awt/peer/ClasspathFontPeer.java index 6b753aa15ec..6bd3653edaa 100644 --- a/libjava/gnu/java/awt/peer/ClasspathFontPeer.java +++ b/libjava/gnu/java/awt/peer/ClasspathFontPeer.java @@ -160,7 +160,7 @@ public abstract class ClasspathFontPeer return name; } - protected static void copyStyleToAttrs (int style, Map attrs) + public static void copyStyleToAttrs (int style, Map attrs) { if ((style & Font.BOLD) == Font.BOLD) attrs.put (TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD); @@ -179,7 +179,7 @@ public abstract class ClasspathFontPeer attrs.put (TextAttribute.FAMILY, fam); } - protected static void copySizeToAttrs (float size, Map attrs) + public static void copySizeToAttrs (float size, Map attrs) { attrs.put (TextAttribute.SIZE, new Float (size)); } diff --git a/libjava/gnu/java/awt/peer/ClasspathTextLayoutPeer.java b/libjava/gnu/java/awt/peer/ClasspathTextLayoutPeer.java new file mode 100644 index 00000000000..143412caf99 --- /dev/null +++ b/libjava/gnu/java/awt/peer/ClasspathTextLayoutPeer.java @@ -0,0 +1,111 @@ +/* ClasspathTextLayoutPeer.java + Copyright (C) 2003 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., 59 Temple Place, Suite 330, Boston, MA +02111-1307 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; + +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.font.TextHitInfo; +import java.awt.font.TextLayout; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.text.CharacterIterator; +import java.text.AttributedCharacterIterator; +import java.text.AttributedString; +import java.util.Map; +import java.awt.font.TextAttribute; + + +/** + * @author Graydon Hoare + */ + +public interface ClasspathTextLayoutPeer +{ + TextHitInfo getStrongCaret (TextHitInfo hit1, + TextHitInfo hit2); + + void draw (Graphics2D g2, float x, float y); + + byte getBaseline (); + + boolean isLeftToRight (); + boolean isVertical (); + + float getAdvance (); + float getAscent (); + float getDescent (); + float getLeading (); + + int getCharacterCount (); + byte getCharacterLevel (int index); + + float[] getBaselineOffsets (); + Shape getBlackBoxBounds (int firstEndpoint, int secondEndpoint); + Rectangle2D getBounds (); + + float[] getCaretInfo (TextHitInfo hit, Rectangle2D bounds); + Shape getCaretShape (TextHitInfo hit, Rectangle2D bounds); + Shape[] getCaretShapes (int offset, Rectangle2D bounds, + TextLayout.CaretPolicy policy); + + Shape getLogicalHighlightShape (int firstEndpoint, int secondEndpoint, + Rectangle2D bounds); + int[] getLogicalRangesForVisualSelection (TextHitInfo firstEndpoint, + TextHitInfo secondEndpoint); + + TextHitInfo getNextLeftHit (int offset, TextLayout.CaretPolicy policy); + TextHitInfo getNextRightHit (int offset, TextLayout.CaretPolicy policy); + TextHitInfo hitTestChar (float x, float y, Rectangle2D bounds); + TextHitInfo getVisualOtherHit (TextHitInfo hit); + + float getVisibleAdvance (); + Shape getOutline (AffineTransform tx); + Shape getVisualHighlightShape (TextHitInfo firstEndpoint, + TextHitInfo secondEndpoint, + Rectangle2D bounds); + + TextLayout getJustifiedLayout (float justificationWidth); + void handleJustify (float justificationWidth); + + Object clone (); + int hashCode (); + boolean equals (ClasspathTextLayoutPeer tl); + String toString (); +} diff --git a/libjava/gnu/java/awt/peer/gtk/GdkClasspathFontPeerMetrics.java b/libjava/gnu/java/awt/peer/gtk/GdkClasspathFontPeerMetrics.java deleted file mode 100644 index 2f019e4dbc4..00000000000 --- a/libjava/gnu/java/awt/peer/gtk/GdkClasspathFontPeerMetrics.java +++ /dev/null @@ -1,116 +0,0 @@ -/* GdkClasspathFontPeerMetrics.java - Copyright (C) 1999, 2002 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., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 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.*; -import java.awt.font.*; -import java.awt.geom.*; - -public class GdkClasspathFontPeerMetrics extends FontMetrics -{ - private final int native_state = GtkGenericPeer.getUniqueInteger(); - - private static final int ASCENT = 0, MAX_ASCENT = 1, - DESCENT = 2, MAX_DESCENT = 3, - MAX_ADVANCE = 4; - - private int[] metrics; - private native int[] initState (Object font); - - public GdkClasspathFontPeerMetrics (Font font) - { - super (font); - metrics = initState (font.getPeer()); - } - - public int stringWidth (String str) - { - GlyphVector gv = font.createGlyphVector - (new FontRenderContext - (new AffineTransform (), false, false), str); - Rectangle2D r = gv.getVisualBounds (); - return (int) r.getWidth (); - } - - public int charWidth (char ch) - { - return stringWidth (new String (new char[] { ch })); - } - - public int charsWidth (char data[], int off, int len) - { - return stringWidth (new String (data, off, len)); - } - - /* - Sun's Motif implementation always returns 0 or 1 here (???), but - going by the X11 man pages, it seems as though we should return - font.ascent + font.descent. - */ - public int getLeading () - { - return 1; -// return metrics[ASCENT] + metrics[DESCENT]; - } - - public int getAscent () - { - return metrics[ASCENT]; - } - - public int getMaxAscent () - { - return metrics[MAX_ASCENT]; - } - - public int getDescent () - { - return metrics[DESCENT]; - } - - public int getMaxDescent () - { - return metrics[MAX_DESCENT]; - } - - public int getMaxAdvance () - { - return metrics[MAX_ADVANCE]; - } -} diff --git a/libjava/gnu/java/awt/peer/gtk/GdkFontMetrics.java b/libjava/gnu/java/awt/peer/gtk/GdkFontMetrics.java index c7a73a3f362..ec303b0ff56 100644 --- a/libjava/gnu/java/awt/peer/gtk/GdkFontMetrics.java +++ b/libjava/gnu/java/awt/peer/gtk/GdkFontMetrics.java @@ -1,70 +1,100 @@ /* GdkFontMetrics.java Copyright (C) 1999, 2002 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., 59 Temple Place, Suite 330, Boston, MA -02111-1307 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. */ + 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., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 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.FontMetrics; +import java.awt.*; +import java.awt.font.*; +import java.awt.geom.*; + +import gnu.java.awt.ClasspathToolkit; public class GdkFontMetrics extends FontMetrics { - private final int native_state = GtkGenericPeer.getUniqueInteger(); - - private static final int ASCENT = 0, MAX_ASCENT = 1, - DESCENT = 2, MAX_DESCENT = 3, - MAX_ADVANCE = 4; - - private int[] metrics; - private native int[] initState (String fname, int style, int size); + + private int[] font_metrics; + GdkFontPeer peer; + + static final int FONT_METRICS_ASCENT = 0; + static final int FONT_METRICS_MAX_ASCENT = 1; + static final int FONT_METRICS_DESCENT = 2; + static final int FONT_METRICS_MAX_DESCENT = 3; + static final int FONT_METRICS_MAX_ADVANCE = 4; + + static final int TEXT_METRICS_X_BEARING = 0; + static final int TEXT_METRICS_Y_BEARING = 1; + static final int TEXT_METRICS_WIDTH = 2; + static final int TEXT_METRICS_HEIGHT = 3; + static final int TEXT_METRICS_X_ADVANCE = 4; + static final int TEXT_METRICS_Y_ADVANCE = 5; + + static native void getPeerFontMetrics(GdkFontPeer peer, double [] metrics); + static native void getPeerTextMetrics(GdkFontPeer peer, String str, double [] metrics); public GdkFontMetrics (Font font) - { - super (font); - metrics = initState (font.getName (), font.getStyle (), font.getSize ()); + { + super (font.getPeer() instanceof GdkFontPeer + ? font + : ((ClasspathToolkit)(Toolkit.getDefaultToolkit ())) + .getFont (font.getName(), font.getAttributes ())); + + peer = (GdkFontPeer) this.font.getPeer(); + + font_metrics = new int[5]; + double [] hires = new double[5]; + + if (GtkToolkit.useGraphics2D ()) + GdkGraphics2D.getPeerFontMetrics(peer, hires); + else + getPeerFontMetrics (peer, hires); + + for (int i = 0; i < 5; ++i) + font_metrics[i] = (int) hires[i]; } - - native public int stringWidth (String fname, int style, int size, - String str); - + public int stringWidth (String str) { - return stringWidth (font.getName (), font.getStyle (), font.getSize (), - str); + double [] hires = new double[6]; + if (GtkToolkit.useGraphics2D()) + GdkGraphics2D.getPeerTextMetrics(peer, str, hires); + else + getPeerTextMetrics(peer, str, hires); + return (int) hires [TEXT_METRICS_WIDTH]; } public int charWidth (char ch) @@ -77,34 +107,39 @@ public class GdkFontMetrics extends FontMetrics return stringWidth (new String (data, off, len)); } - // Sun's Motif implementation always returns 0 or 1 here (???). + /* + Sun's Motif implementation always returns 0 or 1 here (???), but + going by the X11 man pages, it seems as though we should return + font.ascent + font.descent. + */ public int getLeading () { - return 0; + return 1; +// return metrics[ASCENT] + metrics[DESCENT]; } public int getAscent () { - return metrics[ASCENT]; + return font_metrics[FONT_METRICS_ASCENT]; } public int getMaxAscent () { - return metrics[MAX_ASCENT]; + return font_metrics[FONT_METRICS_MAX_ASCENT]; } public int getDescent () { - return metrics[DESCENT]; + return font_metrics[FONT_METRICS_DESCENT]; } public int getMaxDescent () { - return metrics[MAX_DESCENT]; + return font_metrics[FONT_METRICS_MAX_DESCENT]; } public int getMaxAdvance () { - return metrics[MAX_ADVANCE]; + return font_metrics[FONT_METRICS_MAX_ADVANCE]; } } diff --git a/libjava/gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java b/libjava/gnu/java/awt/peer/gtk/GdkFontPeer.java index 1cf24a98d61..a2f61def80c 100644 --- a/libjava/gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GdkFontPeer.java @@ -1,68 +1,62 @@ -/* GdkClasspathFontPeer.java -- backend implementation for Font object - Copyright (C) 2003 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., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 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. */ +/* GdkFontPeer.java -- Implements FontPeer with GTK+ + Copyright (C) 1999, 2004 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., 59 Temple Place, Suite 330, Boston, MA +02111-1307 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.peer.FontPeer; import java.awt.*; -import java.awt.font.*; import java.awt.geom.*; -import java.io.InputStream; -import java.io.IOException; -import java.io.Serializable; +import java.awt.font.*; import java.util.Locale; import java.util.Map; -import java.util.StringTokenizer; +import java.util.ResourceBundle; +import java.util.MissingResourceException; import java.text.CharacterIterator; import java.text.AttributedCharacterIterator; import java.text.StringCharacterIterator; -import java.awt.font.TextAttribute; import gnu.classpath.Configuration; import gnu.java.awt.peer.ClasspathFontPeer; -/** - * This class represents a windowing system font using the Pango - * unicode/glyph/font library and the Cairo rendering library. - * - * @author Graydon Hoare (graydon@redhat.com) - */ - -public class GdkClasspathFontPeer extends ClasspathFontPeer +public class GdkFontPeer extends ClasspathFontPeer { + + native static void initStaticState (); + private final int native_state = GtkGenericPeer.getUniqueInteger (); + private static ResourceBundle bundle; static { @@ -71,26 +65,26 @@ public class GdkClasspathFontPeer extends ClasspathFontPeer System.loadLibrary("gtkpeer"); } - if (GtkToolkit.useGraphics2D ()) - initStaticState (); - } - native static void initStaticState (); - private final int native_state = GtkGenericPeer.getUniqueInteger (); + initStaticState (); - - /* Instance Variables */ + try + { + bundle = ResourceBundle.getBundle ("gnu.java.awt.peer.gtk.font"); + } + catch (Throwable ignored) + { + bundle = null; + } + } private native void initState (); private native void dispose (); - private native void setFont (String family, int style, int size); - - protected void sync () - { - this.setFont (this.familyName, this.style, (int)this.size); - } + private native void setFont (String family, int style, int size, boolean useGraphics2D); protected void finalize () { + if (GtkToolkit.useGraphics2D ()) + GdkGraphics2D.releasePeerGraphicResource (this); dispose (); } @@ -130,20 +124,28 @@ public class GdkClasspathFontPeer extends ClasspathFontPeer /* Public API */ - public GdkClasspathFontPeer (String name, int style, int size) + public GdkFontPeer (String name, int style) + { + // All fonts get a default size of 12 if size is not specified. + this(name, style, 12); + } + + public GdkFontPeer (String name, int style, int size) { super(name, style, size); initState (); - setFont (this.familyName, this.style, (int)this.size); + setFont (this.familyName, this.style, (int)this.size, + GtkToolkit.useGraphics2D()); } - public GdkClasspathFontPeer (String name, Map attributes) + public GdkFontPeer (String name, Map attributes) { super(name, attributes); initState (); - setFont (this.familyName, this.style, (int)this.size); + setFont (this.familyName, this.style, (int)this.size, + GtkToolkit.useGraphics2D()); } - + public String getSubFamilyName(Font font, Locale locale) { return null; @@ -228,7 +230,6 @@ public class GdkClasspathFontPeer extends ClasspathFontPeer } - public LineMetrics getLineMetrics (Font font, CharacterIterator ci, int begin, int limit, FontRenderContext rc) { @@ -288,8 +289,7 @@ public class GdkClasspathFontPeer extends ClasspathFontPeer public FontMetrics getFontMetrics (Font font) { - return new GdkClasspathFontPeerMetrics (font); + return new GdkFontMetrics (font); } } - diff --git a/libjava/gnu/java/awt/peer/gtk/GdkGlyphVector.java b/libjava/gnu/java/awt/peer/gtk/GdkGlyphVector.java index ff6b4cd291a..33850445ef4 100644 --- a/libjava/gnu/java/awt/peer/gtk/GdkGlyphVector.java +++ b/libjava/gnu/java/awt/peer/gtk/GdkGlyphVector.java @@ -70,7 +70,7 @@ public class GdkGlyphVector extends GlyphVector private Font font; private FontRenderContext ctx; - private native void initState (GdkClasspathFontPeer peer, FontRenderContext ctx); + private native void initState (GdkFontPeer peer, FontRenderContext ctx); private native void setChars (String s); private native void setGlyphCodes (int codes[]); private native void dispose (); @@ -109,7 +109,7 @@ public class GdkGlyphVector extends GlyphVector */ - public GdkGlyphVector (Font f, GdkClasspathFontPeer peer, FontRenderContext c, String s) + public GdkGlyphVector (Font f, GdkFontPeer peer, FontRenderContext c, String s) { font = f; ctx = c; @@ -117,7 +117,7 @@ public class GdkGlyphVector extends GlyphVector setChars (s); } - public GdkGlyphVector (Font f, GdkClasspathFontPeer peer, FontRenderContext c, int codes[]) + public GdkGlyphVector (Font f, GdkFontPeer peer, FontRenderContext c, int codes[]) { font = f; ctx = c; diff --git a/libjava/gnu/java/awt/peer/gtk/GdkGraphics.java b/libjava/gnu/java/awt/peer/gtk/GdkGraphics.java index 4f2ccb86c18..5c92e68b49e 100644 --- a/libjava/gnu/java/awt/peer/gtk/GdkGraphics.java +++ b/libjava/gnu/java/awt/peer/gtk/GdkGraphics.java @@ -284,11 +284,17 @@ public class GdkGraphics extends Graphics native public void drawRect(int x, int y, int width, int height); native public void fillRect (int x, int y, int width, int height); - native void drawString (String str, int x, int y, String fname, int style, int size); + 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 (str, x, y, font.getName(), font.getStyle(), font.getSize()); + drawString(getFontPeer(), str, x, y); } + public void drawString (AttributedCharacterIterator ci, int x, int y) { @@ -405,7 +411,7 @@ public class GdkGraphics extends Graphics color.getGreen () ^ xorColor.getGreen (), color.getBlue () ^ xorColor.getBlue ()); } - + public void setFont (Font font) { this.font = font; diff --git a/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java b/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java index 768b35e8d4f..b291d5e8bb3 100644 --- a/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java +++ b/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java @@ -115,7 +115,7 @@ public class GdkGraphics2D extends Graphics2D { paint = g.paint; stroke = g.stroke; - hints = g.hints; + setRenderingHints (g.hints); if (g.fg.getAlpha() != -1) fg = new Color (g.fg.getRed (), g.fg.getGreen (), @@ -226,9 +226,6 @@ public class GdkGraphics2D extends Graphics2D private native void cairoSave (); private native void cairoRestore (); private native void cairoSetMatrix (double m[]); - private native void cairoSetFont (GdkClasspathFontPeer peer); - private native void cairoShowGlyphs (int codes[], - float positions[]); private native void cairoSetOperator (int cairoOperator); private native void cairoSetRGBColor (double red, double green, double blue); private native void cairoSetAlpha (double alpha); @@ -308,17 +305,23 @@ public class GdkGraphics2D extends Graphics2D cairoRestore (); } + // Some operations (drawing rather than filling) require that their + // coords be shifted to land on 0.5-pixel boundaries, in order to land on + // "middle of pixel" coordinates and light up complete pixels. - double x; - double y; - private void setPos (double nx, double ny) + private boolean shiftDrawCalls = false; + private final double shifted(double coord, boolean doShift) { - x = nx; - y = ny; + if (doShift) + return Math.floor(coord) + 0.5; + else + return coord; } - private void walkPath(PathIterator p) + private final void walkPath(PathIterator p, boolean doShift) { + double x = 0; + double y = 0; double coords[] = new double[6]; cairoSetFillRule (p.getWindingRule ()); @@ -329,13 +332,15 @@ public class GdkGraphics2D extends Graphics2D { case PathIterator.SEG_MOVETO: - setPos(coords[0], coords[1]); - cairoMoveTo (coords[0], coords[1]); + x = shifted(coords[0], doShift); + y = shifted(coords[1], doShift); + cairoMoveTo (x, y); break; case PathIterator.SEG_LINETO: - setPos(coords[0], coords[1]); - cairoLineTo (coords[0], coords[1]); + x = shifted(coords[0], doShift); + y = shifted(coords[1], doShift); + cairoLineTo (x, y); break; case PathIterator.SEG_QUADTO: @@ -343,23 +348,25 @@ public class GdkGraphics2D extends Graphics2D // splitting a quadratic bezier into a cubic: // see: http://pfaedit.sourceforge.net/bezier.html - double x1 = x + (2.0/3.0) * (coords[0] - x); - double y1 = y + (2.0/3.0) * (coords[1] - y); + double x1 = x + (2.0/3.0) * (shifted(coords[0], doShift) - x); + double y1 = y + (2.0/3.0) * (shifted(coords[1], doShift) - y); - double x2 = x1 + (1.0/3.0) * (coords[2] - x); - double y2 = y1 + (1.0/3.0) * (coords[3] - y); + double x2 = x1 + (1.0/3.0) * (shifted(coords[2], doShift) - x); + double y2 = y1 + (1.0/3.0) * (shifted(coords[3], doShift) - y); - setPos(coords[2], coords[3]); + x = shifted(coords[2], doShift); + y = shifted(coords[3], doShift); cairoCurveTo (x1, y1, x2, y2, - coords[2], coords[3]); + x, y); break; case PathIterator.SEG_CUBICTO: - setPos(coords[4], coords[5]); - cairoCurveTo (coords[0], coords[1], - coords[2], coords[3], - coords[4], coords[5]); + x = shifted(coords[4], doShift); + y = shifted(coords[5], doShift); + cairoCurveTo (shifted(coords[0], doShift), shifted(coords[1], doShift), + shifted(coords[2], doShift), shifted(coords[3], doShift), + x, y); break; case PathIterator.SEG_CLOSE: @@ -370,7 +377,7 @@ public class GdkGraphics2D extends Graphics2D } - private Map getDefaultHints() + private final Map getDefaultHints() { HashMap defaultHints = new HashMap (); @@ -393,23 +400,22 @@ public class GdkGraphics2D extends Graphics2D } - private void updateBufferedImage() + private final void updateBufferedImage() { int[] pixels = getImagePixels(); updateImagePixels(pixels); } - private boolean isBufferedImageGraphics () + private final boolean isBufferedImageGraphics () { - if (bimage != null) return true; else return false; } - private void updateImagePixels (int[] pixels) + private final void updateImagePixels (int[] pixels) { // This function can only be used if @@ -444,10 +450,10 @@ public class GdkGraphics2D extends Graphics2D } - private boolean drawImage(Image img, - AffineTransform xform, - Color bgcolor, - ImageObserver obs) + private final boolean drawImage(Image img, + AffineTransform xform, + Color bgcolor, + ImageObserver obs) { if (img instanceof GtkOffScreenImage && img.getGraphics () instanceof GdkGraphics2D && @@ -480,23 +486,22 @@ public class GdkGraphics2D extends Graphics2D try { - invertedXform = xform.createInverse(); + invertedXform = xform.createInverse(); if (img instanceof BufferedImage) { // draw an image which has actually been loaded // into memory fully - BufferedImage b = (BufferedImage) img; - return drawRaster (b.getColorModel (), - b.getData (), - invertedXform, - bgcolor); + BufferedImage b = (BufferedImage) img; + return drawRaster (b.getColorModel (), + b.getData (), + invertedXform, + bgcolor); } else { - // begin progressive loading in a separate thread - new PainterThread (this, img, invertedXform, bgcolor); - return false; + return this.drawImage(GdkPixbufDecoder.createBufferedImage(img.getSource()), + xform, bgcolor,obs); } } catch (NoninvertibleTransformException e) @@ -522,38 +527,25 @@ public class GdkGraphics2D extends Graphics2D return; } - stateSave (); cairoNewPath (); - - boolean normalize; - normalize = hints.containsValue (RenderingHints.VALUE_STROKE_NORMALIZE) - || hints.containsValue (RenderingHints.VALUE_STROKE_DEFAULT); - - if (normalize) - translate (0.5,0.5); if (s instanceof Rectangle2D) { Rectangle2D r = (Rectangle2D)s; - cairoRectangle (r.getX (), r.getY (), r.getWidth (), r.getHeight ()); + cairoRectangle (shifted(r.getX (), shiftDrawCalls), + shifted(r.getY (), shiftDrawCalls), + r.getWidth (), r.getHeight ()); } else - walkPath (s.getPathIterator (null)); + walkPath (s.getPathIterator (null), shiftDrawCalls); cairoStroke (); - if (normalize) - translate (-0.5,-0.5); - - stateRestore (); - if (isBufferedImageGraphics ()) updateBufferedImage(); - } public void fill (Shape s) { - stateSave(); cairoNewPath (); if (s instanceof Rectangle2D) { @@ -561,9 +553,8 @@ public class GdkGraphics2D extends Graphics2D cairoRectangle (r.getX (), r.getY (), r.getWidth (), r.getHeight ()); } else - walkPath (s.getPathIterator (null)); + walkPath (s.getPathIterator (null), false); cairoFill (); - stateRestore (); if (isBufferedImageGraphics ()) updateBufferedImage(); @@ -597,8 +588,8 @@ public class GdkGraphics2D extends Graphics2D r.getWidth (), r.getHeight ()); } else - walkPath (clip.getPathIterator (null)); - cairoClosePath (); + walkPath (clip.getPathIterator (null), false); + // cairoClosePath (); cairoClip (); } } @@ -744,7 +735,7 @@ public class GdkGraphics2D extends Graphics2D { BasicStroke bs = (BasicStroke) stroke; cairoSetLineCap (bs.getEndCap()); - cairoSetLineWidth (bs.getLineWidth() / 2.0); + cairoSetLineWidth (bs.getLineWidth()); cairoSetLineJoin (bs.getLineJoin()); cairoSetMiterLimit (bs.getMiterLimit()); float dashes[] = bs.getDashArray(); @@ -810,23 +801,23 @@ public class GdkGraphics2D extends Graphics2D return clip.getBounds (); } - protected Rectangle2D getClipInDevSpace () - { - Rectangle2D uclip = clip.getBounds2D (); - if (transform == null) - return uclip; - else - { - Point2D pos = transform.transform (new Point2D.Double(uclip.getX (), - uclip.getY ()), - (Point2D)null); - Point2D extent = transform.deltaTransform (new Point2D.Double(uclip.getWidth (), - uclip.getHeight ()), - (Point2D)null); - return new Rectangle2D.Double (pos.getX (), pos.getY (), - extent.getX (), extent.getY ()); - } - } + protected Rectangle2D getClipInDevSpace () + { + Rectangle2D uclip = clip.getBounds2D (); + if (transform == null) + return uclip; + else + { + Point2D pos = transform.transform (new Point2D.Double(uclip.getX (), + uclip.getY ()), + (Point2D)null); + Point2D extent = transform.deltaTransform (new Point2D.Double(uclip.getWidth (), + uclip.getHeight ()), + (Point2D)null); + return new Rectangle2D.Double (pos.getX (), pos.getY (), + extent.getX (), extent.getY ()); + } + } public void setClip (int x, int y, int width, int height) { @@ -847,96 +838,34 @@ public class GdkGraphics2D extends Graphics2D r.getWidth (), r.getHeight ()); } else - walkPath (s.getPathIterator (null)); - cairoClosePath (); + walkPath (s.getPathIterator (null), false); + // cairoClosePath (); cairoClip (); } } + private static BasicStroke draw3DRectStroke = new BasicStroke(); + public void draw3DRect(int x, int y, int width, int height, boolean raised) { - Color std = fg; - Color light = std.brighter(); - Color dark = std.darker(); - - if (!raised) - { - Color t = light; - light = dark; - dark = t; - } - - double x1 = (double) x; - double x2 = (double) x + width; - - double y1 = (double) y; - double y2 = (double) y + height; - - stateSave (); - - cairoNewPath (); - - boolean normalize; - normalize = hints.containsValue (RenderingHints.VALUE_STROKE_NORMALIZE) - || hints.containsValue (RenderingHints.VALUE_STROKE_DEFAULT); - - if (normalize) - { - x1 += 0.5; - y1 += 0.5; - x2 += 0.5; - y2 += 0.5; - } - - setColor (light); - cairoMoveTo (x1, y1); - cairoLineTo (x2, y1); - cairoLineTo (x2, y2); - cairoStroke (); - - cairoNewPath (); - setColor (dark); - cairoMoveTo (x1, y1); - cairoLineTo (x1, y2); - cairoLineTo (x2, y2); - cairoStroke (); - - stateRestore (); - + Stroke tmp = stroke; + setStroke(draw3DRectStroke); + super.draw3DRect(x, y, width, height, raised); + setStroke(tmp); if (isBufferedImageGraphics ()) updateBufferedImage(); - } public void fill3DRect(int x, int y, int width, int height, boolean raised) { - double step = 1.0; - if (stroke != null && stroke instanceof BasicStroke) - { - BasicStroke bs = (BasicStroke) stroke; - step = bs.getLineWidth(); - } - - Color bright = fg.brighter (); - Color dark = fg.darker (); - - draw3DRect (x, y, width, height, raised); - - stateSave (); - translate (step/2.0, step/2.0); - cairoNewPath (); - cairoRectangle ((double) x, (double) y, - ((double) width) - step, - ((double) height) - step ); - cairoClosePath (); - cairoFill (); - stateRestore (); - + Stroke tmp = stroke; + setStroke(draw3DRectStroke); + super.fill3DRect(x, y, width, height, raised); + setStroke(tmp); if (isBufferedImageGraphics ()) updateBufferedImage(); - } @@ -947,21 +876,21 @@ public class GdkGraphics2D extends Graphics2D public void fillRect (int x, int y, int width, int height) { - fill(new Rectangle (x, y, width, height)); + cairoNewPath (); + cairoRectangle (x, y, width, height); + cairoFill (); } public void clearRect (int x, int y, int width, int height) { - stateSave (); cairoSetRGBColor (bg.getRed() / 255.0, bg.getGreen() / 255.0, bg.getBlue() / 255.0); cairoSetAlpha (1.0); cairoNewPath (); cairoRectangle (x, y, width, height); - cairoClosePath (); cairoFill (); - stateRestore (); + setColor (fg); if (isBufferedImageGraphics ()) updateBufferedImage(); @@ -978,8 +907,8 @@ public class GdkGraphics2D extends Graphics2D return bg; } - private void doPolygon(int[] xPoints, int[] yPoints, int nPoints, - boolean close, boolean fill) + private final void doPolygon(int[] xPoints, int[] yPoints, int nPoints, + boolean close, boolean fill) { if (nPoints < 1) return; @@ -1034,9 +963,9 @@ public class GdkGraphics2D extends Graphics2D doPolygon (xPoints, yPoints, nPoints, false, false); } - private boolean drawRaster (ColorModel cm, Raster r, - AffineTransform imageToUser, - Color bgcolor) + private final boolean drawRaster (ColorModel cm, Raster r, + AffineTransform imageToUser, + Color bgcolor) { if (r == null) return false; @@ -1095,10 +1024,7 @@ public class GdkGraphics2D extends Graphics2D } } - stateSave (); - translate (x, y); drawPixels (pixels, r.getWidth (), r.getHeight (), r.getWidth (), i2u); - stateRestore (); if (isBufferedImageGraphics ()) updateBufferedImage(); @@ -1141,113 +1067,6 @@ public class GdkGraphics2D extends Graphics2D } - //////////////////////////////////////// - ////// Supporting Private Classes ////// - //////////////////////////////////////// - - private class PainterThread implements Runnable, ImageConsumer - { - - // this is a helper which is spun off when someone tries to do - // Graphics2D.drawImage on an image we cannot determine to be either - // one of our own offscreen images or a BufferedImage; that is, when - // someone wants to draw an image which is possibly still loading over - // a network or something. you run it in a separate thread and it - // writes through to the underlying Graphics2D as pixels becomg - // available. - - GdkGraphics2D gr; - Image image; - ColorModel defaultModel; - AffineTransform xform; - Color bgcolor; - - public PainterThread (GdkGraphics2D g, Image im, - AffineTransform xf, Color bg) - { - image = im; - xform = xf; - bgcolor = bg; - this.gr = (GdkGraphics2D) g.create (); - new Thread (this).start (); - } - - public void imageComplete (int status) - { - } - - public void setColorModel (ColorModel model) - { - defaultModel = model; - } - - public void setDimensions (int width, int height) - { - } - - public void setHints (int hintflags) - { - } - - public void setPixels (int x, int y, int w, int h, ColorModel model, - byte[] pixels, int off, int scansize) - { - } - - public void setPixels (int x, int y, int w, int h, ColorModel model, - int[] pixels, int off, int scansize) - { - gr.stateSave (); - gr.translate (x, y); - - if (model == null) - model = defaultModel; - - int pixels2[]; - if (model != null) - { - pixels2 = new int[pixels.length]; - for (int yy = 0; yy < h; yy++) - for (int xx = 0; xx < w; xx++) - { - int i = yy * scansize + xx; - pixels2[i] = model.getRGB (pixels[i]); - } - } - else - pixels2 = pixels; - - // change all transparent pixels in the image to the - // specified bgcolor - - if (bgcolor != null) - { - for (int i = 0; i < pixels2.length; i++) - { - if (model.getAlpha (pixels2[i]) == 0) - pixels2[i] = bgcolor.getRGB (); - } - } - - double[] xf = new double[6]; - xform.getMatrix(xf); - gr.drawPixels (pixels2, w, h, scansize, xf); - gr.stateRestore (); - } - - public void setProperties (java.util.Hashtable props) - { - } - - public void run () - { - image.getSource ().startProduction (this); - gr.dispose (); - } - } - - - /////////////////////////////////////////////// ////// Unimplemented Stubs and Overloads ////// /////////////////////////////////////////////// @@ -1307,8 +1126,11 @@ public class GdkGraphics2D extends Graphics2D else if (hintValue.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT)) cairoSurfaceSetFilter(4); - } + } + shiftDrawCalls = hints.containsValue (RenderingHints.VALUE_STROKE_NORMALIZE) + || hints.containsValue (RenderingHints.VALUE_STROKE_DEFAULT); + } public Object getRenderingHint(RenderingHints.Key hintKey) @@ -1341,6 +1163,9 @@ public class GdkGraphics2D extends Graphics2D else if(hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT)) cairoSurfaceSetFilter(4); } + + shiftDrawCalls = hints.containsValue (RenderingHints.VALUE_STROKE_NORMALIZE) + || hints.containsValue (RenderingHints.VALUE_STROKE_DEFAULT); } public void addRenderingHints(Map hints) @@ -1366,23 +1191,6 @@ public class GdkGraphics2D extends Graphics2D return new FontRenderContext (transform, true, true); } - public void drawGlyphVector (GlyphVector g, float x, float y) - { - stateSave (); - setFont (g.getFont ()); - translate ((double)x, (double)y); - cairoMoveTo (0, 0); - int nglyphs = g.getNumGlyphs (); - int codes[] = g.getGlyphCodes (0, nglyphs, (int []) null); - float posns[] = g.getGlyphPositions (0, nglyphs, (float []) null); - cairoShowGlyphs (codes, posns); - - if (isBufferedImageGraphics ()) - updateBufferedImage(); - - stateRestore (); - } - public void copyArea (int x, int y, int width, int height, int dx, int dy) { throw new java.lang.UnsupportedOperationException (); @@ -1514,15 +1322,40 @@ public class GdkGraphics2D extends Graphics2D drawLine (x1, y + height, x2, y + height); } - public void drawString (String str, int x, int y) + // these are the most accelerated painting paths + native void cairoDrawGdkGlyphVector (GdkFontPeer f, GdkGlyphVector gv, float x, float y); + native void cairoDrawGdkTextLayout (GdkFontPeer f, GdkTextLayout gl, float x, float y); + native void cairoDrawString (GdkFontPeer f, String str, float x, float y); + + GdkFontPeer getFontPeer() { - drawString (str, (float)x, (float)y); + return (GdkFontPeer) getFont().getPeer(); + } + + public void drawGdkGlyphVector(GdkGlyphVector gv, float x, float y) + { + cairoDrawGdkGlyphVector(getFontPeer(), gv, x, y); + if (isBufferedImageGraphics ()) + updateBufferedImage(); + } + + public void drawGdkTextLayout(GdkTextLayout gl, float x, float y) + { + cairoDrawGdkTextLayout(getFontPeer(), gl, x, y); + if (isBufferedImageGraphics ()) + updateBufferedImage(); } public void drawString (String str, float x, float y) { - GlyphVector gv = font.createGlyphVector (getFontRenderContext(), str); - drawGlyphVector (gv, x, y); + cairoDrawString(getFontPeer(), str, x, y); + if (isBufferedImageGraphics ()) + updateBufferedImage(); + } + + public void drawString (String str, int x, int y) + { + drawString (str, (float)x, (float)y); } public void drawString (AttributedCharacterIterator ci, int x, int y) @@ -1530,6 +1363,14 @@ public class GdkGraphics2D extends Graphics2D drawString (ci, (float)x, (float)y); } + public void drawGlyphVector (GlyphVector gv, float x, float y) + { + if (gv instanceof GdkGlyphVector) + drawGdkGlyphVector((GdkGlyphVector)gv, x, y); + else + throw new java.lang.UnsupportedOperationException (); + } + public void drawString (AttributedCharacterIterator ci, float x, float y) { GlyphVector gv = font.createGlyphVector (getFontRenderContext(), ci); @@ -1575,30 +1416,38 @@ public class GdkGraphics2D extends Graphics2D return font; } + // Until such time as pango is happy to talk directly to cairo, we + // actually need to redirect some calls from the GtkFontPeer and + // GtkFontMetrics into the drawing kit and ask cairo ourselves. + + static native void releasePeerGraphicResource (GdkFontPeer f); + static native void getPeerTextMetrics (GdkFontPeer f, String str, double [] metrics); + static native void getPeerFontMetrics (GdkFontPeer f, double [] metrics); + public FontMetrics getFontMetrics () { + // the reason we go via the toolkit here is to try to get + // a cached object. the toolkit keeps such a cache. return Toolkit.getDefaultToolkit ().getFontMetrics (font); } public FontMetrics getFontMetrics (Font f) { + // the reason we go via the toolkit here is to try to get + // a cached object. the toolkit keeps such a cache. return Toolkit.getDefaultToolkit ().getFontMetrics (f); } public void setFont (Font f) { - if (f.getPeer() instanceof GdkClasspathFontPeer) + if (f.getPeer() instanceof GdkFontPeer) font = f; else font = ((ClasspathToolkit)(Toolkit.getDefaultToolkit ())) - .getFont (f.getName(), f.getAttributes ()); - - if (f != null && - f.getPeer() instanceof GdkClasspathFontPeer) - cairoSetFont ((GdkClasspathFontPeer) f.getPeer()); + .getFont (f.getName(), f.getAttributes ()); } - + public String toString() { return getClass ().getName () + diff --git a/libjava/gnu/java/awt/peer/gtk/GdkTextLayout.java b/libjava/gnu/java/awt/peer/gtk/GdkTextLayout.java new file mode 100644 index 00000000000..26cfc16f0da --- /dev/null +++ b/libjava/gnu/java/awt/peer/gtk/GdkTextLayout.java @@ -0,0 +1,435 @@ +/* GdkTextLayout.java + Copyright (C) 2003 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., 59 Temple Place, Suite 330, Boston, MA +02111-1307 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.Graphics2D; +import java.awt.Shape; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphMetrics; +import java.awt.font.GlyphVector; +import java.awt.font.TextHitInfo; +import java.awt.font.TextLayout; +import java.awt.geom.AffineTransform; +import java.awt.geom.GeneralPath; +import java.awt.geom.Rectangle2D; +import java.text.CharacterIterator; +import java.text.AttributedCharacterIterator; +import java.text.AttributedString; +import java.util.Map; +import java.awt.font.TextAttribute; + +import gnu.classpath.Configuration; +import gnu.java.awt.peer.ClasspathTextLayoutPeer; + +/** + * This is an implementation of the text layout peer interface which + * delegates all the hard work to pango. + * + * @author Graydon Hoare + */ + +public class GdkTextLayout + implements ClasspathTextLayoutPeer +{ + // native side, plumbing, etc. + static + { + if (Configuration.INIT_LOAD_LIBRARY) + { + System.loadLibrary("gtkpeer"); + } + initStaticState (); + } + private native void setText(String str); + private native void getExtents(double[] inkExtents, + double[] logExtents); + private native void indexToPos(int idx, double[] pos); + private native void initState (); + private native void dispose (); + native static void initStaticState (); + private final int native_state = GtkGenericPeer.getUniqueInteger (); + protected void finalize () + { + dispose (); + } + + // we hold on to these to make sure we can render when presented + // with non-GdkGraphics2D paint targets + private AttributedString attributedString; + private FontRenderContext fontRenderContext; + + public GdkTextLayout(AttributedString str, FontRenderContext frc) + { + initState(); + attributedString = str; + fontRenderContext = frc; + } + + protected class CharacterIteratorProxy + implements CharacterIterator + { + public CharacterIterator target; + public int begin; + public int limit; + public int index; + + public CharacterIteratorProxy (CharacterIterator ci) + { + target = ci; + } + + public int getBeginIndex () + { + return begin; + } + + public int getEndIndex () + { + return limit; + } + + public int getIndex () + { + return index; + } + + public char setIndex (int idx) + throws IllegalArgumentException + { + if (idx < begin || idx >= limit) + throw new IllegalArgumentException (); + char ch = target.setIndex (idx); + index = idx; + return ch; + } + + public char first () + { + int save = target.getIndex (); + char ch = target.setIndex (begin); + target.setIndex (save); + return ch; + } + + public char last () + { + if (begin == limit) + return this.first (); + + int save = target.getIndex (); + char ch = target.setIndex (limit - 1); + target.setIndex (save); + return ch; + } + + public char current () + { + return target.current(); + } + + public char next () + { + if (index >= limit - 1) + return CharacterIterator.DONE; + else + { + index++; + return target.next(); + } + } + + public char previous () + { + if (index <= begin) + return CharacterIterator.DONE; + else + { + index--; + return target.previous (); + } + } + + public Object clone () + { + CharacterIteratorProxy cip = new CharacterIteratorProxy (this.target); + cip.begin = this.begin; + cip.limit = this.limit; + cip.index = this.index; + return cip; + } + + } + + + // public side + + 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 (); + } + } + } + } + + public TextHitInfo getStrongCaret (TextHitInfo hit1, + TextHitInfo hit2) + { + throw new Error("not implemented"); + } + + public byte getBaseline () + { + throw new Error("not implemented"); + } + + public boolean isLeftToRight () + { + throw new Error("not implemented"); + } + + public boolean isVertical () + { + throw new Error("not implemented"); + } + + public float getAdvance () + { + throw new Error("not implemented"); + } + + public float getAscent () + { + throw new Error("not implemented"); + } + + public float getDescent () + { + throw new Error("not implemented"); + } + + public float getLeading () + { + throw new Error("not implemented"); + } + + public int getCharacterCount () + { + throw new Error("not implemented"); + } + + public byte getCharacterLevel (int index) + { + throw new Error("not implemented"); + } + + public float[] getBaselineOffsets () + { + throw new Error("not implemented"); + } + + public Shape getBlackBoxBounds (int firstEndpoint, int secondEndpoint) + { + throw new Error("not implemented"); + } + + public Rectangle2D getBounds () + { + double[] inkExtents = new double[4]; + double[] logExtents = new double[4]; + getExtents(inkExtents, logExtents); + return new Rectangle2D.Double(logExtents[0], logExtents[1], + logExtents[2], logExtents[3]); + } + + public float[] getCaretInfo (TextHitInfo hit, Rectangle2D bounds) + { + throw new Error("not implemented"); + } + + public Shape getCaretShape (TextHitInfo hit, Rectangle2D bounds) + { + throw new Error("not implemented"); + } + + public Shape[] getCaretShapes (int offset, Rectangle2D bounds, + TextLayout.CaretPolicy policy) + { + throw new Error("not implemented"); + } + + public Shape getLogicalHighlightShape (int firstEndpoint, int secondEndpoint, + Rectangle2D bounds) + { + AffineTransform at = new AffineTransform(); + GeneralPath gp = new GeneralPath(); + double [] rect = new double[4]; + Rectangle2D tmp = new Rectangle2D.Double(); + for (int i = firstEndpoint; i <= secondEndpoint; ++i) + { + indexToPos(i, rect); + tmp.setRect(rect[0], rect[1], rect[2], rect[3]); + Rectangle2D.intersect(tmp, bounds, tmp); + gp.append(tmp.getPathIterator(at), false); + } + return gp; + } + + public int[] getLogicalRangesForVisualSelection (TextHitInfo firstEndpoint, + TextHitInfo secondEndpoint) + { + throw new Error("not implemented"); + } + + public TextHitInfo getNextLeftHit (int offset, TextLayout.CaretPolicy policy) + { + throw new Error("not implemented"); + } + public TextHitInfo getNextRightHit (int offset, TextLayout.CaretPolicy policy) + { + throw new Error("not implemented"); + } + public TextHitInfo hitTestChar (float x, float y, Rectangle2D bounds) + { + throw new Error("not implemented"); + } + public TextHitInfo getVisualOtherHit (TextHitInfo hit) + { + throw new Error("not implemented"); + } + + public float getVisibleAdvance () + { + throw new Error("not implemented"); + } + + public Shape getOutline (AffineTransform tx) + { + throw new Error("not implemented"); + } + + public Shape getVisualHighlightShape (TextHitInfo firstEndpoint, + TextHitInfo secondEndpoint, + Rectangle2D bounds) + { + throw new Error("not implemented"); + } + + + public TextLayout getJustifiedLayout (float justificationWidth) + { + throw new Error("not implemented"); + } + + public void handleJustify (float justificationWidth) + { + throw new Error("not implemented"); + } + + public Object clone () + { + throw new Error("not implemented"); + } + + public int hashCode () + { + throw new Error("not implemented"); + } + + public boolean equals (ClasspathTextLayoutPeer tl) + { + throw new Error("not implemented"); + } + + public String toString () + { + throw new Error("not implemented"); + } + +} diff --git a/libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java index e4e4f08f444..b4507643e8b 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java @@ -224,7 +224,7 @@ public class GtkComponentPeer extends GtkGenericPeer public FontMetrics getFontMetrics (Font font) { - return new GdkFontMetrics (font); + return getToolkit().getFontMetrics(font); } public Graphics getGraphics () diff --git a/libjava/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java index 651118d8422..94874deb617 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java @@ -68,11 +68,7 @@ public class GtkTextAreaPeer extends GtkTextComponentPeer awtComponent.setFont (f); } - FontMetrics fm; - if (GtkToolkit.useGraphics2D ()) - fm = new GdkClasspathFontPeerMetrics (f); - else - fm = new GdkFontMetrics (f); + FontMetrics fm = getFontMetrics (f); TextArea ta = ((TextArea) awtComponent); int sizeRows = ta.getRows (); @@ -130,11 +126,7 @@ public class GtkTextAreaPeer extends GtkTextComponentPeer if (f == null) return new Dimension (width, height); - FontMetrics fm; - if (GtkToolkit.useGraphics2D ()) - fm = new GdkClasspathFontPeerMetrics (f); - else - fm = new GdkFontMetrics (f); + FontMetrics fm = getFontMetrics (f); int sizeRows = rows == 0 ? DEFAULT_ROWS : rows; int sizeCols = cols == 0 ? DEFAULT_COLS : cols; @@ -163,11 +155,7 @@ public class GtkTextAreaPeer extends GtkTextComponentPeer if (f == null) return new Dimension (width, height); - FontMetrics fm; - if (GtkToolkit.useGraphics2D ()) - fm = new GdkClasspathFontPeerMetrics (f); - else - fm = new GdkFontMetrics (f); + FontMetrics fm = getFontMetrics (f); int sizeRows = rows == 0 ? DEFAULT_ROWS : rows; int sizeCols = cols == 0 ? DEFAULT_COLS : cols; diff --git a/libjava/gnu/java/awt/peer/gtk/GtkTextFieldPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkTextFieldPeer.java index 73d92cbaa94..bd1ac812470 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkTextFieldPeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkTextFieldPeer.java @@ -66,11 +66,7 @@ public class GtkTextFieldPeer extends GtkTextComponentPeer awtComponent.setFont (f); } - FontMetrics fm; - if (GtkToolkit.useGraphics2D ()) - fm = new GdkClasspathFontPeerMetrics (f); - else - fm = new GdkFontMetrics (f); + FontMetrics fm = getFontMetrics (f); TextField tf = ((TextField) awtComponent); int cols = tf.getColumns (); @@ -117,11 +113,7 @@ public class GtkTextFieldPeer extends GtkTextComponentPeer if (f == null) return new Dimension (2 * gtkEntryGetBorderWidth (), dim[1]); - FontMetrics fm; - if (GtkToolkit.useGraphics2D ()) - fm = new GdkClasspathFontPeerMetrics (f); - else - fm = new GdkFontMetrics (f); + FontMetrics fm = getFontMetrics (f); int text_width = cols * fm.getMaxAdvance (); @@ -140,11 +132,7 @@ public class GtkTextFieldPeer extends GtkTextComponentPeer if (f == null) return new Dimension (2 * gtkEntryGetBorderWidth (), dim[1]); - FontMetrics fm; - if (GtkToolkit.useGraphics2D ()) - fm = new GdkClasspathFontPeerMetrics (f); - else - fm = new GdkFontMetrics (f); + FontMetrics fm = getFontMetrics (f); int text_width = cols * fm.getMaxAdvance (); diff --git a/libjava/gnu/java/awt/peer/gtk/GtkToolkit.java b/libjava/gnu/java/awt/peer/gtk/GtkToolkit.java index 3f82159c3ab..b130a3b4524 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkToolkit.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkToolkit.java @@ -49,19 +49,23 @@ import java.awt.image.ColorModel; import java.awt.image.ImageObserver; import java.awt.image.ImageConsumer; import java.awt.image.ImageProducer; +import java.awt.font.FontRenderContext; import java.awt.GraphicsEnvironment; import java.awt.peer.*; import java.net.URL; +import java.text.AttributedString; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.Map; +import java.util.HashMap; import java.util.MissingResourceException; import java.util.Properties; import gnu.java.awt.EmbeddedWindow; import gnu.java.awt.EmbeddedWindowSupport; import gnu.java.awt.peer.EmbeddedWindowPeer; import gnu.java.awt.peer.ClasspathFontPeer; +import gnu.java.awt.peer.ClasspathTextLayoutPeer; import gnu.classpath.Configuration; import gnu.java.awt.peer.gtk.GdkPixbufDecoder; @@ -304,22 +308,59 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit "SansSerif" }); } + private class LRUCache extends java.util.LinkedHashMap + { + int max_entries; + public LRUCache(int max) + { + super(max, 0.75f, true); + max_entries = max; + } + protected boolean removeEldestEntry(Map.Entry eldest) + { + return size() > max_entries; + } + } + + private LRUCache fontCache = new LRUCache(50); + private LRUCache metricsCache = new LRUCache(50); + private LRUCache imageCache = new LRUCache(50); + public FontMetrics getFontMetrics (Font font) { - if (useGraphics2D()) - return new GdkClasspathFontPeerMetrics (font); + if (metricsCache.containsKey(font)) + return (FontMetrics) metricsCache.get(font); else - return new GdkFontMetrics (font); + { + FontMetrics m; + m = new GdkFontMetrics (font); + metricsCache.put(font, m); + return m; + } } public Image getImage (String filename) { - return createImage (filename); + if (imageCache.containsKey(filename)) + return (Image) imageCache.get(filename); + else + { + Image im = createImage(filename); + imageCache.put(filename, im); + return im; + } } public Image getImage (URL url) { - return createImage (url); + if (imageCache.containsKey(url)) + return (Image) imageCache.get(url); + else + { + Image im = createImage(url); + imageCache.put(url, im); + return im; + } } public PrintJob getPrintJob (Frame frame, String jobtitle, Properties props) @@ -502,7 +543,7 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit */ protected FontPeer getFontPeer (String name, int style) { // All fonts get a default size of 12 if size is not specified. - return getFontPeer(name, style, 12); + return getFontPeer (name, style, 12); } /** @@ -510,10 +551,12 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit */ private FontPeer getFontPeer (String name, int style, int size) { - GtkFontPeer fp = new GtkFontPeer (name, style, size); - return fp; + Map attrs = new HashMap (); + ClasspathFontPeer.copyStyleToAttrs (style, attrs); + ClasspathFontPeer.copySizeToAttrs (size, attrs); + return getClasspathFontPeer (name, attrs); } - + /** * Newer method to produce a peer for a Font object, even though Sun's * design claims Font should now be peerless, we do not agree with this @@ -522,40 +565,28 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit public ClasspathFontPeer getClasspathFontPeer (String name, Map attrs) { - if (useGraphics2D()) - return new GdkClasspathFontPeer (name, attrs); + Map keyMap = new HashMap (attrs); + // We don't know what kind of "name" the user requested (logical, face, + // family), and we don't actually *need* to know here. The worst case + // involves failure to consolidate fonts with the same backend in our + // cache. This is harmless. + keyMap.put ("GtkToolkit.RequestedFontName", name); + if (fontCache.containsKey (keyMap)) + return (ClasspathFontPeer) fontCache.get (keyMap); else { - // Default values - int size = 12; - int style = Font.PLAIN; - if (name == null) - name = "Default"; - - if (attrs.containsKey (TextAttribute.WEIGHT)) - { - Float weight = (Float) attrs.get (TextAttribute.WEIGHT); - if (weight.floatValue () >= TextAttribute.WEIGHT_BOLD.floatValue ()) - style += Font.BOLD; - } - - if (attrs.containsKey (TextAttribute.POSTURE)) - { - Float posture = (Float) attrs.get (TextAttribute.POSTURE); - if (posture.floatValue () >= TextAttribute.POSTURE_OBLIQUE.floatValue ()) - style += Font.ITALIC; - } - - if (attrs.containsKey (TextAttribute.SIZE)) - { - Float fsize = (Float) attrs.get (TextAttribute.SIZE); - size = fsize.intValue(); - } - - return (ClasspathFontPeer) this.getFontPeer (name, style, size); + ClasspathFontPeer newPeer = new GdkFontPeer (name, attrs); + fontCache.put (keyMap, newPeer); + return newPeer; } } + public ClasspathTextLayoutPeer getClasspathTextLayoutPeer (AttributedString str, + FontRenderContext frc) + { + return new GdkTextLayout(str, frc); + } + protected EventQueue getSystemEventQueueImpl() { return q; diff --git a/libjava/java/awt/Font.java b/libjava/java/awt/Font.java index 25a1d925b23..0dc2683ecc3 100644 --- a/libjava/java/awt/Font.java +++ b/libjava/java/awt/Font.java @@ -234,7 +234,11 @@ private static final long serialVersionUID = -4206021311591459213L; size = tokenval; } - return getFontFromToolkit (name, attrsToMap (style, size)); + HashMap attrs = new HashMap(); + ClasspathFontPeer.copyStyleToAttrs (style, attrs); + ClasspathFontPeer.copySizeToAttrs (size, attrs); + + return getFontFromToolkit (name, attrs); } /* These methods delegate to the toolkit. */ @@ -244,23 +248,6 @@ private static final long serialVersionUID = -4206021311591459213L; return (ClasspathToolkit)(Toolkit.getDefaultToolkit ()); } - protected static Map attrsToMap(int style, int size) - { - Map attrs = new HashMap(); - attrs.put (TextAttribute.SIZE, new Float ((float)size)); - - if ((style & BOLD) == BOLD) - attrs.put (TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD); - else - attrs.put (TextAttribute.WEIGHT, TextAttribute.WEIGHT_REGULAR); - - if ((style & ITALIC) == ITALIC) - attrs.put (TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE); - else - attrs.put (TextAttribute.POSTURE, TextAttribute.POSTURE_REGULAR); - return attrs; - } - /* Every factory method in Font should eventually call this. */ protected static Font getFontFromToolkit (String name, Map attribs) { @@ -325,7 +312,10 @@ private static final long serialVersionUID = -4206021311591459213L; public Font (String name, int style, int size) { - this.peer = getPeerFromToolkit (name, attrsToMap (style, size)); + HashMap attrs = new HashMap(); + ClasspathFontPeer.copyStyleToAttrs (style, attrs); + ClasspathFontPeer.copySizeToAttrs (size, attrs); + this.peer = getPeerFromToolkit (name, attrs); } public Font (Map attrs) diff --git a/libjava/java/awt/font/TextLayout.java b/libjava/java/awt/font/TextLayout.java index aecbbe08567..e4ed0d0eb1c 100644 --- a/libjava/java/awt/font/TextLayout.java +++ b/libjava/java/awt/font/TextLayout.java @@ -41,12 +41,17 @@ package java.awt.font; import java.awt.Font; import java.awt.Graphics2D; import java.awt.Shape; +import java.awt.Toolkit; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import java.text.AttributedCharacterIterator; import java.text.AttributedString; import java.text.CharacterIterator; import java.util.Map; +import java.awt.font.TextAttribute; + +import gnu.java.awt.ClasspathToolkit; +import gnu.java.awt.peer.ClasspathTextLayoutPeer; /** * @author Michael Koch @@ -54,6 +59,7 @@ import java.util.Map; public final class TextLayout implements Cloneable { public static final CaretPolicy DEFAULT_CARET_POLICY = new CaretPolicy (); + ClasspathTextLayoutPeer peer; public static class CaretPolicy { @@ -65,37 +71,39 @@ public final class TextLayout implements Cloneable public TextHitInfo getStrongCaret (TextHitInfo hit1, TextHitInfo hit2, TextLayout layout) { - throw new Error ("not implemented"); + return layout.peer.getStrongCaret(hit1, hit2); } } - private AttributedString attributedString; - private FontRenderContext fontRenderContext; - public TextLayout (AttributedCharacterIterator text, FontRenderContext frc) { - attributedString = new AttributedString (text); - fontRenderContext = frc; + AttributedString as = new AttributedString (text); + ClasspathToolkit tk = (ClasspathToolkit)(Toolkit.getDefaultToolkit ()); + peer = tk.getClasspathTextLayoutPeer(as, frc); } public TextLayout (String string, Font font, FontRenderContext frc) { - attributedString = new AttributedString (string); - attributedString.addAttribute (TextAttribute.FONT, font); - fontRenderContext = frc; + AttributedString as = new AttributedString (string); + as.addAttribute (TextAttribute.FONT, font); + ClasspathToolkit tk = (ClasspathToolkit)(Toolkit.getDefaultToolkit ()); + peer = tk.getClasspathTextLayoutPeer(as, frc); } - public TextLayout (String string, Map attributes, FontRenderContext frc) + public TextLayout (String string, Map attributes, FontRenderContext frc) { - attributedString = new AttributedString (string, attributes); - fontRenderContext = frc; + AttributedString as = new AttributedString (string, attributes); + ClasspathToolkit tk = (ClasspathToolkit)(Toolkit.getDefaultToolkit ()); + peer = tk.getClasspathTextLayoutPeer(as, frc); } protected Object clone () { try { - return super.clone (); + TextLayout tl = (TextLayout) super.clone (); + tl.peer = (ClasspathTextLayoutPeer) this.peer.clone(); + return tl; } catch (CloneNotSupportedException e) { @@ -105,146 +113,9 @@ public final class TextLayout implements Cloneable } - protected class CharacterIteratorProxy - implements CharacterIterator - { - public CharacterIterator target; - public int begin; - public int limit; - public int index; - - public CharacterIteratorProxy (CharacterIterator ci) - { - target = ci; - } - - public int getBeginIndex () - { - return begin; - } - - public int getEndIndex () - { - return limit; - } - - public int getIndex () - { - return index; - } - - public char setIndex (int idx) - throws IllegalArgumentException - { - if (idx < begin || idx >= limit) - throw new IllegalArgumentException (); - char ch = target.setIndex (idx); - index = idx; - return ch; - } - - public char first () - { - int save = target.getIndex (); - char ch = target.setIndex (begin); - target.setIndex (save); - return ch; - } - - public char last () - { - if (begin == limit) - return this.first (); - - int save = target.getIndex (); - char ch = target.setIndex (limit - 1); - target.setIndex (save); - return ch; - } - - public char current () - { - return target.current(); - } - - public char next () - { - if (index >= limit - 1) - return CharacterIterator.DONE; - else - { - index++; - return target.next(); - } - } - - public char previous () - { - if (index <= begin) - return CharacterIterator.DONE; - else - { - index--; - return target.previous (); - } - } - - public Object clone () - { - CharacterIteratorProxy cip = new CharacterIteratorProxy (this.target); - cip.begin = this.begin; - cip.limit = this.limit; - cip.index = this.index; - return cip; - } - - } - - public void draw (Graphics2D g2, float x, float y) { - 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 (); - } - } + peer.draw(g2, x, y); } public boolean equals (Object obj) @@ -257,207 +128,207 @@ public final class TextLayout implements Cloneable public boolean equals (TextLayout tl) { - throw new Error ("not implemented"); + return this.peer.equals(tl.peer); } public float getAdvance () { - throw new Error ("not implemented"); + return peer.getAdvance(); } public float getAscent () { - throw new Error ("not implemented"); + return peer.getAscent(); } public byte getBaseline () { - throw new Error ("not implemented"); + return peer.getBaseline(); } public float[] getBaselineOffsets () { - throw new Error ("not implemented"); + return peer.getBaselineOffsets(); } public Shape getBlackBoxBounds (int firstEndpoint, int secondEndpoint) { - throw new Error ("not implemented"); + return peer.getBlackBoxBounds(firstEndpoint, secondEndpoint); } public Rectangle2D getBounds() { - throw new Error ("not implemented"); + return peer.getBounds(); } public float[] getCaretInfo (TextHitInfo hit) { - throw new Error ("not implemented"); + return getCaretInfo(hit, getBounds()); } public float[] getCaretInfo (TextHitInfo hit, Rectangle2D bounds) { - throw new Error ("not implemented"); + return peer.getCaretInfo(hit, bounds); } public Shape getCaretShape (TextHitInfo hit) { - throw new Error ("not implemented"); + return getCaretShape(hit, getBounds()); } public Shape getCaretShape (TextHitInfo hit, Rectangle2D bounds) { - throw new Error ("not implemented"); + return peer.getCaretShape(hit, bounds); } public Shape[] getCaretShapes (int offset) { - throw new Error ("not implemented"); + return getCaretShapes(offset, getBounds()); } public Shape[] getCaretShapes (int offset, Rectangle2D bounds) { - throw new Error ("not implemented"); + return getCaretShapes(offset, getBounds(), DEFAULT_CARET_POLICY); } public Shape[] getCaretShapes (int offset, Rectangle2D bounds, TextLayout.CaretPolicy policy) { - throw new Error ("not implemented"); + return peer.getCaretShapes(offset, bounds, policy); } public int getCharacterCount () { - throw new Error ("not implemented"); + return peer.getCharacterCount(); } public byte getCharacterLevel (int index) { - throw new Error ("not implemented"); + return peer.getCharacterLevel(index); } public float getDescent () { - throw new Error ("not implemented"); + return peer.getDescent(); } public TextLayout getJustifiedLayout (float justificationWidth) { - throw new Error ("not implemented"); + return peer.getJustifiedLayout(justificationWidth); } public float getLeading () { - throw new Error ("not implemented"); + return peer.getLeading(); } public Shape getLogicalHighlightShape (int firstEndpoint, int secondEndpoint) { - throw new Error ("not implemented"); + return getLogicalHighlightShape (firstEndpoint, secondEndpoint, getBounds()); } public Shape getLogicalHighlightShape (int firstEndpoint, int secondEndpoint, Rectangle2D bounds) { - throw new Error ("not implemented"); + return peer.getLogicalHighlightShape(firstEndpoint, secondEndpoint, bounds); } public int[] getLogicalRangesForVisualSelection (TextHitInfo firstEndpoint, TextHitInfo secondEndpoint) { - throw new Error ("not implemented"); + return peer.getLogicalRangesForVisualSelection(firstEndpoint, secondEndpoint); } public TextHitInfo getNextLeftHit (int offset) { - throw new Error ("not implemented"); + return getNextLeftHit(offset, DEFAULT_CARET_POLICY); } public TextHitInfo getNextLeftHit (int offset, TextLayout.CaretPolicy policy) { - throw new Error ("not implemented"); + return peer.getNextLeftHit(offset, policy); } public TextHitInfo getNextLeftHit (TextHitInfo hit) { - throw new Error ("not implemented"); + return getNextLeftHit(hit.getCharIndex()); } public TextHitInfo getNextRightHit (int offset) { - throw new Error ("not implemented"); + return getNextRightHit(offset, DEFAULT_CARET_POLICY); } public TextHitInfo getNextRightHit (int offset, TextLayout.CaretPolicy policy) { - throw new Error ("not implemented"); + return peer.getNextRightHit(offset, policy); } public TextHitInfo getNextRightHit (TextHitInfo hit) { - throw new Error ("not implemented"); + return getNextRightHit(hit.getCharIndex()); } public Shape getOutline (AffineTransform tx) { - throw new Error ("not implemented"); + return peer.getOutline(tx); } public float getVisibleAdvance () { - throw new Error ("not implemented"); + return peer.getVisibleAdvance(); } public Shape getVisualHighlightShape (TextHitInfo firstEndpoint, TextHitInfo secondEndpoint) { - throw new Error ("not implemented"); + return getVisualHighlightShape(firstEndpoint, secondEndpoint, getBounds()); } public Shape getVisualHighlightShape (TextHitInfo firstEndpoint, TextHitInfo secondEndpoint, Rectangle2D bounds) { - throw new Error ("not implemented"); + return peer.getVisualHighlightShape(firstEndpoint, secondEndpoint, bounds); } public TextHitInfo getVisualOtherHit (TextHitInfo hit) { - throw new Error ("not implemented"); + return peer.getVisualOtherHit(hit); } protected void handleJustify (float justificationWidth) { - throw new Error ("not implemented"); + peer.handleJustify(justificationWidth); } public int hashCode () { - throw new Error ("not implemented"); + return peer.hashCode(); } public TextHitInfo hitTestChar (float x, float y) { - throw new Error ("not implemented"); + return hitTestChar(x, y, getBounds()); } public TextHitInfo hitTestChar (float x, float y, Rectangle2D bounds) { - throw new Error ("not implemented"); + return peer.hitTestChar(x, y, bounds); } public boolean isLeftToRight () { - throw new Error ("not implemented"); + return peer.isLeftToRight(); } public boolean isVertical () { - throw new Error ("not implemented"); + return peer.isVertical(); } public String toString () { - throw new Error ("not implemented"); + return peer.toString(); } } diff --git a/libjava/javax/swing/plaf/basic/BasicGraphicsUtils.java b/libjava/javax/swing/plaf/basic/BasicGraphicsUtils.java index 06e502e0e7e..b1064f48eaa 100644 --- a/libjava/javax/swing/plaf/basic/BasicGraphicsUtils.java +++ b/libjava/javax/swing/plaf/basic/BasicGraphicsUtils.java @@ -455,9 +455,9 @@ public class BasicGraphicsUtils drawUnderline = (underlinedIndex >= 0) && (underlinedIndex < textLength); - // XXX - FIXME we now always use this fall-back since TextLayout is - // almost completely not implemented. - if (!(g instanceof Graphics2D) || true) + // FIXME: unfortunately pango and cairo can't agree on metrics + // so for the time being we continue to *not* use TextLayouts. + if (true || !(g instanceof Graphics2D)) { /* Fall-back. This is likely to produce garbage for any text * containing right-to-left (Hebrew or Arabic) characters, even diff --git a/libjava/javax/swing/plaf/basic/BasicSliderUI.java b/libjava/javax/swing/plaf/basic/BasicSliderUI.java index 60330ea0006..ef227c84abe 100644 --- a/libjava/javax/swing/plaf/basic/BasicSliderUI.java +++ b/libjava/javax/swing/plaf/basic/BasicSliderUI.java @@ -1955,10 +1955,10 @@ public class BasicSliderUI extends SliderUI } g.setColor(Color.WHITE); - g.drawPolygon(bright); + g.drawPolyline(bright.xpoints, bright.ypoints, bright.npoints); g.setColor(Color.BLACK); - g.drawPolygon(dark); + g.drawPolyline(dark.xpoints, dark.ypoints, dark.npoints); g.setColor(Color.GRAY); g.fillPolygon(all); diff --git a/libjava/javax/swing/text/Utilities.java b/libjava/javax/swing/text/Utilities.java index 61c13eef509..d954e886e90 100644 --- a/libjava/javax/swing/text/Utilities.java +++ b/libjava/javax/swing/text/Utilities.java @@ -91,13 +91,27 @@ public class Utilities FontMetrics metrics = g.getFontMetrics(); int ascent = metrics.getAscent(); + int pixelWidth = 0; + int pos = 0; + int len = 0; + for (int offset = s.offset; offset < (s.offset + s.count); ++offset) { - switch (buffer[offset]) + char c = buffer[offset]; + if (len > 0 && (c == '\t' || c == '\n')) + { + g.drawChars(buffer, pos, len, pixelX, pixelY + ascent); + pixelX += pixelWidth; + pixelWidth = 0; + pos = offset+1; + len = 0; + } + + switch (c) { case '\t': // In case we have a tab, we just 'jump' over the tab. - // When we have no tab expander we just use the width of 'm'. + // When we have no tab expander we just use the width of ' '. if (e != null) pixelX = (int) e.nextTabStop((float) pixelX, startOffset + offset - s.offset); @@ -105,20 +119,20 @@ public class Utilities pixelX += metrics.charWidth(' '); break; case '\n': - // In case we have a newline, we must draw - // the buffer and jump on the next line. - g.drawChars(buffer, offset, 1, pixelX, y); + // In case we have a newline, we must jump to the next line. pixelY += metrics.getHeight(); pixelX = x; break; default: - // Here we draw the char. - g.drawChars(buffer, offset, 1, pixelX, pixelY + ascent); - pixelX += metrics.charWidth(buffer[offset]); + ++len; + pixelWidth += metrics.charWidth(buffer[offset]); break; } } + if (len > 0) + g.drawChars(buffer, pos, len, pixelX, pixelY + ascent); + return pixelX; } diff --git a/libjava/jni/gtk-peer/gdkfont.h b/libjava/jni/gtk-peer/gdkfont.h index f2ee86a2d69..c9f624563a3 100644 --- a/libjava/jni/gtk-peer/gdkfont.h +++ b/libjava/jni/gtk-peer/gdkfont.h @@ -47,6 +47,7 @@ extern struct state_table *native_font_state_table; extern struct state_table *native_glyphvector_state_table; +struct state_table *native_text_layout_state_table; #define NSA_FONT_INIT(env, clazz) \ native_font_state_table = init_state_table (env, clazz) @@ -73,11 +74,49 @@ extern struct state_table *native_glyphvector_state_table; #define NSA_DEL_GV_PTR(env, obj) \ remove_state_slot (env, obj, native_glyphvector_state_table) + +#define NSA_TEXT_LAYOUT_INIT(env, clazz) \ + native_text_layout_state_table = init_state_table (env, clazz) + +#define NSA_GET_TEXT_LAYOUT_PTR(env, obj) \ + get_state (env, obj, native_text_layout_state_table) + +#define NSA_SET_TEXT_LAYOUT_PTR(env, obj, ptr) \ + set_state (env, obj, native_text_layout_state_table, (void *)ptr) + +#define NSA_DEL_TEXT_LAYOUT_PTR(env, obj) \ + remove_state_slot (env, obj, native_text_layout_state_table) + +#define FONT_METRICS_ASCENT 0 +#define FONT_METRICS_MAX_ASCENT 1 +#define FONT_METRICS_DESCENT 2 +#define FONT_METRICS_MAX_DESCENT 3 +#define FONT_METRICS_MAX_ADVANCE 4 +#define NUM_FONT_METRICS 5 + +#define TEXT_METRICS_X_BEARING 0 +#define TEXT_METRICS_Y_BEARING 1 +#define TEXT_METRICS_WIDTH 2 +#define TEXT_METRICS_HEIGHT 3 +#define TEXT_METRICS_X_ADVANCE 4 +#define TEXT_METRICS_Y_ADVANCE 5 +#define NUM_TEXT_METRICS 6 + struct peerfont { PangoFont *font; PangoFontDescription *desc; PangoContext *ctx; + PangoLayout *layout; + /* + * The GdkGraphics2D (using cairo) may store a pointer to a + * cairo_font_t here; since we want to work equally well with + * the GdkGraphics class (using GDK) we do not explicitly mention + * cairo types here; it is up to the higher level driver routine + * in GdkClasspathFontPeer.java to decide which backend functions + * to invoke. + */ + void *graphics_resource; }; struct glyphvec @@ -90,4 +129,9 @@ struct glyphvec PangoContext *ctx; }; +struct textlayout +{ + PangoLayout *pango_layout; +}; + #endif /* __GDKFONT_H__ */ diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.c deleted file mode 100644 index c10b945ab6b..00000000000 --- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.c +++ /dev/null @@ -1,102 +0,0 @@ -/* gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.c - Copyright (C) 1999, 2003 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., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 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. */ - -#include <math.h> - -#include "gdkfont.h" -#include "gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.h" - -#define ASCENT 0 -#define MAX_ASCENT 1 -#define DESCENT 2 -#define MAX_DESCENT 3 -#define MAX_ADVANCE 4 -#define NUM_METRICS 5 - -JNIEXPORT jintArray JNICALL Java_gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics_initState - (JNIEnv *env, jobject self, jobject font) -{ - jintArray array; - jint *metrics; - struct peerfont *pf = NULL; - FT_Matrix mat; - double pointsize; - FT_Face face; - - pf = NSA_GET_FONT_PTR(env, font); - g_assert (pf != NULL); - - array = (*env)->NewIntArray (env, NUM_METRICS); - metrics = (*env)->GetIntArrayElements (env, array, NULL); - - gdk_threads_enter (); - -#define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 64.0)) -#define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0) -#define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0)) -#define DOUBLE_FROM_16_16(t) ((double)(t) / 65536.0) - - pointsize = pango_font_description_get_size (pf->desc); - pointsize /= (double) PANGO_SCALE; - - mat.xx = DOUBLE_TO_16_16(1); - mat.xy = DOUBLE_TO_16_16(0); - mat.yx = DOUBLE_TO_16_16(0); - mat.yy = DOUBLE_TO_16_16(1); - - face = pango_ft2_font_get_face (pf->font); - FT_Set_Transform(face, &mat, NULL); - FT_Set_Char_Size( face, - DOUBLE_TO_26_6 (pointsize), - DOUBLE_TO_26_6 (pointsize), - 0, 0); - - metrics[ASCENT] = ceil (DOUBLE_FROM_26_6(face->size->metrics.ascender)); - metrics[MAX_ASCENT] = metrics[ASCENT]; - metrics[DESCENT] = floor (DOUBLE_FROM_26_6(face->size->metrics.descender)); - if (metrics[DESCENT] < 0) - metrics[DESCENT] = - metrics[DESCENT]; - metrics[MAX_DESCENT] = metrics[DESCENT]; - metrics[MAX_ADVANCE] = ceil (DOUBLE_FROM_26_6(face->size->metrics.max_advance)); - - gdk_threads_leave (); - - (*env)->ReleaseIntArrayElements (env, array, metrics, 0); - - return array; -} - diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontMetrics.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontMetrics.c index bb406c50c49..ada954d6245 100644 --- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontMetrics.c +++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontMetrics.c @@ -1,5 +1,5 @@ /* gdkfontmetrics.c - Copyright (C) 1999, 2003 Free Software Foundation, Inc. + Copyright (C) 1999, 2003, 2004 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -36,110 +36,78 @@ obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #include "gtkpeer.h" +#include "gdkfont.h" + #include "gnu_java_awt_peer_gtk_GdkFontMetrics.h" #include <gdk/gdkx.h> -#define ASCENT 0 -#define MAX_ASCENT 1 -#define DESCENT 2 -#define MAX_DESCENT 3 -#define MAX_ADVANCE 4 -#define NUM_METRICS 5 - -JNIEXPORT jintArray JNICALL Java_gnu_java_awt_peer_gtk_GdkFontMetrics_initState - (JNIEnv *env, jobject obj __attribute__((unused)), - jstring fname, jint style, jint size) +JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkFontMetrics_getPeerFontMetrics + (JNIEnv *env, jclass clazz, jobject java_font, jdoubleArray java_metrics) { - jintArray array; - jint *metrics; - const char *font_name; - PangoFontDescription *font_desc; - PangoContext *context; + struct peerfont *pfont = NULL; + jdouble *native_metrics = NULL; PangoFontMetrics *pango_metrics; - array = (*env)->NewIntArray (env, NUM_METRICS); - - metrics = (*env)->GetIntArrayElements (env, array, NULL); - font_name = (*env)->GetStringUTFChars (env, fname, NULL); - - gdk_threads_enter (); - - font_desc = pango_font_description_from_string (font_name); - pango_font_description_set_size (font_desc, size * dpi_conversion_factor); + gdk_threads_enter(); - if (style & AWT_STYLE_BOLD) - pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD); + pfont = (struct peerfont *) NSA_GET_FONT_PTR (env, java_font); + g_assert (pfont != NULL); - if (style & AWT_STYLE_ITALIC) - pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE); - - context = gdk_pango_context_get(); - pango_context_set_font_description (context, font_desc); - - pango_metrics = pango_context_get_metrics (context, font_desc, + pango_metrics = pango_context_get_metrics (pfont->ctx, pfont->desc, gtk_get_default_language ()); - metrics[ASCENT] = - PANGO_PIXELS (pango_font_metrics_get_ascent (pango_metrics)); - metrics[MAX_ASCENT] = metrics[ASCENT]; - metrics[DESCENT] = - PANGO_PIXELS (pango_font_metrics_get_descent (pango_metrics)); - metrics[MAX_DESCENT] = metrics[DESCENT]; - metrics[MAX_ADVANCE] = - PANGO_PIXELS (pango_font_metrics_get_approximate_char_width (pango_metrics)); - - pango_font_metrics_unref (pango_metrics); - - pango_font_description_free (font_desc); + native_metrics = (*env)->GetDoubleArrayElements (env, java_metrics, NULL); + g_assert (native_metrics != NULL); - gdk_threads_leave (); + native_metrics[FONT_METRICS_ASCENT] = PANGO_PIXELS (pango_font_metrics_get_ascent (pango_metrics)); + native_metrics[FONT_METRICS_MAX_ASCENT] = native_metrics[FONT_METRICS_ASCENT]; + native_metrics[FONT_METRICS_DESCENT] = PANGO_PIXELS (pango_font_metrics_get_descent (pango_metrics)); + if (native_metrics[FONT_METRICS_DESCENT] < 0) + native_metrics[FONT_METRICS_DESCENT] = - native_metrics[FONT_METRICS_DESCENT]; + native_metrics[FONT_METRICS_MAX_DESCENT] = native_metrics[FONT_METRICS_DESCENT]; + native_metrics[FONT_METRICS_MAX_ADVANCE] = PANGO_PIXELS (pango_font_metrics_get_approximate_char_width (pango_metrics)); + + (*env)->ReleaseDoubleArrayElements (env, java_metrics, native_metrics, 0); - (*env)->ReleaseStringUTFChars (env, fname, font_name); - (*env)->ReleaseIntArrayElements (env, array, metrics, 0); + pango_font_metrics_unref (pango_metrics); - return array; + gdk_threads_leave(); } -JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_gtk_GdkFontMetrics_stringWidth - (JNIEnv *env, jobject obj __attribute__((unused)), - jstring fname, jint style, jint size, jstring str) +JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkFontMetrics_getPeerTextMetrics + (JNIEnv *env, jclass clazz, jobject java_font, jstring str, jdoubleArray java_metrics) { - PangoFontDescription *font_desc; - PangoContext *context; - PangoLayout *layout; - int width = 0; - const char *cstr; - const char *font_name; - - cstr = (*env)->GetStringUTFChars (env, str, NULL); - font_name = (*env)->GetStringUTFChars (env, fname, NULL); - - gdk_threads_enter (); - - font_desc = pango_font_description_from_string (font_name); - pango_font_description_set_size (font_desc, size * dpi_conversion_factor); + struct peerfont *pfont = NULL; + const char *cstr = NULL; + jdouble *native_metrics = NULL; + PangoRectangle log; - if (style & AWT_STYLE_BOLD) - pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD); + gdk_threads_enter(); - if (style & AWT_STYLE_ITALIC) - pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE); + pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, java_font); + g_assert (pfont != NULL); - context = gdk_pango_context_get(); - pango_context_set_font_description (context, font_desc); - - layout = pango_layout_new (context); - - pango_layout_set_text (layout, cstr, -1); + cstr = (*env)->GetStringUTFChars (env, str, NULL); + g_assert(cstr != NULL); - pango_layout_get_pixel_size (layout, &width, NULL); + pango_layout_set_text (pfont->layout, cstr, -1); + pango_layout_get_extents (pfont->layout, NULL, &log); - pango_font_description_free (font_desc); + (*env)->ReleaseStringUTFChars (env, str, cstr); + pango_layout_set_text (pfont->layout, "", -1); - gdk_threads_leave (); + native_metrics = (*env)->GetDoubleArrayElements (env, java_metrics, NULL); + g_assert (native_metrics != NULL); - (*env)->ReleaseStringUTFChars (env, fname, font_name); - (*env)->ReleaseStringUTFChars (env, str, cstr); + native_metrics[TEXT_METRICS_X_BEARING] = PANGO_PIXELS(log.x); + native_metrics[TEXT_METRICS_Y_BEARING] = PANGO_PIXELS(log.y); + native_metrics[TEXT_METRICS_WIDTH] = PANGO_PIXELS(log.width); + native_metrics[TEXT_METRICS_HEIGHT] = PANGO_PIXELS(log.height); + native_metrics[TEXT_METRICS_X_ADVANCE] = PANGO_PIXELS(log.x + log.width); + native_metrics[TEXT_METRICS_Y_ADVANCE] = PANGO_PIXELS(log.y + log.height); + + (*env)->ReleaseDoubleArrayElements (env, java_metrics, native_metrics, 0); - return width; + gdk_threads_leave(); } + diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c index 34d557131ec..31e9c2d06b2 100644 --- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c +++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c @@ -1,5 +1,5 @@ /* gnu_java_awt_GdkFont.c - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2004 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -36,7 +36,7 @@ exception statement from your version. */ #include "gdkfont.h" -#include "gnu_java_awt_peer_gtk_GdkClasspathFontPeer.h" +#include "gnu_java_awt_peer_gtk_GdkFontPeer.h" struct state_table *native_font_state_table; @@ -47,6 +47,7 @@ pango text objects: Font <-> - PangoFont - PangoFontDescription - PangoContext + - PangoLayout (for rendering and measuring) GlyphVector <-> - GList of PangoGlyphItem - PangoFontDescription @@ -68,17 +69,16 @@ enum java_awt_font_baseline { java_awt_font_HANGING_BASELINE = 2 }; -JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkClasspathFontPeer_initStaticState +JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkFontPeer_initStaticState (JNIEnv *env, jclass clazz) { NSA_FONT_INIT (env, clazz); } -JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkClasspathFontPeer_initState +JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkFontPeer_initState (JNIEnv *env, jobject self) { struct peerfont *pfont = NULL; - gdk_threads_enter (); g_assert (self != NULL); pfont = (struct peerfont *) g_malloc0 (sizeof (struct peerfont)); @@ -88,7 +88,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkClasspathFontPeer_initState } -JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkClasspathFontPeer_dispose +JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkFontPeer_dispose (JNIEnv *env, jobject self) { struct peerfont *pfont = NULL; @@ -96,21 +96,22 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkClasspathFontPeer_dispose gdk_threads_enter (); pfont = (struct peerfont *)NSA_DEL_FONT_PTR (env, self); g_assert (pfont != NULL); - if (pfont->ctx != NULL) - g_object_unref (pfont->ctx); + if (pfont->layout != NULL) + g_object_unref (pfont->font); if (pfont->font != NULL) g_object_unref (pfont->font); + if (pfont->ctx != NULL) + g_object_unref (pfont->ctx); if (pfont->desc != NULL) pango_font_description_free (pfont->desc); g_free (pfont); gdk_threads_leave (); } -JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkClasspathFontPeer_setFont - (JNIEnv *env, jobject self, jstring family_name_str, jint style_int, jint size) +JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkFontPeer_setFont + (JNIEnv *env, jobject self, jstring family_name_str, jint style_int, jint size, jboolean useGraphics2D) { struct peerfont *pfont = NULL; - PangoFontMap *map = NULL; char const *family_name = NULL; enum java_awt_font_style style; @@ -143,25 +144,33 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkClasspathFontPeer_setFont if (style & java_awt_font_ITALIC) pango_font_description_set_style (pfont->desc, PANGO_STYLE_ITALIC); - - /* - FIXME: these are possibly wrong, and should in any case - probably be cached between calls. - */ - map = pango_ft2_font_map_for_display (); - g_assert (map != NULL); - - if (pfont->ctx == NULL) - pfont->ctx = pango_ft2_font_map_create_context (PANGO_FT2_FONT_MAP (map)); - g_assert (pfont->ctx != NULL); + if (useGraphics2D) + { + if (pfont->ctx == NULL) + pfont->ctx = pango_ft2_font_map_create_context (pango_ft2_font_map_for_display ()); + } + else + { + if (pfont->ctx == NULL) + pfont->ctx = gdk_pango_context_get(); + } + g_assert (pfont->ctx != NULL); + if (pfont->font != NULL) - g_object_unref (pfont->font); - - pfont->font = pango_font_map_load_font (map, pfont->ctx, pfont->desc); + { + g_object_unref (pfont->font); + pfont->font = NULL; + } + + pfont->font = pango_context_load_font (pfont->ctx, pfont->desc); g_assert (pfont->font != NULL); + if (pfont->layout == NULL) + pfont->layout = pango_layout_new (pfont->ctx); + g_assert (pfont->layout != NULL); + gdk_threads_leave (); } diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c index d537d9a4051..e471ee261f2 100644 --- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c +++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c @@ -36,6 +36,7 @@ obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #include "gtkpeer.h" +#include "gdkfont.h" #include "gnu_java_awt_peer_gtk_GdkGraphics.h" #include <gdk/gdkprivate.h> #include <gdk/gdkx.h> @@ -87,6 +88,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_initState__II g->cm = gdk_rgb_get_cmap (); gdk_colormap_ref (g->cm); g->gc = gdk_gc_new (g->drawable); + gdk_threads_leave (); NSA_SET_PTR (env, obj, g); @@ -145,6 +147,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_dispose gdk_threads_leave (); + free (g); } @@ -164,57 +167,41 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_translateNative } JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_drawString - (JNIEnv *env, jobject obj, jstring str, jint x, jint y, - jstring fname, jint style, jint size) + (JNIEnv *env, jobject obj, jobject font, jstring str, jint x, jint y) { + struct peerfont *pfont = NULL; struct graphics *g; const char *cstr; - const char *font_name; int baseline_y; - PangoFontDescription *font_desc; - PangoContext *context; - PangoLayout *layout; PangoLayoutIter *iter; g = (struct graphics *) NSA_GET_PTR (env, obj); + g_assert (g != NULL); + + pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, font); + g_assert (pfont != NULL); cstr = (*env)->GetStringUTFChars (env, str, NULL); - font_name = (*env)->GetStringUTFChars (env, fname, NULL); gdk_threads_enter (); - font_desc = pango_font_description_from_string (font_name); - - pango_font_description_set_size (font_desc, size * dpi_conversion_factor); - - if (style & AWT_STYLE_BOLD) - pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD); - - if (style & AWT_STYLE_ITALIC) - pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE); - - context = gdk_pango_context_get(); - pango_context_set_font_description (context, font_desc); - - layout = pango_layout_new (context); - - pango_layout_set_text (layout, cstr, -1); - iter = pango_layout_get_iter (layout); + pango_layout_set_font_description (pfont->layout, pfont->desc); + pango_layout_set_text (pfont->layout, cstr, -1); + iter = pango_layout_get_iter (pfont->layout); baseline_y = pango_layout_iter_get_baseline (iter); gdk_draw_layout (g->drawable, g->gc, x + g->x_offset, y + g->y_offset - PANGO_PIXELS (baseline_y), - layout); + pfont->layout); - pango_font_description_free (font_desc); pango_layout_iter_free (iter); + pango_layout_set_text (pfont->layout, "", -1); - gdk_flush (); + /* gdk_flush (); */ gdk_threads_leave (); - (*env)->ReleaseStringUTFChars (env, fname, font_name); (*env)->ReleaseStringUTFChars (env, str, cstr); } @@ -229,7 +216,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_drawLine gdk_draw_line (g->drawable, g->gc, x + g->x_offset, y + g->y_offset, x2 + g->x_offset, y2 + g->y_offset); - gdk_flush (); + /* gdk_flush (); */ gdk_threads_leave (); } @@ -244,7 +231,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_fillRect gdk_draw_rectangle (g->drawable, g->gc, TRUE, x + g->x_offset, y + g->y_offset, width, height); - gdk_flush (); + /* gdk_flush (); */ gdk_threads_leave (); } @@ -258,7 +245,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_drawRect gdk_threads_enter (); gdk_draw_rectangle (g->drawable, g->gc, FALSE, x + g->x_offset, y + g->y_offset, width, height); - gdk_flush (); + /* gdk_flush (); */ gdk_threads_leave (); } @@ -277,7 +264,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_copyArea (GdkWindow *)g->drawable, x + g->x_offset, y + g->y_offset, width, height); - gdk_flush (); + /* gdk_flush (); */ gdk_threads_leave (); } @@ -297,7 +284,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_copyPixmap (GdkWindow *)g2->drawable, 0 + g2->x_offset, 0 + g2->y_offset, width, height); - gdk_flush (); + /* gdk_flush (); */ gdk_threads_leave (); } @@ -431,7 +418,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_clearRect x + g->x_offset, y + g->y_offset, width, height); gdk_gc_set_foreground (g->gc, &(saved.foreground)); } - gdk_flush (); + /* gdk_flush (); */ gdk_threads_leave (); } @@ -478,7 +465,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_drawArc gdk_draw_arc (g->drawable, g->gc, FALSE, x + g->x_offset, y + g->y_offset, width, height, angle1 << 6, angle2 << 6); - gdk_flush (); + /* gdk_flush (); */ gdk_threads_leave (); } @@ -522,7 +509,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_drawPolyline gdk_threads_enter (); gdk_draw_lines (g->drawable, g->gc, points, npoints); - gdk_flush (); + /* gdk_flush (); */ gdk_threads_leave (); g_free (points); @@ -546,7 +533,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_drawPolygon gdk_threads_enter (); gdk_draw_lines (g->drawable, g->gc, points, npoints); - gdk_flush (); + /* gdk_flush (); */ gdk_threads_leave (); g_free (points); @@ -564,7 +551,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_fillPolygon g->x_offset, g->y_offset); gdk_threads_enter (); gdk_draw_polygon (g->drawable, g->gc, TRUE, points, npoints); - gdk_flush (); + /* gdk_flush (); */ gdk_threads_leave (); g_free (points); @@ -582,7 +569,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_fillArc gdk_draw_arc (g->drawable, g->gc, TRUE, x + g->x_offset, y + g->y_offset, width, height, angle1 << 6, angle2 << 6); - gdk_flush (); + /* gdk_flush (); */ gdk_threads_leave (); } @@ -597,7 +584,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_drawOval gdk_draw_arc (g->drawable, g->gc, FALSE, x + g->x_offset, y + g->y_offset, width, height, 0, 23040); - gdk_flush (); + /* gdk_flush (); */ gdk_threads_leave (); } @@ -612,7 +599,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_fillOval gdk_draw_arc (g->drawable, g->gc, TRUE, x + g->x_offset, y + g->y_offset, width, height, 0, 23040); - gdk_flush (); + /* gdk_flush (); */ gdk_threads_leave (); } diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c index 08034100127..63d3b4a42be 100644 --- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c +++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c @@ -402,7 +402,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_gdkDrawDrawable begin_drawing_operation(dst); - gdk_flush(); + /* gdk_flush(); */ gdk_drawable_get_size (src->drawable, &s_width, &s_height); gdk_drawable_get_size (dst->drawable, &d_width, &d_height); @@ -713,6 +713,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_drawPixels native_matrix[4], native_matrix[5]); cairo_surface_set_matrix (surf, mat); cairo_surface_set_filter (surf, cairo_surface_get_filter(gr->surface)); + cairo_show_surface (gr->cr, surf, w, h); cairo_matrix_destroy (mat); cairo_surface_destroy (surf); @@ -853,39 +854,374 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMatrix gdk_threads_leave(); } -JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetFont - (JNIEnv *env, jobject obj, jobject font) +static void +install_font_peer(cairo_t *cr, + struct peerfont *pfont, + int debug) { - struct graphics2d *gr = NULL; - struct peerfont *pfont = NULL; - cairo_font_t *ft = NULL; + cairo_font_t *ft; FT_Face face = NULL; + g_assert(cr != NULL); + g_assert(pfont != NULL); + + if (pfont->graphics_resource == NULL) + { + face = pango_ft2_font_get_face (pfont->font); + g_assert (face != NULL); + + ft = cairo_ft_font_create_for_ft_face (face); + g_assert (ft != NULL); + + if (debug) printf ("install_font_peer made new cairo font for '%s'\n", face->family_name); + + cairo_set_font (cr, ft); + cairo_scale_font (cr, + (pango_font_description_get_size (pfont->desc) / + (double)PANGO_SCALE) * (96.0 / 72.0)); + + pfont->graphics_resource = ft; + } + else + { + if (debug) printf ("install_font_peer reused existing font resource\n"); + ft = (cairo_font_t *) pfont->graphics_resource; + cairo_set_font (cr, ft); + cairo_scale_font (cr, + (pango_font_description_get_size (pfont->desc) / + (double)PANGO_SCALE) * (96.0 / 72.0)); + } +} + +static cairo_t *metrics_cairo = NULL; +static cairo_surface_t *metrics_surface = NULL; + +static void +ensure_metrics_cairo() +{ + if (metrics_cairo == NULL) + { + metrics_cairo = cairo_create (); + metrics_surface = cairo_image_surface_create (CAIRO_FORMAT_A8, 1, 1); + cairo_set_target_surface (metrics_cairo, metrics_surface); + } +} + + +JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_releasePeerGraphicsResource + (JNIEnv *env, jclass clazz, jobject java_font) +{ + struct peerfont *pfont = NULL; + + g_assert(java_font != NULL); + + gdk_threads_enter(); + pfont = (struct peerfont *) NSA_GET_FONT_PTR (env, java_font); + g_assert (pfont != NULL); + if (pfont->graphics_resource != NULL) + { + cairo_font_destroy ((cairo_font_t *) pfont->graphics_resource); + pfont->graphics_resource = NULL; + } + gdk_threads_leave(); +} + +JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_getPeerTextMetrics + (JNIEnv *env, jclass clazz, jobject java_font, jstring str, jdoubleArray java_metrics) +{ + struct peerfont *pfont = NULL; + const char *cstr = NULL; + jdouble *native_metrics = NULL; + cairo_text_extents_t extents; + + g_assert(java_font != NULL); gdk_threads_enter(); + + pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, java_font); + g_assert (pfont != NULL); + + ensure_metrics_cairo(); + install_font_peer (metrics_cairo, pfont, 0); + + cstr = (*env)->GetStringUTFChars (env, str, NULL); + g_assert(cstr != NULL); + cairo_text_extents (metrics_cairo, cstr, &extents); + + native_metrics = (*env)->GetDoubleArrayElements (env, java_metrics, NULL); + g_assert (native_metrics != NULL); + + native_metrics[TEXT_METRICS_X_BEARING] = extents.x_bearing; + native_metrics[TEXT_METRICS_Y_BEARING] = extents.y_bearing; + native_metrics[TEXT_METRICS_WIDTH] = extents.width; + native_metrics[TEXT_METRICS_HEIGHT] = extents.height; + native_metrics[TEXT_METRICS_X_ADVANCE] = extents.x_advance; + native_metrics[TEXT_METRICS_Y_ADVANCE] = extents.y_advance; + + (*env)->ReleaseStringUTFChars (env, str, cstr); + (*env)->ReleaseDoubleArrayElements (env, java_metrics, native_metrics, 0); + gdk_threads_leave(); +} + +JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_getPeerFontMetrics + (JNIEnv *env, jclass clazz, jobject java_font, jdoubleArray java_metrics) +{ + struct peerfont *pfont = NULL; + jdouble *native_metrics = NULL; + cairo_font_extents_t extents; + + g_assert(java_font != NULL); + + gdk_threads_enter(); + + pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, java_font); + g_assert (pfont != NULL); + + ensure_metrics_cairo(); + install_font_peer (metrics_cairo, pfont, 0); + + cairo_current_font_extents (metrics_cairo, &extents); + + native_metrics = (*env)->GetDoubleArrayElements (env, java_metrics, NULL); + g_assert (native_metrics != NULL); + + native_metrics[FONT_METRICS_ASCENT] = extents.ascent; + native_metrics[FONT_METRICS_MAX_ASCENT] = extents.ascent; + native_metrics[FONT_METRICS_DESCENT] = extents.descent; + if (native_metrics[FONT_METRICS_DESCENT] < 0) + native_metrics[FONT_METRICS_DESCENT] = - native_metrics[FONT_METRICS_DESCENT]; + native_metrics[FONT_METRICS_MAX_DESCENT] = native_metrics[FONT_METRICS_DESCENT]; + native_metrics[FONT_METRICS_MAX_ADVANCE] = extents.max_x_advance; + + (*env)->ReleaseDoubleArrayElements (env, java_metrics, native_metrics, 0); + gdk_threads_leave(); +} + +static void +paint_glyph_run(struct graphics2d *gr, + cairo_glyph_t **glyphs, + gint *n_glyphs, + PangoLayoutRun *run) +{ + gint i = 0; + gint x = 0, y = 0; + + g_assert (gr != NULL); + g_assert (glyphs != NULL); + g_assert (n_glyphs != NULL); + g_assert (run != NULL); + + if (run->glyphs != NULL && run->glyphs->num_glyphs > 0) + { + if (*n_glyphs < run->glyphs->num_glyphs) + { + *glyphs = g_realloc(*glyphs, + (sizeof(cairo_glyph_t) + * run->glyphs->num_glyphs)); + *n_glyphs = run->glyphs->num_glyphs; + } + + g_assert (*glyphs != NULL); + + if (gr->debug) printf ("painting %d glyphs: ", run->glyphs->num_glyphs); + + for (i = 0; i < run->glyphs->num_glyphs; ++i) + { + (*glyphs)[i].index = run->glyphs->glyphs[i].glyph; + + (*glyphs)[i].x = + ((double) (x + run->glyphs->glyphs[i].geometry.x_offset)) + / ((double) PANGO_SCALE); + + (*glyphs)[i].y = + ((double) (y + run->glyphs->glyphs[i].geometry.y_offset)) + / ((double) PANGO_SCALE); + + if (gr->debug) printf(" (%ld @ %f,%f)", + (*glyphs)[i].index, + (*glyphs)[i].x, + (*glyphs)[i].y); + + x += run->glyphs->glyphs[i].geometry.width; + } + + if (gr->debug) printf("\n"); + begin_drawing_operation (gr); + cairo_show_glyphs (gr->cr, *glyphs, run->glyphs->num_glyphs); + end_drawing_operation (gr); + } +} + +JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoDrawString + (JNIEnv *env, jobject obj, jobject font, jstring str, float x, float y) +{ + struct graphics2d *gr = NULL; + const char *cstr = NULL; + struct peerfont *pfont = NULL; + + /* + cairo_glyph_t *glyphs = NULL; + gint n_glyphs = 0; + PangoLayoutRun *run = NULL; + PangoLayoutIter *iter = NULL; + */ + + g_assert(obj != NULL); + g_assert(font != NULL); + g_assert(str != NULL); + + gdk_threads_enter (); if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; } gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); - g_assert (gr != NULL); + g_assert(gr != NULL); - pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, font); + pfont = (struct peerfont *) NSA_GET_FONT_PTR (env, font); g_assert (pfont != NULL); - face = pango_ft2_font_get_face (pfont->font); - g_assert (face != NULL); + cstr = (*env)->GetStringUTFChars (env, str, NULL); + g_assert(cstr != NULL); + + if (gr->debug) printf ("painting string '%s' at (%f,%f)\n", cstr, x, y); - ft = cairo_ft_font_create_for_ft_face (face); - g_assert (ft != NULL); + /* For now we let cairo do the glyph conversion; eventually this + * ought to be unified with pango, but it is impossible to get + * pango and cairo to agree on metrics at the moment, so we either + * have to use "all cairo" metrics (the string-based APIs) or + * "all pango" metrics (the glyph-vector based APIs). + */ - if (gr->debug) printf ("cairo_set_font '%s'\n", face->family_name); + install_font_peer (gr->cr, pfont, gr->debug); + cairo_move_to (gr->cr, x, y); + cairo_show_text (gr->cr, cstr); - cairo_set_font (gr->cr, ft); + /* + + pango_layout_set_text (gr->pango_layout, cstr, -1); - cairo_scale_font (gr->cr, - pango_font_description_get_size (pfont->desc) / - (double)PANGO_SCALE); + iter = pango_layout_get_iter (gr->pango_layout); + g_assert(iter != NULL); - cairo_font_destroy (ft); - gdk_threads_leave(); + cairo_translate (gr->cr, x, y); + + do + { + run = pango_layout_iter_get_run (iter); + if (run != NULL) + paint_glyph_run (gr, &glyphs, &n_glyphs, run); + } + while (pango_layout_iter_next_run (iter)); + + if (glyphs != NULL) + g_free (glyphs); + + cairo_translate (gr->cr, -x, -y); + + pango_layout_iter_free (iter); + + */ + + gdk_threads_leave (); + + (*env)->ReleaseStringUTFChars (env, str, cstr); +} + + +JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoDrawGdkGlyphVector + (JNIEnv *env, jobject self, jobject font, jobject java_vec, jfloat x, jfloat y) +{ + + struct graphics2d *gr = NULL; + struct peerfont *pfont = NULL; + struct glyphvec *gv = NULL; + PangoLayoutRun *run = NULL; + cairo_glyph_t *glyphs = NULL; + gint n_glyphs = 0; + + g_assert (self != NULL); + g_assert (java_vec != NULL); + + gdk_threads_enter (); + if (peer_is_disposed(env, self)) { gdk_threads_leave(); return; } + + gr = (struct graphics2d *)NSA_GET_G2D_PTR (env, self); + gv = (struct glyphvec *)NSA_GET_GV_PTR (env, java_vec); + pfont = (struct peerfont *) NSA_GET_FONT_PTR (env, font); + + g_assert (gr != NULL); + g_assert (gv != NULL); + g_assert (pfont != NULL); + + if (gr->debug) printf ("painting pango glyph vector\n"); + + install_font_peer (gr->cr, pfont, gr->debug); + cairo_translate (gr->cr, x, y); + + /* nb. PangoLayoutRun is a typedef for PangoGlyphItem. */ + run = (PangoLayoutRun *) gv->glyphitems; + if (run != NULL) + paint_glyph_run (gr, &glyphs, &n_glyphs, run); + + if (glyphs != NULL) + g_free (glyphs); + + cairo_translate (gr->cr, -x, -y); + gdk_threads_leave (); +} + +JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoDrawGdkTextLayout + (JNIEnv *env, jobject self, jobject font, jobject java_layout, jfloat x, jfloat y) +{ + /* + * FIXME: Some day we expect either cairo or pango will know how to make + * a pango layout paint to a cairo surface. that day is not yet here. + */ + + struct graphics2d *gr = NULL; + struct peerfont *pfont = NULL; + struct textlayout *tl = NULL; + PangoLayoutIter *i = NULL; + PangoLayoutRun *run = NULL; + cairo_glyph_t *glyphs = NULL; + gint n_glyphs = 0; + + g_assert (self != NULL); + g_assert (java_layout != NULL); + + gr = (struct graphics2d *)NSA_GET_G2D_PTR (env, self); + tl = (struct textlayout *)NSA_GET_TEXT_LAYOUT_PTR (env, java_layout); + pfont = (struct peerfont *) NSA_GET_FONT_PTR (env, font); + + g_assert (gr != NULL); + g_assert (tl != NULL); + g_assert (tl->pango_layout != NULL); + g_assert (pfont != NULL); + + if (gr->debug) printf ("painting pango layout\n"); + + gdk_threads_enter (); + if (peer_is_disposed(env, self)) { gdk_threads_leave(); return; } + + i = pango_layout_get_iter (tl->pango_layout); + g_assert (i != NULL); + + install_font_peer (gr->cr, pfont, gr->debug); + cairo_translate (gr->cr, x, y); + + do + { + run = pango_layout_iter_get_run (i); + if (run != NULL) + paint_glyph_run (gr, &glyphs, &n_glyphs, run); + } + while (pango_layout_iter_next_run (i)); + + if (glyphs != NULL) + g_free (glyphs); + + cairo_translate (gr->cr, -x, -y); + + pango_layout_iter_free (i); + gdk_threads_leave (); } JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoShowGlyphs @@ -1038,7 +1374,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetAlpha gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); g_assert (gr != NULL); - if (gr->debug) printf ("cairo_set_alpha %f\n", a); + if (gr->debug) printf ("cairo_set_alpha %f\n", a); cairo_set_alpha (gr->cr, a); gdk_threads_leave(); } diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c new file mode 100644 index 00000000000..1afcd902979 --- /dev/null +++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c @@ -0,0 +1,175 @@ +/* gnu_java_awt_GdkTextLayout.c + Copyright (C) 2004 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., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 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. */ + + +#include <jni.h> +#include <gtk/gtk.h> +#include "native_state.h" +#include "gdkfont.h" +#include "gnu_java_awt_peer_gtk_GdkTextLayout.h" + +JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkTextLayout_initStaticState + (JNIEnv *env, jclass clazz) +{ + NSA_TEXT_LAYOUT_INIT (env, clazz); +} + +JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkTextLayout_initState + (JNIEnv *env, jobject self) +{ + struct textlayout *tl; + + gdk_threads_enter (); + g_assert(self != NULL); + tl = g_malloc0 (sizeof (struct textlayout)); + g_assert(tl != NULL); + tl->pango_layout = pango_layout_new(gdk_pango_context_get()); + g_assert(tl->pango_layout != NULL); + NSA_SET_TEXT_LAYOUT_PTR (env, self, tl); + gdk_threads_leave (); +} + +JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_setText + (JNIEnv *env, jobject self, jstring text) +{ + struct textlayout *tl; + gchar *str = NULL; + gint len = 0; + + gdk_threads_enter (); + g_assert(self != NULL); + g_assert(text != NULL); + + tl = (struct textlayout *)NSA_GET_TEXT_LAYOUT_PTR (env, self); + g_assert(tl != NULL); + g_assert(tl->pango_layout != NULL); + + len = (*env)->GetStringUTFLength (env, text); + str = (gchar *)(*env)->GetStringUTFChars (env, text, NULL); + g_assert (str != NULL); + + pango_layout_set_text (tl->pango_layout, text, len); + + (*env)->ReleaseStringUTFChars (env, text, str); + gdk_threads_leave (); +} + +JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkTextLayout_indexToPos + (JNIEnv *env, jobject self, jint idx, jdoubleArray javaPos) +{ + struct textlayout *tl; + PangoRectangle pangoPos; + jdouble *nativePos; + + gdk_threads_enter (); + g_assert(self != NULL); + g_assert(javaPos != NULL); + + tl = (struct textlayout *)NSA_GET_TEXT_LAYOUT_PTR (env, self); + g_assert(tl != NULL); + g_assert(tl->pango_layout != NULL); + + g_assert((*env)->GetArrayLength (env, javaPos) == 4); + + nativePos = (*env)->GetDoubleArrayElements (env, javaPos, NULL); + + pango_layout_index_to_pos (tl->pango_layout, idx, &pangoPos); + + nativePos[0] = (jdouble) pangoPos.x; + nativePos[1] = (jdouble) pangoPos.y; + nativePos[2] = (jdouble) pangoPos.width; + nativePos[3] = (jdouble) pangoPos.height; + + (*env)->ReleaseDoubleArrayElements (env, javaPos, nativePos, 0); + gdk_threads_leave (); +} + +JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkTextLayout_getExtents + (JNIEnv *env, jobject self, jdoubleArray javaInkExtents, jdoubleArray javaLogExtents) +{ + struct textlayout *tl; + PangoRectangle pangoInkExtents, pangoLogExtents; + jdouble *nativeInkExtents, *nativeLogExtents; + + gdk_threads_enter (); + g_assert(self != NULL); + g_assert(javaInkExtents != NULL); + g_assert(javaLogExtents != NULL); + + tl = (struct textlayout *)NSA_GET_TEXT_LAYOUT_PTR (env, self); + g_assert(tl != NULL); + g_assert(tl->pango_layout != NULL); + + g_assert((*env)->GetArrayLength (env, javaInkExtents) == 4); + g_assert((*env)->GetArrayLength (env, javaLogExtents) == 4); + + nativeInkExtents = (*env)->GetDoubleArrayElements (env, javaInkExtents, NULL); + nativeLogExtents = (*env)->GetDoubleArrayElements (env, javaLogExtents, NULL); + + pango_layout_get_extents (tl->pango_layout, + &pangoInkExtents, &pangoLogExtents); + + nativeInkExtents[0] = (jdouble) pangoInkExtents.x; + nativeInkExtents[1] = (jdouble) pangoInkExtents.y; + nativeInkExtents[2] = (jdouble) pangoInkExtents.width; + nativeInkExtents[3] = (jdouble) pangoInkExtents.height; + + nativeLogExtents[0] = (jdouble) pangoLogExtents.x; + nativeLogExtents[1] = (jdouble) pangoLogExtents.y; + nativeLogExtents[2] = (jdouble) pangoLogExtents.width; + nativeLogExtents[3] = (jdouble) pangoLogExtents.height; + + (*env)->ReleaseDoubleArrayElements (env, javaInkExtents, nativeInkExtents, 0); + (*env)->ReleaseDoubleArrayElements (env, javaLogExtents, nativeLogExtents, 0); + + gdk_threads_leave (); +} + +JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkTextLayout_dispose + (JNIEnv *env, jobject self) +{ + struct textlayout *tl; + + gdk_threads_enter (); + g_assert(self != NULL); + tl = (struct textlayout *) NSA_DEL_TEXT_LAYOUT_PTR (env, self); + g_assert(tl != NULL); + if (tl->pango_layout != NULL) + g_object_unref (tl->pango_layout); + g_free(tl); + gdk_threads_leave (); +} diff --git a/libjava/jni/gtk-peer/gtkpeer.h b/libjava/jni/gtk-peer/gtkpeer.h index 754658c36e2..47f524420bd 100644 --- a/libjava/jni/gtk-peer/gtkpeer.h +++ b/libjava/jni/gtk-peer/gtkpeer.h @@ -115,6 +115,9 @@ struct graphics GdkDrawable *drawable; GdkGC *gc; GdkColormap *cm; + PangoFontDescription *pango_font; + PangoContext *pango_context; + PangoLayout *pango_layout; jint x_offset, y_offset; }; |