2 Copyright (C) 2003, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package gnu
.java
.awt
.peer
.gtk
;
41 import gnu
.classpath
.Configuration
;
42 import gnu
.java
.awt
.peer
.ClasspathTextLayoutPeer
;
45 import java
.awt
.Graphics2D
;
46 import java
.awt
.Shape
;
47 import java
.awt
.font
.FontRenderContext
;
48 import java
.awt
.font
.GlyphMetrics
;
49 import java
.awt
.font
.GlyphVector
;
50 import java
.awt
.font
.TextAttribute
;
51 import java
.awt
.font
.TextHitInfo
;
52 import java
.awt
.font
.TextLayout
;
53 import java
.awt
.geom
.AffineTransform
;
54 import java
.awt
.geom
.GeneralPath
;
55 import java
.awt
.geom
.Rectangle2D
;
56 import java
.text
.AttributedCharacterIterator
;
57 import java
.text
.AttributedString
;
58 import java
.text
.CharacterIterator
;
61 * This is an implementation of the text layout peer interface which
62 * delegates all the hard work to pango.
64 * @author Graydon Hoare
67 public class GdkTextLayout
68 implements ClasspathTextLayoutPeer
70 // native side, plumbing, etc.
73 if (Configuration
.INIT_LOAD_LIBRARY
)
75 System
.loadLibrary("gtkpeer");
79 private native void setText(String str
);
80 private native void getExtents(double[] inkExtents
,
82 private native void indexToPos(int idx
, double[] pos
);
83 private native void initState ();
84 private native void dispose ();
85 static native void initStaticState();
86 private final int native_state
= GtkGenericPeer
.getUniqueInteger ();
87 protected void finalize ()
92 // we hold on to these to make sure we can render when presented
93 // with non-GdkGraphics2D paint targets
94 private AttributedString attributedString
;
95 private FontRenderContext fontRenderContext
;
97 public GdkTextLayout(AttributedString str
, FontRenderContext frc
)
100 attributedString
= str
;
101 fontRenderContext
= frc
;
104 protected class CharacterIteratorProxy
105 implements CharacterIterator
107 public CharacterIterator target
;
112 public CharacterIteratorProxy (CharacterIterator ci
)
117 public int getBeginIndex ()
122 public int getEndIndex ()
127 public int getIndex ()
132 public char setIndex (int idx
)
133 throws IllegalArgumentException
135 if (idx
< begin
|| idx
>= limit
)
136 throw new IllegalArgumentException ();
137 char ch
= target
.setIndex (idx
);
144 int save
= target
.getIndex ();
145 char ch
= target
.setIndex (begin
);
146 target
.setIndex (save
);
153 return this.first ();
155 int save
= target
.getIndex ();
156 char ch
= target
.setIndex (limit
- 1);
157 target
.setIndex (save
);
161 public char current ()
163 return target
.current();
168 if (index
>= limit
- 1)
169 return CharacterIterator
.DONE
;
173 return target
.next();
177 public char previous ()
180 return CharacterIterator
.DONE
;
184 return target
.previous ();
188 public Object
clone ()
190 CharacterIteratorProxy cip
= new CharacterIteratorProxy (this.target
);
191 cip
.begin
= this.begin
;
192 cip
.limit
= this.limit
;
193 cip
.index
= this.index
;
202 public void draw (Graphics2D g2
, float x
, float y
)
204 if (g2
instanceof GdkGraphics2D
)
206 // we share pango structures directly with GdkGraphics2D
208 GdkGraphics2D gg2
= (GdkGraphics2D
) g2
;
209 gg2
.drawGdkTextLayout(this, x
, y
);
213 // falling back to a rather tedious layout algorithm when
215 AttributedCharacterIterator ci
= attributedString
.getIterator ();
216 CharacterIteratorProxy proxy
= new CharacterIteratorProxy (ci
);
217 Font defFont
= g2
.getFont ();
219 /* Note: this implementation currently only interprets FONT text
220 * attributes. There is a reasonable argument to be made for some
221 * attributes being interpreted out here, where we have control of the
222 * Graphics2D and can construct or derive new fonts, and some
223 * attributes being interpreted by the GlyphVector itself. So far, for
224 * all attributes except FONT we do neither.
227 for (char c
= ci
.first ();
228 c
!= CharacterIterator
.DONE
;
231 proxy
.begin
= ci
.getIndex ();
232 proxy
.limit
= ci
.getRunLimit(TextAttribute
.FONT
);
233 if (proxy
.limit
<= proxy
.begin
)
236 proxy
.index
= proxy
.begin
;
238 Object fnt
= ci
.getAttribute(TextAttribute
.FONT
);
240 if (fnt
instanceof Font
)
241 gv
= ((Font
)fnt
).createGlyphVector (fontRenderContext
, proxy
);
243 gv
= defFont
.createGlyphVector (fontRenderContext
, proxy
);
245 g2
.drawGlyphVector (gv
, x
, y
);
247 int n
= gv
.getNumGlyphs ();
248 for (int i
= 0; i
< n
; ++i
)
250 GlyphMetrics gm
= gv
.getGlyphMetrics (i
);
251 if (gm
.getAdvanceX() == gm
.getAdvance ())
252 x
+= gm
.getAdvanceX ();
254 y
+= gm
.getAdvanceY ();
260 public TextHitInfo
getStrongCaret (TextHitInfo hit1
,
263 throw new Error("not implemented");
266 public byte getBaseline ()
268 throw new Error("not implemented");
271 public boolean isLeftToRight ()
273 throw new Error("not implemented");
276 public boolean isVertical ()
278 throw new Error("not implemented");
281 public float getAdvance ()
283 throw new Error("not implemented");
286 public float getAscent ()
288 throw new Error("not implemented");
291 public float getDescent ()
293 throw new Error("not implemented");
296 public float getLeading ()
298 throw new Error("not implemented");
301 public int getCharacterCount ()
303 throw new Error("not implemented");
306 public byte getCharacterLevel (int index
)
308 throw new Error("not implemented");
311 public float[] getBaselineOffsets ()
313 throw new Error("not implemented");
316 public Shape
getBlackBoxBounds (int firstEndpoint
, int secondEndpoint
)
318 throw new Error("not implemented");
321 public Rectangle2D
getBounds ()
323 double[] inkExtents
= new double[4];
324 double[] logExtents
= new double[4];
325 getExtents(inkExtents
, logExtents
);
326 return new Rectangle2D
.Double(logExtents
[0], logExtents
[1],
327 logExtents
[2], logExtents
[3]);
330 public float[] getCaretInfo (TextHitInfo hit
, Rectangle2D bounds
)
332 throw new Error("not implemented");
335 public Shape
getCaretShape (TextHitInfo hit
, Rectangle2D bounds
)
337 throw new Error("not implemented");
340 public Shape
[] getCaretShapes (int offset
, Rectangle2D bounds
,
341 TextLayout
.CaretPolicy policy
)
343 throw new Error("not implemented");
346 public Shape
getLogicalHighlightShape (int firstEndpoint
, int secondEndpoint
,
349 AffineTransform at
= new AffineTransform();
350 GeneralPath gp
= new GeneralPath();
351 double [] rect
= new double[4];
352 Rectangle2D tmp
= new Rectangle2D
.Double();
353 for (int i
= firstEndpoint
; i
<= secondEndpoint
; ++i
)
356 tmp
.setRect(rect
[0], rect
[1], rect
[2], rect
[3]);
357 Rectangle2D
.intersect(tmp
, bounds
, tmp
);
358 gp
.append(tmp
.getPathIterator(at
), false);
363 public int[] getLogicalRangesForVisualSelection (TextHitInfo firstEndpoint
,
364 TextHitInfo secondEndpoint
)
366 throw new Error("not implemented");
369 public TextHitInfo
getNextLeftHit (int offset
, TextLayout
.CaretPolicy policy
)
371 throw new Error("not implemented");
373 public TextHitInfo
getNextRightHit (int offset
, TextLayout
.CaretPolicy policy
)
375 throw new Error("not implemented");
377 public TextHitInfo
hitTestChar (float x
, float y
, Rectangle2D bounds
)
379 throw new Error("not implemented");
381 public TextHitInfo
getVisualOtherHit (TextHitInfo hit
)
383 throw new Error("not implemented");
386 public float getVisibleAdvance ()
388 throw new Error("not implemented");
391 public native Shape
getOutline (AffineTransform tx
);
393 public Shape
getVisualHighlightShape (TextHitInfo firstEndpoint
,
394 TextHitInfo secondEndpoint
,
397 throw new Error("not implemented");
401 public TextLayout
getJustifiedLayout (float justificationWidth
)
403 throw new Error("not implemented");
406 public void handleJustify (float justificationWidth
)
408 throw new Error("not implemented");
411 public Object
clone ()
413 throw new Error("not implemented");
416 public int hashCode ()
418 throw new Error("not implemented");
421 public boolean equals (ClasspathTextLayoutPeer tl
)
423 throw new Error("not implemented");
426 public String
toString ()
428 throw new Error("not implemented");