It seems like jIRCii makes use of some more sophisticated font methods,
that didn't work quite right and lead to overlapping chars in jIRCii's
text components:
- Control characters (like \n) need to be filtered in the TextLayout and
GdkFontPeer so that the aren't rendered and also not measured in the
glyph metrics. Otherwise we get strange boxes when accidentally
rendering \n and other chars.
- Font.getStringBounds() can be implemented without a peer interface by
using TextLayout. We should maybe throw out some more ClasspathFontPeer
stuff and maybe provide a generic FontMetrics/LineMetrics implementation
based on TextLayout too.
- Fresh Window objects need to have a font set.
- In FreetypeGlyphVector.getLogicalBounds() we don't need to translate
the glyph bounds. They already are translated.
2006-11-02 Roman Kennke <[EMAIL PROTECTED]>
PR 29644
* gnu/java/awt/peer/ClasspathFontPeer.java
(getStringBounds): Removed abstract method. This is replaced
in java.awt.Font to use a TextLayout.
* gnu/java/awt/peer/gtk/GtkWindowPeer.java
(GtkWindowPeer): Set a font on the window object.
* gnu/java/awt/peer/gtk/FreetypeGlyphVector.java
(FreetypeGlyphVector(Font,String,FontRenderContext,int)):
Changed to take char,int,int instead of String. Filter
control characters.
(FreetypeGlyphVector(Font,String,FontRenderContext)):
Create char array out of string.
(getLogicalBounds): Don't translate bounds. They already are
translated.
* gnu/java/awt/peer/gtk/GdkFontMetrics.java
(stringWidth): Filter out control characters.
* gnu/java/awt/peer/gtk/GdkFontPeer.java
(getStringBounds): Removed unneeded method.
(layoutGlyphVector): Pass char array directly to FreetypeGlyphVector
constructor.
* gnu/java/awt/peer/qt/QtFontPeer.java
(getStringBounds): Removed unneeded method.
* gnu/java/awt/peer/x/XFontPeer.java
(getStringBounds): Removed unneeded method.
* gnu/java/awt/peer/x/XFontPeer2.java
(getStringBounds): Removed unneeded method.
* java/awt/Font.java
(getStringBounds(char[],int,int,FontRenderContext)):
Use TextLayout to determine the bounds.
(getStringBounds(CharacterIterator,int,int,FontRenderContext)):
Delegate to the char[] version of this method.
(getStringBounds(String,FontRenderContext)):
Delegate to the char[] version of this method.
(getStringBounds(String,int,int,FontRenderContext)):
Delegate to the String version of this method.
/Roman
------------------------------------------------------------------------
Index: gnu/java/awt/peer/x/XFontPeer.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/x/XFontPeer.java,v
retrieving revision 1.2
diff -u -1 -5 -r1.2 XFontPeer.java
--- gnu/java/awt/peer/x/XFontPeer.java 18 Jul 2006 18:17:10 -0000 1.2
+++ gnu/java/awt/peer/x/XFontPeer.java 2 Nov 2006 11:01:15 -0000
@@ -596,37 +596,30 @@
* Returns the line metrics for this font and the specified string and
* font render context.
*/
public LineMetrics getLineMetrics(Font font, CharacterIterator ci, int begin,
int limit, FontRenderContext rc)
{
return new XLineMetrics();
}
public Rectangle2D getMaxCharBounds(Font font, FontRenderContext rc)
{
// TODO: Implement this.
throw new UnsupportedOperationException("Not yet implemented.");
}
- public Rectangle2D getStringBounds(Font font, CharacterIterator ci,
- int begin, int limit, FontRenderContext
frc)
- {
- // TODO: Implement this.
- throw new UnsupportedOperationException("Not yet implemented.");
- }
-
/**
* Encodes a font name + style + size specification into a X logical font
* description (XLFD) as described here:
*
* http://www.meretrx.com/e93/docs/xlfd.html
*
* This is implemented to look up the font description in the
* fonts.properties of this package.
*
* @param name the font name
* @param atts the text attributes
*
* @return the encoded font description
*/
static String encodeFont(String name, Map atts)
Index: gnu/java/awt/peer/x/XFontPeer2.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/x/XFontPeer2.java,v
retrieving revision 1.1
diff -u -1 -5 -r1.1 XFontPeer2.java
--- gnu/java/awt/peer/x/XFontPeer2.java 29 Jun 2006 15:15:56 -0000 1.1
+++ gnu/java/awt/peer/x/XFontPeer2.java 2 Nov 2006 11:01:15 -0000
@@ -314,22 +314,16 @@
// FIXME: Implement this.
throw new UnsupportedOperationException("Not yet implemented");
}
public LineMetrics getLineMetrics(Font font, CharacterIterator ci, int begin, int limit, FontRenderContext rc)
{
return new XLineMetrics(font, ci, begin, limit, rc);
}
public Rectangle2D getMaxCharBounds(Font font, FontRenderContext rc)
{
// FIXME: Implement this.
throw new UnsupportedOperationException("Not yet implemented");
}
- public Rectangle2D getStringBounds(Font font, CharacterIterator ci, int begin, int limit, FontRenderContext frc)
- {
- // FIXME: Implement this.
- throw new UnsupportedOperationException("Not yet implemented");
- }
-
}
Index: java/awt/Font.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/awt/Font.java,v
retrieving revision 1.37
diff -u -1 -5 -r1.37 Font.java
--- java/awt/Font.java 25 Jul 2006 17:58:52 -0000 1.37
+++ java/awt/Font.java 2 Nov 2006 11:01:15 -0000
@@ -1074,118 +1074,129 @@
* font in the specified [EMAIL PROTECTED] FontRenderContext}. This box will
include the
* glyph origin, ascent, advance, height, and leading, but may not include
all
* diacritics or accents. To get the complete visual bounding box of all the
* glyphs in a run of text, use the [EMAIL PROTECTED] TextLayout#getBounds} method of
* [EMAIL PROTECTED] TextLayout}.
*
* @param str The string to measure.
* @param frc The context in which to make the precise glyph measurements.
*
* @return A bounding box covering the logical bounds of the specified text.
*
* @see #createGlyphVector(FontRenderContext, String)
*/
public Rectangle2D getStringBounds(String str, FontRenderContext frc)
{
- return getStringBounds(str, 0, str.length() - 1, frc);
+ char[] chars = str.toCharArray();
+ return getStringBounds(chars, 0, chars.length, frc);
}
/**
* Returns the logical bounds of the specified string when rendered with this
* font in the specified [EMAIL PROTECTED] FontRenderContext}. This box will
include the
* glyph origin, ascent, advance, height, and leading, but may not include
all
* diacritics or accents. To get the complete visual bounding box of all the
* glyphs in a run of text, use the [EMAIL PROTECTED] TextLayout#getBounds}
method of
* [EMAIL PROTECTED] TextLayout}.
*
* @param str The string to measure.
* @param begin Index of the first character in <code>str</code> to measure.
* @param limit Index of the last character in <code>str</code> to measure.
* @param frc The context in which to make the precise glyph measurements.
*
* @return A bounding box covering the logical bounds of the specified text.
*
* @throws IndexOutOfBoundsException if the range [begin, limit] is
* invalid in <code>str</code>.
*
* @since 1.2
*
* @see #createGlyphVector(FontRenderContext, String)
*/
public Rectangle2D getStringBounds(String str, int begin,
int limit, FontRenderContext frc)
{
- return peer.getStringBounds(this, new StringCharacterIterator(str), begin,
- limit, frc);
+ String sub = str.substring(begin, limit);
+ return getStringBounds(sub, frc);
}
/**
* Returns the logical bounds of the specified string when rendered with this
* font in the specified [EMAIL PROTECTED] FontRenderContext}. This box will
include the
* glyph origin, ascent, advance, height, and leading, but may not include
all
* diacritics or accents. To get the complete visual bounding box of all the
* glyphs in a run of text, use the [EMAIL PROTECTED] TextLayout#getBounds}
method of
* [EMAIL PROTECTED] TextLayout}.
*
* @param ci The text to measure.
* @param begin Index of the first character in <code>ci</code> to measure.
* @param limit Index of the last character in <code>ci</code> to measure.
* @param frc The context in which to make the precise glyph measurements.
*
* @return A bounding box covering the logical bounds of the specified text.
*
* @throws IndexOutOfBoundsException if the range [begin, limit] is
* invalid in <code>ci</code>.
*
* @since 1.2
*
* @see #createGlyphVector(FontRenderContext, CharacterIterator)
*/
public Rectangle2D getStringBounds(CharacterIterator ci, int begin,
int limit, FontRenderContext frc)
{
- return peer.getStringBounds(this, ci, begin, limit, frc);
+ int start = ci.getBeginIndex();
+ int end = ci.getEndIndex();
+ char[] chars = new char[limit - start];
+ ci.setIndex(start);
+ for (int index = 0; index < chars.length; index++)
+ {
+ chars[index] = ci.current();
+ ci.next();
+ }
+ return getStringBounds(chars, 0, chars.length, frc);
}
/**
* Returns the logical bounds of the specified string when rendered with this
* font in the specified [EMAIL PROTECTED] FontRenderContext}. This box will
include the
* glyph origin, ascent, advance, height, and leading, but may not include
all
* diacritics or accents. To get the complete visual bounding box of all the
* glyphs in a run of text, use the [EMAIL PROTECTED] TextLayout#getBounds}
method of
* [EMAIL PROTECTED] TextLayout}.
*
* @param chars The text to measure.
* @param begin Index of the first character in <code>ci</code> to measure.
* @param limit Index of the last character in <code>ci</code> to measure.
* @param frc The context in which to make the precise glyph measurements.
*
* @return A bounding box covering the logical bounds of the specified text.
*
* @throws IndexOutOfBoundsException if the range [begin, limit] is
* invalid in <code>chars</code>.
*
* @since 1.2
*
* @see #createGlyphVector(FontRenderContext, char[])
*/
public Rectangle2D getStringBounds(char[] chars, int begin,
int limit, FontRenderContext frc)
{
- return peer.getStringBounds(this,
- new StringCharacterIterator(new String(chars)),
- begin, limit, frc);
+ String str = new String(chars, begin, limit - begin);
+ TextLayout layout = new TextLayout(str, this, frc);
+ return new Rectangle2D.Float(0, -layout.getAscent(), layout.getAdvance(),
+ layout.getDescent() + layout.getLeading());
}
/**
* Returns a copy of the affine transformation this font is currently
* subject to, if any.
*
* @return The current transformation.
*/
public AffineTransform getTransform()
{
return peer.getTransform(this);
}
/**
* Indicates whether this font's line metrics are uniform. A font may be
Index: gnu/java/awt/peer/gtk/FreetypeGlyphVector.java
===================================================================
RCS file:
/cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java,v
retrieving revision 1.11
diff -u -1 -5 -r1.11 FreetypeGlyphVector.java
--- gnu/java/awt/peer/gtk/FreetypeGlyphVector.java 17 Oct 2006 18:08:37
-0000 1.11
+++ gnu/java/awt/peer/gtk/FreetypeGlyphVector.java 2 Nov 2006 11:01:15
-0000
@@ -80,40 +80,47 @@
*/
private int[] glyphCodes;
/**
* Glyph transforms. (de facto only the translation is used)
*/
private AffineTransform[] glyphTransforms;
private GlyphMetrics[] metricsCache;
/**
* Create a glyphvector from a given (Freetype) font and a String.
*/
public FreetypeGlyphVector(Font f, String s, FontRenderContext frc)
{
- this(f, s, frc, Font.LAYOUT_LEFT_TO_RIGHT);
+ this(f, s.toCharArray(), 0, s.length(), frc, Font.LAYOUT_LEFT_TO_RIGHT);
}
/**
* Create a glyphvector from a given (Freetype) font and a String.
*/
- public FreetypeGlyphVector(Font f, String s, FontRenderContext frc,
- int flags)
+ public FreetypeGlyphVector(Font f, char[] chars, int start, int len,
+ FontRenderContext frc, int flags)
{
- this.s = s;
+ // We need to filter out control characters (and possibly other
+ // non-renderable characters here).
+ StringBuilder b = new StringBuilder(chars.length);
+ for (int i = start; i < start + len; i++)
+ if (!Character.isISOControl(chars[i]))
+ b.append(chars[i]);
+ this.s = b.toString();
+
this.font = f;
this.frc = frc;
if( !(font.getPeer() instanceof GdkFontPeer ) )
throw new IllegalArgumentException("Not a valid font.");
peer = (GdkFontPeer)font.getPeer();
getGlyphs();
if( flags == Font.LAYOUT_RIGHT_TO_LEFT )
{
// reverse the glyph ordering.
int[] temp = new int[ nGlyphs ];
for(int i = 0; i < nGlyphs; i++)
temp[ i ] = glyphCodes[ nGlyphs - i - 1];
glyphCodes = temp;
}
@@ -417,36 +424,30 @@
* Return the logical bounds of the whole thing.
*/
public Rectangle2D getLogicalBounds()
{
if( nGlyphs == 0 )
return new Rectangle2D.Double(0, 0, 0, 0);
if( logicalBounds != null )
return logicalBounds;
Rectangle2D rect = (Rectangle2D)getGlyphLogicalBounds( 0 );
AffineTransform tx = new AffineTransform();
for( int i = 1; i < nGlyphs; i++ )
{
Rectangle2D r2 = (Rectangle2D)getGlyphLogicalBounds( i );
- // Translate to the glyph's position
- tx.setToTranslation(glyphPositions[i*2], glyphPositions[i*2+1]);
- Point2D pt = new Point2D.Double(r2.getMinX(), r2.getMinY());
- tx.transform(pt, pt);
- r2.setRect(pt.getX(), pt.getY(), r2.getWidth(), r2.getHeight());
-
rect = rect.createUnion( r2 );
}
logicalBounds = rect;
return rect;
}
/**
* Returns the number of glyphs.
*/
public int getNumGlyphs()
{
return glyphCodes.length;
}
Index: gnu/java/awt/peer/gtk/GdkFontMetrics.java
===================================================================
RCS file:
/cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/GdkFontMetrics.java,v
retrieving revision 1.16
diff -u -1 -5 -r1.16 GdkFontMetrics.java
--- gnu/java/awt/peer/gtk/GdkFontMetrics.java 16 Mar 2006 20:21:07 -0000
1.16
+++ gnu/java/awt/peer/gtk/GdkFontMetrics.java 2 Nov 2006 11:01:16 -0000
@@ -83,32 +83,46 @@
public GdkFontMetrics (Font font)
{
super(initFont(font));
peer = (GdkFontPeer) this.font.getPeer();
font_metrics = new int[5];
double [] hires = new double[5];
peer.getFontMetrics (hires);
for (int i = 0; i < 5; ++i)
font_metrics[i] = (int) hires[i];
}
public int stringWidth (String str)
{
+
+// TextLayout layout = new TextLayout(str, getFont(), null);
+// return (int) layout.getAdvance();
+ // We need to filter control chars, because they are never displayed
+ // in Java and thus also have no metrics.
+ int len = str.length();
+ StringBuilder b = new StringBuilder(len);
+ for (int i = 0; i < len; i++)
+ {
+ char ch = str.charAt(i);
+ if (! Character.isISOControl(ch))
+ b.append(ch);
+ }
double [] hires = new double[6];
- peer.getTextMetrics(str, hires);
+ String string = b.toString();
+ peer.getTextMetrics(string, hires);
return (int) hires [TEXT_METRICS_WIDTH];
}
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));
}
public int getLeading ()
{
Index: gnu/java/awt/peer/gtk/GdkFontPeer.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java,v
retrieving revision 1.19
diff -u -1 -5 -r1.19 GdkFontPeer.java
--- gnu/java/awt/peer/gtk/GdkFontPeer.java 17 Jul 2006 22:41:03 -0000
1.19
+++ gnu/java/awt/peer/gtk/GdkFontPeer.java 2 Nov 2006 11:01:16 -0000
@@ -333,50 +333,40 @@
{
throw new UnsupportedOperationException ();
}
public int getNumGlyphs (Font font)
{
byte[] data = getTrueTypeTable((byte)'m', (byte) 'a',
(byte)'x', (byte) 'p');
if( data == null )
return -1;
ByteBuffer buf = ByteBuffer.wrap( data );
return buf.getShort(4);
}
- public Rectangle2D getStringBounds (Font font, CharacterIterator ci,
- int begin, int limit, FontRenderContext frc)
- {
- GlyphVector gv = new FreetypeGlyphVector( font,
- buildString(ci, begin, limit),
- frc);
- return gv.getVisualBounds();
- }
-
public boolean hasUniformLineMetrics (Font font)
{
return true;
}
public GlyphVector layoutGlyphVector (Font font, FontRenderContext frc,
char[] chars, int start, int limit,
int flags)
{
- return new FreetypeGlyphVector( font, new String( chars, start,
- limit - start),
+ return new FreetypeGlyphVector( font, chars, start, limit - start,
frc, flags);
}
public LineMetrics getLineMetrics (Font font, String str,
FontRenderContext frc)
{
return new GdkFontLineMetrics (this, getFontMetrics (font), str.length ());
}
public FontMetrics getFontMetrics (Font font)
{
// Get the font metrics through GtkToolkit to take advantage of
// the metrics cache.
return Toolkit.getDefaultToolkit().getFontMetrics (font);
}
Index: gnu/java/awt/peer/gtk/GtkWindowPeer.java
===================================================================
RCS file:
/cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java,v
retrieving revision 1.57
diff -u -1 -5 -r1.57 GtkWindowPeer.java
--- gnu/java/awt/peer/gtk/GtkWindowPeer.java 18 Oct 2006 22:09:16 -0000
1.57
+++ gnu/java/awt/peer/gtk/GtkWindowPeer.java 2 Nov 2006 11:01:16 -0000
@@ -29,30 +29,31 @@
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.awt.peer.gtk;
import gnu.java.awt.ComponentReshapeEvent;
import java.awt.Component;
+import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.KeyboardFocusManager;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.event.ComponentEvent;
import java.awt.event.FocusEvent;
import java.awt.event.PaintEvent;
import java.awt.event.WindowEvent;
import java.awt.peer.WindowPeer;
public class GtkWindowPeer extends GtkContainerPeer
implements WindowPeer
{
protected static final int GDK_WINDOW_TYPE_HINT_NORMAL = 0;
@@ -139,30 +140,32 @@
setEnabled (awtComponent.isEnabled ());
}
void setVisibleAndEnabled ()
{
}
public native void setVisibleNative (boolean b);
public native void setVisibleNativeUnlocked (boolean b);
native void connectSignals ();
public GtkWindowPeer (Window window)
{
super (window);
+ // Set reasonable font for the window.
+ window.setFont(new Font("Dialog", Font.PLAIN, 12));
}
public native void toBack();
public native void toFront();
native void nativeSetBounds (int x, int y, int width, int height);
native void nativeSetBoundsUnlocked (int x, int y, int width, int height);
native void nativeSetLocation (int x, int y);
native void nativeSetLocationUnlocked (int x, int y);
// Called from show.
protected void setLocation (int x, int y)
{
nativeSetLocation (x, y);
}
Index: gnu/java/awt/peer/qt/QtFontPeer.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/qt/QtFontPeer.java,v
retrieving revision 1.4
diff -u -1 -5 -r1.4 QtFontPeer.java
--- gnu/java/awt/peer/qt/QtFontPeer.java 26 Jul 2006 20:08:07 -0000
1.4
+++ gnu/java/awt/peer/qt/QtFontPeer.java 2 Nov 2006 11:01:16 -0000
@@ -182,27 +182,16 @@
public LineMetrics getLineMetrics (Font font,
CharacterIterator ci,
int begin, int limit,
FontRenderContext rc)
{
throw new UnsupportedOperationException();
}
public Rectangle2D getMaxCharBounds (Font font,
FontRenderContext rc)
{
throw new UnsupportedOperationException();
}
- public Rectangle2D getStringBounds (Font font,
- CharacterIterator ci,
- int begin, int limit,
- FontRenderContext frc)
- {
- int index = begin;
- String s = "" + ci.setIndex( index );
- while( index++ <= limit )
- s = s + ci.next();
- return metrics.getStringBounds(s);
- }
}