
2003-10-14 Graydon Hoare <graydon@redhat.com> * gnu/java/awt/ClasspathToolkit.java: New abstract class. * gnu/java/awt/peer/ClasspathFontPeer.java: New abstract class. * gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c: New concrete implementation of ClasspathFontPeer, with native part. * gnu/java/awt/peer/gtk/GdkGlyphVector.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c: New class, with native part. * gnu/java/awt/peer/gtk/GdkGraphics2D.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c: implement setFont, cairoSetFont, drawGlyphVector, cairoShowGlyphs. From-SVN: r72931
342 lines
10 KiB
Java
342 lines
10 KiB
Java
/* GdkGlyphVector.java -- Glyph vector 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. */
|
|
|
|
|
|
package gnu.java.awt.peer.gtk;
|
|
|
|
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.util.Locale;
|
|
import java.util.Map;
|
|
import java.util.StringTokenizer;
|
|
import java.text.CharacterIterator;
|
|
import java.text.AttributedCharacterIterator;
|
|
import gnu.classpath.Configuration;
|
|
|
|
public class GdkGlyphVector extends GlyphVector
|
|
{
|
|
|
|
static
|
|
{
|
|
if (Configuration.INIT_LOAD_LIBRARY)
|
|
{
|
|
System.loadLibrary("gtkpeer");
|
|
}
|
|
initStaticState ();
|
|
}
|
|
native static void initStaticState ();
|
|
private final int native_state = GtkGenericPeer.getUniqueInteger ();
|
|
|
|
private Font font;
|
|
private FontRenderContext ctx;
|
|
|
|
private native void initState (GdkClasspathFontPeer peer, FontRenderContext ctx);
|
|
private native void setChars (String s);
|
|
private native void setGlyphCodes (int codes[]);
|
|
private native void dispose ();
|
|
private native int glyphCode (int idx);
|
|
private native int numGlyphs ();
|
|
private native int glyphCharIndex (int idx);
|
|
private native double[] allLogicalExtents ();
|
|
private native double[] allInkExtents ();
|
|
private native double[] glyphLogicalExtents (int idx);
|
|
private native double[] glyphInkExtents (int idx);
|
|
private native boolean glyphIsHorizontal (int idx);
|
|
private native boolean isEqual (GdkGlyphVector ggv);
|
|
|
|
|
|
/*
|
|
geometric notes:
|
|
|
|
the FRC contains a mapping from points -> pixels.
|
|
|
|
typographics points are typically 1/72 of an inch.
|
|
|
|
pixel displays are often around 72 dpi.
|
|
|
|
so the FRC can get away with using an identity transform on a screen,
|
|
often. behavior is documented by sun to fall back to an identity
|
|
transform if the internal transformation is null.
|
|
|
|
coordinates coming up from pango are expressed as floats -- in device
|
|
space, so basically pixels-with-fractional-bits -- derived from their
|
|
storage format in pango (1024ths of pixels).
|
|
|
|
it is not clear from the javadocs whether the results of methods like
|
|
getGlyphPositions ought to return coordinates in device space, or
|
|
"point" space, or what. for now I'm returning them in device space.
|
|
|
|
*/
|
|
|
|
|
|
public GdkGlyphVector (Font f, GdkClasspathFontPeer peer, FontRenderContext c, String s)
|
|
{
|
|
font = f;
|
|
ctx = c;
|
|
initState (peer, ctx);
|
|
setChars (s);
|
|
}
|
|
|
|
public GdkGlyphVector (Font f, GdkClasspathFontPeer peer, FontRenderContext c, int codes[])
|
|
{
|
|
font = f;
|
|
ctx = c;
|
|
initState (peer, ctx);
|
|
setGlyphCodes (codes);
|
|
}
|
|
|
|
protected void finalize ()
|
|
{
|
|
dispose ();
|
|
}
|
|
|
|
public Font getFont ()
|
|
{
|
|
return font;
|
|
}
|
|
|
|
public FontRenderContext getFontRenderContext ()
|
|
{
|
|
return ctx;
|
|
}
|
|
|
|
public int getGlyphCharIndex (int glyphIndex)
|
|
{
|
|
return glyphCharIndex (glyphIndex);
|
|
}
|
|
|
|
public int[] getGlyphCharIndices (int beginGlyphIndex,
|
|
int numEntries,
|
|
int[] codeReturn)
|
|
{
|
|
int ix[] = codeReturn;
|
|
if (ix == null)
|
|
ix = new int[numEntries];
|
|
|
|
for (int i = 0; i < numEntries; i++)
|
|
ix[i] = glyphCharIndex (beginGlyphIndex + i);
|
|
return ix;
|
|
}
|
|
|
|
public int getGlyphCode (int glyphIndex)
|
|
{
|
|
return glyphCode (glyphIndex);
|
|
}
|
|
|
|
public int[] getGlyphCodes (int beginGlyphIndex, int numEntries,
|
|
int[] codeReturn)
|
|
{
|
|
int ix[] = codeReturn;
|
|
if (ix == null)
|
|
ix = new int[numEntries];
|
|
|
|
for (int i = 0; i < numEntries; i++)
|
|
ix[i] = glyphCode (beginGlyphIndex + i);
|
|
return ix;
|
|
}
|
|
|
|
public Shape getGlyphLogicalBounds (int glyphIndex)
|
|
{
|
|
double extents[] = glyphLogicalExtents (glyphIndex);
|
|
return new Rectangle2D.Double (extents[0], extents[1],
|
|
extents[2], extents[3]);
|
|
}
|
|
|
|
public GlyphMetrics getGlyphMetrics (int glyphIndex)
|
|
{
|
|
double extents[] = glyphLogicalExtents (glyphIndex);
|
|
Rectangle2D log_bounds = new Rectangle2D.Double (extents[0], extents[1],
|
|
extents[2], extents[3]);
|
|
|
|
extents = glyphInkExtents (glyphIndex);
|
|
Rectangle2D ink_bounds = new Rectangle2D.Double (extents[0], extents[1],
|
|
extents[2], extents[3]);
|
|
|
|
boolean is_horizontal = glyphIsHorizontal (glyphIndex);
|
|
|
|
return new GlyphMetrics (is_horizontal,
|
|
(float)(log_bounds.getWidth() + log_bounds.getX()),
|
|
(float)(log_bounds.getHeight() + log_bounds.getY()),
|
|
ink_bounds, GlyphMetrics.STANDARD);
|
|
}
|
|
|
|
public Shape getGlyphOutline (int glyphIndex)
|
|
{
|
|
throw new UnsupportedOperationException ();
|
|
}
|
|
|
|
public Shape getGlyphOutline (int glyphIndex, float x, float y)
|
|
{
|
|
throw new UnsupportedOperationException ();
|
|
}
|
|
|
|
public Rectangle getGlyphPixelBounds (int glyphIndex,
|
|
FontRenderContext renderFRC,
|
|
float x, float y)
|
|
{
|
|
double extents[] = glyphInkExtents(glyphIndex);
|
|
return new Rectangle ((int)x, (int)y, (int)extents[2], (int)extents[3]);
|
|
}
|
|
|
|
public Point2D getGlyphPosition (int glyphIndex)
|
|
{
|
|
float[] ret = new float[2 * (glyphIndex + 1)];
|
|
getGlyphPositions (0, glyphIndex + 1, ret);
|
|
return new Point2D.Float (ret[2 * glyphIndex],
|
|
ret[2 * glyphIndex + 1]);
|
|
}
|
|
|
|
public float[] getGlyphPositions (int beginGlyphIndex,
|
|
int numEntries,
|
|
float[] positionReturn)
|
|
{
|
|
float fx[] = positionReturn;
|
|
if (fx == null)
|
|
fx = new float[numEntries * 2];
|
|
|
|
|
|
float x = 0.0f;
|
|
float y = 0.0f;
|
|
for (int i = 0; i < numEntries; ++i)
|
|
{
|
|
boolean is_horizontal = glyphIsHorizontal (beginGlyphIndex + i);
|
|
double log_extents[] = glyphLogicalExtents (beginGlyphIndex + i);
|
|
fx[2*i] = x + (float)log_extents[0]; // x offset
|
|
fx[2*i + 1] = y + (float)log_extents[1]; // y offset
|
|
if (is_horizontal)
|
|
x += (float)log_extents[2]; // x advance ("logical width") in pango-ese
|
|
else
|
|
y += (float)log_extents[3]; // y advance ("logical height") in pango-ese
|
|
}
|
|
return fx;
|
|
}
|
|
|
|
public AffineTransform getGlyphTransform (int glyphIndex)
|
|
{
|
|
// glyphs don't have independent transforms in these simple glyph
|
|
// vectors; docs specify null is an ok return here.
|
|
return null;
|
|
}
|
|
|
|
public Shape getGlyphVisualBounds (int glyphIndex)
|
|
{
|
|
double extents[] = glyphInkExtents (glyphIndex);
|
|
return new Rectangle2D.Double (extents[0], extents[1],
|
|
extents[2], extents[3]);
|
|
}
|
|
|
|
public int getLayoutFlags ()
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
public Rectangle2D getLogicalBounds ()
|
|
{
|
|
double extents[] = allLogicalExtents ();
|
|
return new Rectangle2D.Double (extents[0], extents[1],
|
|
extents[2], extents[3]);
|
|
}
|
|
|
|
public int getNumGlyphs ()
|
|
{
|
|
return numGlyphs ();
|
|
}
|
|
|
|
public Shape getOutline ()
|
|
{
|
|
throw new UnsupportedOperationException ();
|
|
}
|
|
|
|
public Rectangle getPixelBounds (FontRenderContext renderFRC,
|
|
float x, float y)
|
|
{
|
|
double extents[] = allInkExtents();
|
|
return new Rectangle ((int)x, (int)y,
|
|
(int)extents[2], (int)extents[3]);
|
|
}
|
|
|
|
public Rectangle2D getVisualBounds ()
|
|
{
|
|
double extents[] = allInkExtents();
|
|
return new Rectangle2D.Double (extents[0], extents[1],
|
|
extents[2], extents[3]);
|
|
}
|
|
|
|
public void performDefaultLayout ()
|
|
{
|
|
}
|
|
|
|
public void setGlyphPosition (int glyphIndex, Point2D newPos)
|
|
{
|
|
// should we be ok twiddling pango's structure here?
|
|
throw new UnsupportedOperationException ();
|
|
}
|
|
|
|
public void setGlyphTransform (int glyphIndex,
|
|
AffineTransform newTX)
|
|
{
|
|
// not yet.. maybe not ever?
|
|
throw new UnsupportedOperationException ();
|
|
}
|
|
|
|
public boolean equals(GlyphVector gv)
|
|
{
|
|
if (gv == null)
|
|
return false;
|
|
|
|
if (! (gv instanceof GdkGlyphVector))
|
|
return false;
|
|
|
|
GdkGlyphVector ggv = (GdkGlyphVector)gv;
|
|
return isEqual(ggv);
|
|
}
|
|
|
|
public GlyphJustificationInfo getGlyphJustificationInfo(int idx)
|
|
{
|
|
throw new UnsupportedOperationException ();
|
|
}
|
|
|
|
public Shape getOutline(float x, float y)
|
|
{
|
|
throw new UnsupportedOperationException ();
|
|
}
|
|
|
|
}
|