Home | History | Annotate | Download | only in unicodefont
      1 /*******************************************************************************
      2  * Copyright 2011 See AUTHORS file.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *   http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  ******************************************************************************/
     16 
     17 package com.badlogic.gdx.tools.hiero.unicodefont;
     18 
     19 import java.awt.Font;
     20 import java.awt.Rectangle;
     21 import java.awt.Shape;
     22 import java.awt.font.GlyphMetrics;
     23 import java.awt.font.GlyphVector;
     24 
     25 import com.badlogic.gdx.graphics.Texture;
     26 import com.badlogic.gdx.graphics.g2d.BitmapFont;
     27 import com.badlogic.gdx.tools.hiero.unicodefont.UnicodeFont.RenderType;
     28 
     29 /** Represents the glyph in a font for a unicode codepoint.
     30  * @author Nathan Sweet */
     31 public class Glyph {
     32 	private int codePoint;
     33 	private short width, height;
     34 	private short yOffset;
     35 	private boolean isMissing;
     36 	private Shape shape;
     37 	float u, v, u2, v2;
     38 	private int xOffset, xAdvance;
     39 	Texture texture;
     40 
     41 	Glyph (int codePoint, Rectangle bounds, GlyphVector vector, int index, UnicodeFont unicodeFont) {
     42 		this.codePoint = codePoint;
     43 
     44 		int padTop = unicodeFont.getPaddingTop(), padBottom = unicodeFont.getPaddingBottom();
     45 		int padLeft = unicodeFont.getPaddingLeft(), padRight = unicodeFont.getPaddingRight();
     46 
     47 		if (unicodeFont.renderType == RenderType.FreeType && unicodeFont.bitmapFont != null) {
     48 			BitmapFont.Glyph g = unicodeFont.bitmapFont.getData().getGlyph((char)codePoint);
     49 			if (g == null)
     50 				isMissing = true;
     51 			else {
     52 				boolean empty = g.width == 0 || g.height == 0;
     53 				width = empty ? 0 : (short)(g.width + padLeft + padRight);
     54 				height = empty ? 0 : (short)(g.height + padTop + padBottom);
     55 				yOffset = (short)(g.yoffset - padTop);
     56 				xOffset = g.xoffset - unicodeFont.getPaddingLeft();
     57 				xAdvance = g.xadvance + unicodeFont.getPaddingAdvanceX() + unicodeFont.getPaddingLeft()
     58 					+ unicodeFont.getPaddingRight();
     59 				isMissing = codePoint == 0;
     60 			}
     61 
     62 		} else {
     63 			GlyphMetrics metrics = vector.getGlyphMetrics(index);
     64 			int lsb = (int)metrics.getLSB();
     65 			if (lsb > 0) lsb = 0;
     66 			int rsb = (int)metrics.getRSB();
     67 			if (rsb > 0) rsb = 0;
     68 
     69 			int glyphWidth = bounds.width - lsb - rsb;
     70 			int glyphHeight = bounds.height;
     71 			if (glyphWidth > 0 && glyphHeight > 0) {
     72 				width = (short)(glyphWidth + padLeft + padRight);
     73 				height = (short)(glyphHeight + padTop + padBottom);
     74 				yOffset = (short)(unicodeFont.getAscent() + bounds.y - padTop);
     75 			}
     76 
     77 			// xOffset and xAdvance will be incorrect for unicode characters such as combining marks or non-spacing characters
     78 			// (eg Pnujabi's "\u0A1C\u0A47") that require the context of surrounding glyphs to determine spacing, but this is the
     79 			// best we can do with the BMFont format.
     80 			char[] chars = Character.toChars(codePoint);
     81 			GlyphVector charVector = unicodeFont.getFont().layoutGlyphVector(GlyphPage.renderContext, chars, 0, chars.length,
     82 				Font.LAYOUT_LEFT_TO_RIGHT);
     83 			GlyphMetrics charMetrics = vector.getGlyphMetrics(0);
     84 			xOffset = vector.getGlyphPixelBounds(0, GlyphPage.renderContext, 0, 0).x - unicodeFont.getPaddingLeft();
     85 			xAdvance = (int)(metrics.getAdvanceX() + unicodeFont.getPaddingAdvanceX() + unicodeFont.getPaddingLeft()
     86 				+ unicodeFont.getPaddingRight());
     87 
     88 			shape = vector.getGlyphOutline(index, -bounds.x + unicodeFont.getPaddingLeft(), -bounds.y + unicodeFont.getPaddingTop());
     89 
     90 			isMissing = !unicodeFont.getFont().canDisplay((char)codePoint);
     91 		}
     92 	}
     93 
     94 	/** The unicode codepoint the glyph represents. */
     95 	public int getCodePoint () {
     96 		return codePoint;
     97 	}
     98 
     99 	/** Returns true if the font does not have a glyph for this codepoint. */
    100 	public boolean isMissing () {
    101 		return isMissing;
    102 	}
    103 
    104 	/** The width of the glyph's image. */
    105 	public int getWidth () {
    106 		return width;
    107 	}
    108 
    109 	/** The height of the glyph's image. */
    110 	public int getHeight () {
    111 		return height;
    112 	}
    113 
    114 	/** The shape to use to draw this glyph. This is set to null after the glyph is stored in a GlyphPage. */
    115 	public Shape getShape () {
    116 		return shape;
    117 	}
    118 
    119 	public void setShape (Shape shape) {
    120 		this.shape = shape;
    121 	}
    122 
    123 	public void setTexture (Texture texture, float u, float v, float u2, float v2) {
    124 		this.texture = texture;
    125 		this.u = u;
    126 		this.v = v;
    127 		this.u2 = u2;
    128 		this.v2 = v2;
    129 	}
    130 
    131 	public Texture getTexture () {
    132 		return texture;
    133 	}
    134 
    135 	public float getU () {
    136 		return u;
    137 	}
    138 
    139 	public float getV () {
    140 		return v;
    141 	}
    142 
    143 	public float getU2 () {
    144 		return u2;
    145 	}
    146 
    147 	public float getV2 () {
    148 		return v2;
    149 	}
    150 
    151 	/** The distance from drawing y location to top of this glyph, causing the glyph to sit on the baseline. */
    152 	public int getYOffset () {
    153 		return yOffset;
    154 	}
    155 
    156 	public int getXOffset () {
    157 		return xOffset;
    158 	}
    159 
    160 	public int getXAdvance () {
    161 		return xAdvance;
    162 	}
    163 }
    164