下面列出了怎么用java.awt.font.GlyphVector的API类实例代码及写法,或者点击链接到github查看源代码。
public void drawGlyphVector(SunGraphics2D sg2d, GlyphVector gv,
float x, float y)
{
FontRenderContext frc = gv.getFontRenderContext();
FontInfo info = sg2d.getGVFontInfo(gv.getFont(), frc);
if (info.pixelHeight > OutlineTextRenderer.THRESHHOLD) {
SurfaceData.outlineTextRenderer.drawGlyphVector(sg2d, gv, x, y);
return;
}
if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
double origin[] = {x, y};
sg2d.transform.transform(origin, 0, origin, 0, 1);
x = (float) origin[0];
y = (float) origin[1];
} else {
x += sg2d.transX; // don't use the glyph info origin, already in gv.
y += sg2d.transY;
}
GlyphList gl = GlyphList.getInstance();
gl.setFromGlyphVector(info, gv, x, y);
drawGlyphList(sg2d, gl, info.aaHint);
gl.dispose();
}
private boolean samePositions(GlyphVector gv, int[] gvcodes,
int[] origCodes, float[] origPositions) {
int numGlyphs = gv.getNumGlyphs();
float[] gvpos = gv.getGlyphPositions(0, numGlyphs, null);
/* this shouldn't happen here, but just in case */
if (numGlyphs != gvcodes.length || /* real paranoia here */
origCodes.length != gvcodes.length ||
origPositions.length != gvpos.length) {
return false;
}
for (int i=0; i<numGlyphs; i++) {
if (gvcodes[i] != origCodes[i] || gvpos[i] != origPositions[i]) {
return false;
}
}
return true;
}
BufferedImage drawText(boolean doGV) {
int w = 400;
int h = 50;
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
g.setColor(Color.white);
g.fillRect(0,0,w,h);
g.setColor(Color.black);
Font f = helvFont.deriveFont(Font.PLAIN, 40);
g.setFont(f);
int x = 5;
int y = h - 10;
if (doGV) {
FontRenderContext frc = new FontRenderContext(null, true, true);
GlyphVector gv = f.createGlyphVector(frc, codes);
g.drawGlyphVector(gv, 5, y);
} else {
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g.drawString(str, x, y);
}
return bi;
}
public void drawGlyphVector(SunGraphics2D sg2d, GlyphVector g,
float x, float y)
{
FontRenderContext frc = g.getFontRenderContext();
FontInfo info = sg2d.getGVFontInfo(g.getFont(), frc);
switch (info.aaHint) {
case SunHints.INTVAL_TEXT_ANTIALIAS_OFF:
super.drawGlyphVector(sg2d, g, x, y);
return;
case SunHints.INTVAL_TEXT_ANTIALIAS_ON:
sg2d.surfaceData.aaTextRenderer.drawGlyphVector(sg2d, g, x, y);
return;
case SunHints.INTVAL_TEXT_ANTIALIAS_LCD_HRGB:
case SunHints.INTVAL_TEXT_ANTIALIAS_LCD_VRGB:
sg2d.surfaceData.lcdTextRenderer.drawGlyphVector(sg2d, g, x, y);
return;
default:
}
}
private boolean samePositions(GlyphVector gv, int[] gvcodes,
int[] origCodes, float[] origPositions) {
int numGlyphs = gv.getNumGlyphs();
float[] gvpos = gv.getGlyphPositions(0, numGlyphs, null);
/* this shouldn't happen here, but just in case */
if (numGlyphs != gvcodes.length || /* real paranoia here */
origCodes.length != gvcodes.length ||
origPositions.length != gvpos.length) {
return false;
}
for (int i=0; i<numGlyphs; i++) {
if (gvcodes[i] != origCodes[i] || gvpos[i] != origPositions[i]) {
return false;
}
}
return true;
}
public void drawGlyphVector(SunGraphics2D sg2d, GlyphVector gv,
float x, float y)
{
FontRenderContext frc = gv.getFontRenderContext();
FontInfo info = sg2d.getGVFontInfo(gv.getFont(), frc);
if (info.pixelHeight > OutlineTextRenderer.THRESHHOLD) {
SurfaceData.outlineTextRenderer.drawGlyphVector(sg2d, gv, x, y);
return;
}
if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
double origin[] = {x, y};
sg2d.transform.transform(origin, 0, origin, 0, 1);
x = (float) origin[0];
y = (float) origin[1];
} else {
x += sg2d.transX; // don't use the glyph info origin, already in gv.
y += sg2d.transY;
}
GlyphList gl = GlyphList.getInstance();
gl.setFromGlyphVector(info, gv, x, y);
drawGlyphList(sg2d, gl, info.aaHint);
gl.dispose();
}
public void drawGlyphVector(GlyphVector gv, float x, float y)
{
if (gv == null) {
throw new NullPointerException("GlyphVector is null");
}
try {
textpipe.drawGlyphVector(this, gv, x, y);
} catch (InvalidPipeException e) {
try {
revalidateAll();
textpipe.drawGlyphVector(this, gv, x, y);
} catch (InvalidPipeException e2) {
// Still catching the exception; we are not yet ready to
// validate the surfaceData correctly. Fail for now and
// try again next time around.
}
} finally {
surfaceData.markDirty();
}
}
BufferedImage drawText(boolean doGV) {
int w = 400;
int h = 50;
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
g.setColor(Color.white);
g.fillRect(0,0,w,h);
g.setColor(Color.black);
Font f = helvFont.deriveFont(Font.PLAIN, 40);
g.setFont(f);
int x = 5;
int y = h - 10;
if (doGV) {
FontRenderContext frc = new FontRenderContext(null, true, true);
GlyphVector gv = f.createGlyphVector(frc, codes);
g.drawGlyphVector(gv, 5, y);
} else {
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g.drawString(str, x, y);
}
return bi;
}
public void drawGlyphVector(GlyphVector gv, float x, float y)
{
if (gv == null) {
throw new NullPointerException("GlyphVector is null");
}
try {
textpipe.drawGlyphVector(this, gv, x, y);
} catch (InvalidPipeException e) {
try {
revalidateAll();
textpipe.drawGlyphVector(this, gv, x, y);
} catch (InvalidPipeException e2) {
// Still catching the exception; we are not yet ready to
// validate the surfaceData correctly. Fail for now and
// try again next time around.
}
} finally {
surfaceData.markDirty();
}
}
public void drawGlyphVector(SunGraphics2D sg2d, GlyphVector g,
float x, float y)
{
FontRenderContext frc = g.getFontRenderContext();
FontInfo info = sg2d.getGVFontInfo(g.getFont(), frc);
switch (info.aaHint) {
case SunHints.INTVAL_TEXT_ANTIALIAS_OFF:
super.drawGlyphVector(sg2d, g, x, y);
return;
case SunHints.INTVAL_TEXT_ANTIALIAS_ON:
sg2d.surfaceData.aaTextRenderer.drawGlyphVector(sg2d, g, x, y);
return;
case SunHints.INTVAL_TEXT_ANTIALIAS_LCD_HRGB:
case SunHints.INTVAL_TEXT_ANTIALIAS_LCD_VRGB:
sg2d.surfaceData.lcdTextRenderer.drawGlyphVector(sg2d, g, x, y);
return;
default:
}
}
@Override
public PieceMovableTypeWen setWen(ChineseCharacterMovableTypeTzu parent,
NonFinalCharComponent chineseCharacterWen)
{
SeprateMovabletype rectangularArea = null;
if (font.canDisplay(chineseCharacterWen.Unicode編號()))
{
GlyphVector glyphVector = font.createGlyphVector(fontRenderContext,
chineseCharacterWen.部件組字式());
rectangularArea = new SeprateMovabletype(new PlaneGeometry(glyphVector.getOutline()));
rectangularArea.設字範圍(tzuModelTerritory);
rectangularArea.設目標範圍(rectangularArea.這馬字範圍());
}
else
{
rectangularArea = findWenForNoBuiltIn(chineseCharacterWen);
}
rectangularArea.徙轉原點();
PieceMovableTypeWen pieceMovableTypeWen = new PieceMovableTypeWen(
parent, chineseCharacterWen, rectangularArea);
return pieceMovableTypeWen;
}
/**
* Returns the logical bounds of the specified array of characters
* in the specified <code>FontRenderContext</code>. The logical
* bounds contains the origin, ascent, advance, and height, which
* includes the leading. The logical bounds does not always enclose
* all the text. For example, in some languages and in some fonts,
* accent marks can be positioned above the ascent or below the
* descent. To obtain a visual bounding box, which encloses all the
* text, use the {@link TextLayout#getBounds() getBounds} method of
* <code>TextLayout</code>.
* <p>Note: The returned bounds is in baseline-relative coordinates
* (see {@link java.awt.Font class notes}).
* @param chars an array of characters
* @param beginIndex the initial offset in the array of
* characters
* @param limit the end offset in the array of characters
* @param frc the specified <code>FontRenderContext</code>
* @return a <code>Rectangle2D</code> that is the bounding box of the
* specified array of characters in the specified
* <code>FontRenderContext</code>.
* @throws IndexOutOfBoundsException if <code>beginIndex</code> is
* less than zero, or <code>limit</code> is greater than the
* length of <code>chars</code>, or <code>beginIndex</code>
* is greater than <code>limit</code>.
* @see FontRenderContext
* @see Font#createGlyphVector
* @since 1.2
*/
public Rectangle2D getStringBounds(char [] chars,
int beginIndex, int limit,
FontRenderContext frc) {
if (beginIndex < 0) {
throw new IndexOutOfBoundsException("beginIndex: " + beginIndex);
}
if (limit > chars.length) {
throw new IndexOutOfBoundsException("limit: " + limit);
}
if (beginIndex > limit) {
throw new IndexOutOfBoundsException("range length: " +
(limit - beginIndex));
}
// this code should be in textlayout
// quick check for simple text, assume GV ok to use if simple
boolean simple = values == null ||
(values.getKerning() == 0 && values.getLigatures() == 0 &&
values.getBaselineTransform() == null);
if (simple) {
simple = ! FontUtilities.isComplexText(chars, beginIndex, limit);
}
if (simple) {
GlyphVector gv = new StandardGlyphVector(this, chars, beginIndex,
limit - beginIndex, frc);
return gv.getLogicalBounds();
} else {
// need char array constructor on textlayout
String str = new String(chars, beginIndex, limit - beginIndex);
TextLayout tl = new TextLayout(str, this, frc);
return new Rectangle2D.Float(0, -tl.getAscent(), tl.getAdvance(),
tl.getAscent() + tl.getDescent() +
tl.getLeading());
}
}
/**
* Returns the logical bounds of the specified array of characters
* in the specified <code>FontRenderContext</code>. The logical
* bounds contains the origin, ascent, advance, and height, which
* includes the leading. The logical bounds does not always enclose
* all the text. For example, in some languages and in some fonts,
* accent marks can be positioned above the ascent or below the
* descent. To obtain a visual bounding box, which encloses all the
* text, use the {@link TextLayout#getBounds() getBounds} method of
* <code>TextLayout</code>.
* <p>Note: The returned bounds is in baseline-relative coordinates
* (see {@link java.awt.Font class notes}).
* @param chars an array of characters
* @param beginIndex the initial offset in the array of
* characters
* @param limit the end offset in the array of characters
* @param frc the specified <code>FontRenderContext</code>
* @return a <code>Rectangle2D</code> that is the bounding box of the
* specified array of characters in the specified
* <code>FontRenderContext</code>.
* @throws IndexOutOfBoundsException if <code>beginIndex</code> is
* less than zero, or <code>limit</code> is greater than the
* length of <code>chars</code>, or <code>beginIndex</code>
* is greater than <code>limit</code>.
* @see FontRenderContext
* @see Font#createGlyphVector
* @since 1.2
*/
public Rectangle2D getStringBounds(char [] chars,
int beginIndex, int limit,
FontRenderContext frc) {
if (beginIndex < 0) {
throw new IndexOutOfBoundsException("beginIndex: " + beginIndex);
}
if (limit > chars.length) {
throw new IndexOutOfBoundsException("limit: " + limit);
}
if (beginIndex > limit) {
throw new IndexOutOfBoundsException("range length: " +
(limit - beginIndex));
}
// this code should be in textlayout
// quick check for simple text, assume GV ok to use if simple
boolean simple = values == null ||
(values.getKerning() == 0 && values.getLigatures() == 0 &&
values.getBaselineTransform() == null);
if (simple) {
simple = ! FontUtilities.isComplexText(chars, beginIndex, limit);
}
if (simple) {
GlyphVector gv = new StandardGlyphVector(this, chars, beginIndex,
limit - beginIndex, frc);
return gv.getLogicalBounds();
} else {
// need char array constructor on textlayout
String str = new String(chars, beginIndex, limit - beginIndex);
TextLayout tl = new TextLayout(str, this, frc);
return new Rectangle2D.Float(0, -tl.getAscent(), tl.getAdvance(),
tl.getAscent() + tl.getDescent() +
tl.getLeading());
}
}
public void runTest(Object ctx, int numReps) {
GVContext gvctx = (GVContext)ctx;
GlyphVector gv = gvctx.gv;
GlyphMetrics gm;
do {
for (int i = 0, e = gv.getNumGlyphs(); i < e; ++i) {
gm = gv.getGlyphMetrics(i);
}
} while (--numReps >= 0);
}
public void runTest(Object ctx, int numReps) {
GVContext gvctx = (GVContext)ctx;
GlyphVector gv = gvctx.gv;
Shape s;
do {
for (int i = 0, e = gv.getNumGlyphs(); i < e; ++i) {
s = gv.getGlyphLogicalBounds(i);
}
} while (--numReps >= 0);
}
/**
* Returns the logical bounds of the specified array of characters
* in the specified <code>FontRenderContext</code>. The logical
* bounds contains the origin, ascent, advance, and height, which
* includes the leading. The logical bounds does not always enclose
* all the text. For example, in some languages and in some fonts,
* accent marks can be positioned above the ascent or below the
* descent. To obtain a visual bounding box, which encloses all the
* text, use the {@link TextLayout#getBounds() getBounds} method of
* <code>TextLayout</code>.
* <p>Note: The returned bounds is in baseline-relative coordinates
* (see {@link java.awt.Font class notes}).
* @param chars an array of characters
* @param beginIndex the initial offset in the array of
* characters
* @param limit the end offset in the array of characters
* @param frc the specified <code>FontRenderContext</code>
* @return a <code>Rectangle2D</code> that is the bounding box of the
* specified array of characters in the specified
* <code>FontRenderContext</code>.
* @throws IndexOutOfBoundsException if <code>beginIndex</code> is
* less than zero, or <code>limit</code> is greater than the
* length of <code>chars</code>, or <code>beginIndex</code>
* is greater than <code>limit</code>.
* @see FontRenderContext
* @see Font#createGlyphVector
* @since 1.2
*/
public Rectangle2D getStringBounds(char [] chars,
int beginIndex, int limit,
FontRenderContext frc) {
if (beginIndex < 0) {
throw new IndexOutOfBoundsException("beginIndex: " + beginIndex);
}
if (limit > chars.length) {
throw new IndexOutOfBoundsException("limit: " + limit);
}
if (beginIndex > limit) {
throw new IndexOutOfBoundsException("range length: " +
(limit - beginIndex));
}
// this code should be in textlayout
// quick check for simple text, assume GV ok to use if simple
boolean simple = values == null ||
(values.getKerning() == 0 && values.getLigatures() == 0 &&
values.getBaselineTransform() == null);
if (simple) {
simple = ! FontUtilities.isComplexText(chars, beginIndex, limit);
}
if (simple) {
GlyphVector gv = new StandardGlyphVector(this, chars, beginIndex,
limit - beginIndex, frc);
return gv.getLogicalBounds();
} else {
// need char array constructor on textlayout
String str = new String(chars, beginIndex, limit - beginIndex);
TextLayout tl = new TextLayout(str, this, frc);
return new Rectangle2D.Float(0, -tl.getAscent(), tl.getAdvance(),
tl.getAscent() + tl.getDescent() +
tl.getLeading());
}
}
public void runTest(Object ctx, int numReps) {
GVContext gvctx = (GVContext)ctx;
GlyphVector gv = gvctx.gv;
GlyphMetrics gm;
do {
for (int i = 0, e = gv.getNumGlyphs(); i < e; ++i) {
gm = gv.getGlyphMetrics(i);
}
} while (--numReps >= 0);
}
public void runTest(Object ctx, int numReps) {
TCContext tcctx = (TCContext)ctx;
final Font font = tcctx.font;
final String text = tcctx.text;
final FontRenderContext frc = tcctx.frc;
GlyphVector gv;
do {
gv = font.createGlyphVector(frc, text);
} while (--numReps >= 0);
}
public void runTest(Object ctx, int numReps) {
GVContext gvctx = (GVContext)ctx;
Graphics2D g2d = gvctx.g2d;
GlyphVector gv = gvctx.gv;
do {
g2d.drawGlyphVector(gv, 40, 40);
} while (--numReps >= 0);
}
public void runTest(Object ctx, int numReps) {
GVContext gvctx = (GVContext)ctx;
GlyphVector gv = gvctx.gv;
Rectangle2D r;
do {
r = gv.getLogicalBounds();
} while (--numReps >= 0);
}
public void runTest(Object ctx, int numReps) {
GVContext gvctx = (GVContext)ctx;
GlyphVector gv = gvctx.gv;
Rectangle2D r;
do {
r = gv.getVisualBounds();
} while (--numReps >= 0);
}
public void runTest(Object ctx, int numReps) {
GVContext gvctx = (GVContext)ctx;
GlyphVector gv = gvctx.gv;
GlyphMetrics gm;
do {
for (int i = 0, e = gv.getNumGlyphs(); i < e; ++i) {
gm = gv.getGlyphMetrics(i);
}
} while (--numReps >= 0);
}
/**
* @see org.newdawn.slick.Font#getHeight(java.lang.String)
*/
public int getHeight (String text) {
if (text == null) throw new IllegalArgumentException("text cannot be null.");
if (text.length() == 0) return 0;
if (displayListCaching) {
DisplayList displayList = (DisplayList)displayLists.get(text);
if (displayList != null) return displayList.height;
}
char[] chars = text.toCharArray();
GlyphVector vector = font.layoutGlyphVector(GlyphPage.renderContext, chars, 0, chars.length, Font.LAYOUT_LEFT_TO_RIGHT);
int lines = 0, height = 0;
for (int i = 0, n = vector.getNumGlyphs(); i < n; i++) {
int charIndex = vector.getGlyphCharIndex(i);
int codePoint = text.codePointAt(charIndex);
if (codePoint == ' ') continue;
Rectangle bounds = getGlyphBounds(vector, i, codePoint);
height = Math.max(height, ascent + bounds.y + bounds.height);
if (codePoint == '\n') {
lines++;
height = 0;
}
}
return lines * getLineHeight() + height;
}
/**
* Returns the logical bounds of the specified array of characters
* in the specified <code>FontRenderContext</code>. The logical
* bounds contains the origin, ascent, advance, and height, which
* includes the leading. The logical bounds does not always enclose
* all the text. For example, in some languages and in some fonts,
* accent marks can be positioned above the ascent or below the
* descent. To obtain a visual bounding box, which encloses all the
* text, use the {@link TextLayout#getBounds() getBounds} method of
* <code>TextLayout</code>.
* <p>Note: The returned bounds is in baseline-relative coordinates
* (see {@link java.awt.Font class notes}).
* @param chars an array of characters
* @param beginIndex the initial offset in the array of
* characters
* @param limit the end offset in the array of characters
* @param frc the specified <code>FontRenderContext</code>
* @return a <code>Rectangle2D</code> that is the bounding box of the
* specified array of characters in the specified
* <code>FontRenderContext</code>.
* @throws IndexOutOfBoundsException if <code>beginIndex</code> is
* less than zero, or <code>limit</code> is greater than the
* length of <code>chars</code>, or <code>beginIndex</code>
* is greater than <code>limit</code>.
* @see FontRenderContext
* @see Font#createGlyphVector
* @since 1.2
*/
public Rectangle2D getStringBounds(char [] chars,
int beginIndex, int limit,
FontRenderContext frc) {
if (beginIndex < 0) {
throw new IndexOutOfBoundsException("beginIndex: " + beginIndex);
}
if (limit > chars.length) {
throw new IndexOutOfBoundsException("limit: " + limit);
}
if (beginIndex > limit) {
throw new IndexOutOfBoundsException("range length: " +
(limit - beginIndex));
}
// this code should be in textlayout
// quick check for simple text, assume GV ok to use if simple
boolean simple = values == null ||
(values.getKerning() == 0 && values.getLigatures() == 0 &&
values.getBaselineTransform() == null);
if (simple) {
simple = ! FontUtilities.isComplexText(chars, beginIndex, limit);
}
if (simple) {
GlyphVector gv = new StandardGlyphVector(this, chars, beginIndex,
limit - beginIndex, frc);
return gv.getLogicalBounds();
} else {
// need char array constructor on textlayout
String str = new String(chars, beginIndex, limit - beginIndex);
TextLayout tl = new TextLayout(str, this, frc);
return new Rectangle2D.Float(0, -tl.getAscent(), tl.getAdvance(),
tl.getAscent() + tl.getDescent() +
tl.getLeading());
}
}
public void runTest(Object ctx, int numReps) {
GVContext gvctx = (GVContext)ctx;
GlyphVector gv = gvctx.gv;
GlyphMetrics gm;
do {
for (int i = 0, e = gv.getNumGlyphs(); i < e; ++i) {
gm = gv.getGlyphMetrics(i);
}
} while (--numReps >= 0);
}
public void runTest(Object ctx, int numReps) {
TCContext tcctx = (TCContext)ctx;
final Font font = tcctx.font;
final CharacterIterator ci = tcctx.ci;
final FontRenderContext frc = tcctx.frc;
GlyphVector gv;
do {
gv = font.createGlyphVector(frc, ci);
} while (--numReps >= 0);
}
public void runTest(Object ctx, int numReps) {
TCContext tcctx = (TCContext)ctx;
final Font font = tcctx.font;
final int[] glyphs = tcctx.glyphs;
final FontRenderContext frc = tcctx.frc;
GlyphVector gv;
do {
gv = font.createGlyphVector(frc, glyphs);
} while (--numReps >= 0);
}
public void runTest(Object ctx, int numReps) {
GVContext gvctx = (GVContext)ctx;
GlyphVector gv = gvctx.gv;
Rectangle2D r;
do {
r = gv.getVisualBounds();
} while (--numReps >= 0);
}
public void runTest(Object ctx, int numReps) {
GVContext gvctx = (GVContext)ctx;
Graphics2D g2d = gvctx.g2d;
GlyphVector gv = gvctx.gv;
do {
g2d.drawGlyphVector(gv, 40, 40);
} while (--numReps >= 0);
}
public void runTest(Object ctx, int numReps) {
TCContext tcctx = (TCContext)ctx;
final Font font = tcctx.font;
final char[] chars = tcctx.chars;
final FontRenderContext frc = tcctx.frc;
GlyphVector gv;
do {
gv = font.createGlyphVector(frc, chars);
} while (--numReps >= 0);
}