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