--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/javauis/lcdui_qt/src/javax/microedition/lcdui/Font.java Mon May 03 12:27:20 2010 +0300
@@ -0,0 +1,672 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package javax.microedition.lcdui;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import org.eclipse.ercp.swt.mobile.MobileShell;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.internal.qt.graphics.FontUtils;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Implementation of LCDUI <code>Font</code> class.
+ */
+public final class Font {
+
+ /**
+ * System font face.
+ *
+ * @value for FACE_SYSTEM is 0.
+ */
+ public static final int FACE_SYSTEM = 0;
+
+ /**
+ * Monospace font face.
+ *
+ * @value for FACE_MONOSPACE is 32.
+ */
+ public static final int FACE_MONOSPACE = 32;
+
+ /**
+ * Proportional font face.
+ *
+ * @value for FACE_PROPORTIONAL is 64.
+ */
+ public static final int FACE_PROPORTIONAL = 64;
+
+ /**
+ * Plain font style.
+ *
+ * @value for STYLE_PLAIN is 0.
+ */
+ public static final int STYLE_PLAIN = 0;
+
+ /**
+ * Bold font style.
+ *
+ * @value for STYLE_BOLD is 1.
+ */
+ public static final int STYLE_BOLD = 1;
+
+ /**
+ * Italic font style.
+ *
+ * @value for STYLE_ITALIC is 2.
+ */
+ public static final int STYLE_ITALIC = 2;
+
+ /**
+ * Underlined font style.
+ *
+ * @value for STYLE_UNDERLINED is 4.
+ */
+ public static final int STYLE_UNDERLINED = 4;
+
+ /**
+ * Small font size.
+ *
+ * @value for SIZE_SMALL is 8.
+ */
+ public static final int SIZE_SMALL = 8;
+
+ /**
+ * Medium font size.
+ *
+ * @value for SIZE_MEDIUM is 0.
+ */
+ public static final int SIZE_MEDIUM = 0;
+
+ /**
+ * Large font size.
+ *
+ * @value for SIZE_LARGE is 16.
+ */
+ public static final int SIZE_LARGE = 16;
+
+ /**
+ * Font specifier for default input text drawing.
+ *
+ * @value for FONT_INPUT_TEXT is 1.
+ */
+ public static final int FONT_INPUT_TEXT = 1;
+
+ /**
+ * Font specifier for default Item and Screen drawing.
+ *
+ * @value for FONT_STATIC_TEXT is 0.
+ */
+ public static final int FONT_STATIC_TEXT = 0;
+
+ private static final int STYLE_ALL = STYLE_PLAIN | STYLE_BOLD
+ | STYLE_ITALIC | STYLE_UNDERLINED;
+
+ private static final String FONTDATA_CONST = "|-1|-1|-1|-1|-1|-1|1|";
+
+ /**
+ * Lookup table which stores LCDUI fonts based on FontData keys.
+ */
+ private static Hashtable fontTable = new Hashtable();
+ private static FontUtils fontUtils;
+ private static int[] tempFontRect = new int[4];
+ private static FontData eswtTempFontData;
+ private static FontData eswtSystemFontData;
+ private int eswtTempFontAscent;
+ private int eswtTempFontHeight;
+ private int eswtTempFontWidth;
+
+ // Instance members.
+
+ private org.eclipse.swt.graphics.Font eswtFont;
+ private int face;
+ private int style;
+ private int size;
+
+ /**
+ * Disposes all fonts created.
+ */
+ static void disposeFonts() {
+ for (Enumeration e = fontTable.elements(); e.hasMoreElements();) {
+ Font font = (Font) e.nextElement();
+ font.eswtFont.dispose();
+ }
+ fontTable.clear();
+ }
+
+ /**
+ * LCDUI Font --> eSWT Font
+ */
+ static org.eclipse.swt.graphics.Font getESWTFont(Font font) {
+ if (font != null) {
+ return font.eswtFont;
+ }
+ return null;
+ }
+
+ /**
+ * eSWT Font --> LCDUI Font
+ */
+ static Font getFont(final org.eclipse.swt.graphics.Font font) {
+ if (font != null) {
+ FontData fd = getFontData(font);
+ return getFont(fd);
+ }
+ return null;
+ }
+
+ /**
+ * Returns default font.
+ *
+ * @return default system font.
+ */
+ public static Font getDefaultFont() {
+ return getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_MEDIUM);
+ }
+
+ /**
+ * Request specified Font.
+ *
+ * @param specifier font specifier
+ * @return the font
+ */
+ public static Font getFont(int specifier) {
+ if (specifier == FONT_INPUT_TEXT || specifier == FONT_STATIC_TEXT) {
+ return getFont(getFontData(specifier));
+ }
+ else {
+ throw new IllegalArgumentException(
+ MsgRepository.FONT_EXCEPTION_INVALID_SPECIFIER);
+ }
+ }
+
+ /**
+ * Request Font based on parameters.
+ *
+ * @param face font face
+ * @param style font style
+ * @param size font size
+ * @return the font
+ */
+ public static Font getFont(int face, int style, int size) {
+ if (face != FACE_SYSTEM && face != FACE_MONOSPACE
+ && face != FACE_PROPORTIONAL) {
+ throw new IllegalArgumentException(
+ MsgRepository.FONT_EXCEPTION_INVALID_FACE);
+ }
+ if (style < STYLE_PLAIN || style > STYLE_ALL) {
+ throw new IllegalArgumentException(
+ MsgRepository.FONT_EXCEPTION_INVALID_STYLE);
+ }
+ if (size != SIZE_SMALL && size != SIZE_MEDIUM && size != SIZE_LARGE) {
+ throw new IllegalArgumentException(
+ MsgRepository.FONT_EXCEPTION_INVALID_SIZE);
+ }
+ FontData fd = getFontData(face, style, size);
+ Font font = getFont(fd);
+ // We must handle underlining separately because it is not part of
+ // eSWT's style.
+ if ((style & Font.STYLE_UNDERLINED) == Font.STYLE_UNDERLINED) {
+ font.style |= Font.STYLE_UNDERLINED;
+ }
+ return font;
+ }
+
+ /**
+ * Request freesized Font.
+ *
+ * @param face font face
+ * @param style font style
+ * @param height font height
+ * @return the font
+ */
+ static Font getFreeSizedFont(int face, int style, int height) {
+ if (face != FACE_SYSTEM && face != FACE_MONOSPACE
+ && face != FACE_PROPORTIONAL) {
+ throw new IllegalArgumentException(
+ MsgRepository.FONT_EXCEPTION_INVALID_FACE);
+ }
+ if (style < STYLE_PLAIN || style > STYLE_ALL) {
+ throw new IllegalArgumentException(
+ MsgRepository.FONT_EXCEPTION_INVALID_STYLE);
+ }
+ if (height < 0) {
+ throw new IllegalArgumentException(
+ MsgRepository.FONT_EXCEPTION_INVALID_SIZE);
+ }
+ FontData fd = getFontData(face, style, height);
+ Font font = getFont(fd);
+ // We must handle underlining separately because it is not part of
+ // eSWT's style.
+ if ((style & Font.STYLE_UNDERLINED) == Font.STYLE_UNDERLINED) {
+ font.style |= Font.STYLE_UNDERLINED;
+ }
+ return font;
+ }
+
+ /**
+ * Lookup or create a font based on given FontData.
+ *
+ * @param fontdata font's data
+ * @return a font
+ */
+ private static Font getFont(FontData fontdata) {
+ Font ret = null;
+ if (fontdata != null) {
+ if (fontTable.containsKey(fontdata)) {
+ ret = (Font) fontTable.get(fontdata);
+ }
+ else {
+ ret = new Font(fontdata);
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * Constructor (private).<br>
+ *
+ * @param reqFD the requested eSWT FontData
+ */
+ private Font(final FontData reqFD) {
+ ESWTUIThreadRunner.syncExec(new Runnable() {
+ public void run() {
+ eswtFont = new org.eclipse.swt.graphics.Font(ESWTUIThreadRunner
+ .getInstance().getDisplay(), reqFD);
+ }
+ });
+ // get FontData info from resulted Font, because resulting FontData
+ // might be different than the requested one
+ FontData resFD = getFontData(eswtFont);
+ this.face = mapFontNameToFace(resFD.getName());
+ this.style = mapESWTStyleToStyle(resFD.getStyle());
+ this.size = mapHeightToSize(resFD.getHeight());
+ fontTable.put(resFD, this);
+ }
+
+ /**
+ * Return font's style.
+ *
+ * @return style
+ */
+ public int getStyle() {
+ return style;
+ }
+
+ /**
+ * Return font's size.
+ *
+ * @return size
+ */
+ public int getSize() {
+ return size;
+ }
+
+ /**
+ * Return font's face.
+ *
+ * @return face
+ */
+ public int getFace() {
+ return face;
+ }
+
+ /**
+ * Checks if the font is plain styled.
+ *
+ * @return true if the font is plain, false otherwise
+ */
+ public boolean isPlain() {
+ return (style == Font.STYLE_PLAIN);
+ }
+
+ /**
+ * Checks if the font is bold styled.
+ *
+ * @return true if the font is bold, false otherwise
+ */
+ public boolean isBold() {
+ return ((style & Font.STYLE_BOLD) == Font.STYLE_BOLD);
+ }
+
+ /**
+ * Checks if the font is italic styled.
+ *
+ * @return true if the font is italic, false otherwise
+ */
+ public boolean isItalic() {
+ return ((style & Font.STYLE_ITALIC) == Font.STYLE_ITALIC);
+ }
+
+ /**
+ * Checks if the font is underlined styled.
+ *
+ * @return true if the font is underlined, false otherwise.
+ */
+ public boolean isUnderlined() {
+ return ((style & Font.STYLE_UNDERLINED) == Font.STYLE_UNDERLINED);
+ }
+
+ /**
+ * Return font's height.
+ *
+ * @return height
+ */
+ public int getHeight() {
+ if (eswtTempFontHeight == 0) {
+ ESWTUIThreadRunner.safeSyncExec(new Runnable() {
+ public void run() {
+ FontUtils fu = eswtGetFontUtils(eswtFont);
+ eswtTempFontHeight = fu.getAscent() + fu.getDescent();
+ }
+ });
+ }
+ return eswtTempFontHeight;
+ }
+
+ /**
+ * The position of the baseline from the top of the font in pixels.
+ *
+ * @return the baseline position
+ */
+ public int getBaselinePosition() {
+ if (eswtTempFontAscent == 0) {
+ ESWTUIThreadRunner.safeSyncExec(new Runnable() {
+ public void run() {
+ eswtTempFontAscent = eswtGetFontUtils(eswtFont).getAscent();
+ }
+ });
+ }
+ return eswtTempFontAscent;
+ }
+
+ /**
+ * Returns the width of the given character in pixels.
+ *
+ * @param c the character
+ * @return the width
+ */
+ public int charWidth(char c) {
+ return stringWidth(String.valueOf(c));
+ }
+
+ /**
+ * Returns the width of the given character array's region in pixels.
+ *
+ * @param c characters
+ * @param offset starting position
+ * @param length the length
+ * @return the width
+ */
+ public int charsWidth(char[] c, int offset, int length) {
+ return stringWidth(new String(c, offset, length));
+ }
+
+ /**
+ * Returns string width in pixels.
+ *
+ * @param string the string
+ * @return the width
+ */
+ public int stringWidth(String string) {
+ if (string == null) {
+ throw new NullPointerException(
+ MsgRepository.FONT_EXCEPTION_NULL_STRING);
+ }
+ final String finalString = string;
+ eswtTempFontWidth = 0;
+ ESWTUIThreadRunner.safeSyncExec(new Runnable() {
+ public void run() {
+ eswtGetFontUtils(eswtFont).getBoundingRect(tempFontRect, finalString);
+ eswtTempFontWidth = tempFontRect[2];
+ }
+ });
+ return eswtTempFontWidth;
+ }
+
+ /**
+ * Get the static FontUtils instance setup with given font.
+ */
+ private static FontUtils eswtGetFontUtils(org.eclipse.swt.graphics.Font font) {
+ if (fontUtils == null) {
+ fontUtils = new FontUtils(font.handle);
+ }
+ else {
+ fontUtils.setFont(font.handle);
+ }
+ return fontUtils;
+ }
+
+ /**
+ * Returns sub-string width in pixels.
+ *
+ * @param string the string
+ * @param offset starting position
+ * @param length the length
+ * @return the width of the specified region
+ */
+ public int substringWidth(String string, int offset, int length) {
+ return stringWidth(string.substring(offset, offset + length));
+ }
+
+ /**
+ * Get FontData of a eSWT control.
+ *
+ * @param control eSWT control
+ * @return FontData
+ */
+ private static FontData getFontData(final int specifier) {
+ ESWTUIThreadRunner.syncExec(new Runnable() {
+ public void run() {
+ Control control = null;
+ MobileShell shell = new MobileShell(ESWTUIThreadRunner
+ .getInstance().getDisplay(), SWT.NONE);
+ if (specifier == FONT_INPUT_TEXT) {
+ control = new Text(shell, SWT.NONE);
+ }
+ else {
+ control = new Label(shell, SWT.NONE);
+ }
+ eswtTempFontData = control.getFont().getFontData()[0];
+ control.dispose();
+ shell.dispose();
+ }
+ });
+ return eswtTempFontData;
+ }
+
+ /**
+ * Get FontData of a eSWT font.
+ *
+ * @param font eSWT font
+ * @return FontData
+ */
+ private static FontData getFontData(
+ final org.eclipse.swt.graphics.Font font) {
+ ESWTUIThreadRunner.syncExec(new Runnable() {
+ public void run() {
+ eswtTempFontData = font.getFontData()[0];
+ }
+ });
+ return eswtTempFontData;
+ }
+
+ /**
+ * Construct FontData with the given specifiers.
+ *
+ * @return FontData
+ */
+ private static FontData getFontData(final int face, final int style,
+ final int size) {
+ ESWTUIThreadRunner.syncExec(new Runnable() {
+ public void run() {
+ int underlined = 0;
+ if ((style & Font.STYLE_UNDERLINED) == Font.STYLE_UNDERLINED) {
+ underlined = 1;
+ }
+ /* FontData constructor format:
+ * version|name|height|style|underline|
+ * overline|strike|stretch|pitch|qt-style|weight|strategy|
+ */
+ StringBuffer sb = new StringBuffer();
+ sb.append("1|"); // version
+ sb.append(mapFaceToFontName(face)); // family name
+ sb.append("|");
+ sb.append(mapSizeToHeight(size)); // height
+ sb.append("|");
+ sb.append(mapStyleToESWTStyle(style)); // style
+ sb.append("|QT|1|");//Qt version 2 string for extra formats
+ sb.append((new Integer(underlined).toString())); // underline
+ sb.append(FONTDATA_CONST);
+ eswtTempFontData = new FontData(sb.toString());
+ }
+ });
+ return eswtTempFontData;
+ }
+
+ /**
+ * Returns System default font's FontData instance.
+ *
+ * @return system FontData
+ */
+ private static FontData getSystemFontData() {
+ if (eswtSystemFontData == null) {
+ ESWTUIThreadRunner.syncExec(new Runnable() {
+ public void run() {
+ eswtSystemFontData = ESWTUIThreadRunner.getInstance()
+ .getDisplay().getSystemFont().getFontData()[0];
+ }
+ });
+ }
+ return eswtSystemFontData;
+ }
+
+ /**
+ * Get eSWT font name from LCDUI face parameter.
+ *
+ * @param face font's face type
+ * @return font name
+ */
+ private static String mapFaceToFontName(int face) {
+ // TODO: how to map face values to names
+ switch (face) {
+ case Font.FACE_MONOSPACE:
+ case Font.FACE_PROPORTIONAL:
+ case Font.FACE_SYSTEM:
+ default:
+ return getSystemFontData().getName();
+ }
+ }
+
+ /**
+ * Get face of a given eSWT font name.
+ *
+ * @param eswtFontName font's name
+ * @return font face
+ */
+ private static int mapFontNameToFace(String eswtFontName) {
+ // TODO: how to map names to face values
+ if (eswtFontName.equals(getSystemFontData().getName())) {
+ return Font.FACE_SYSTEM;
+ }
+ else {
+ // Font.FACE_MONOSPACE:
+ // Font.FACE_PROPORTIONAL:
+ return 0;
+ }
+ }
+
+ /**
+ * Get eSWT font height from LCDUI size parameter.<br>
+ * 0 maps to system's default font size, others map directly.
+ *
+ * @param size font's size
+ * @return font height
+ */
+ private static int mapSizeToHeight(int size) {
+ //retreive the system default height
+ int defHeight = getSystemFontData().getHeight();
+
+ if (size == Font.SIZE_SMALL) {
+ //calculate the small size height as a ratio of system default medium size and round off the value to an integer
+ return (int)Math.floor( (defHeight * ( 3f/4 )) + 0.5f );
+ }
+ else if (size == Font.SIZE_LARGE) {
+ //calculate the large height as a ratio of system default medium size and round off the value to an integer
+ return (int)Math.floor( (defHeight * ( 4.5f/4 )) + 0.5f );
+ }
+ else {
+ //return the system default height for medium size which is generally 12 but 7 in symbian for qt
+ return defHeight;
+ }
+ }
+
+ /**
+ * Get LCDUI size from eSWT font height
+ *
+ * @param height font's height
+ * @return font size
+ */
+ private static int mapHeightToSize(int height) {
+ int defHeight = getSystemFontData().getHeight();
+ if (height < defHeight) {
+ return Font.SIZE_SMALL;
+ }
+ else if (height > defHeight) {
+ return Font.SIZE_LARGE;
+ }
+ else {
+ return Font.SIZE_MEDIUM;
+ }
+ }
+
+ /**
+ * Return eSWT style.
+ *
+ * @param style Font's LCDUI style.
+ * @return Font's eSWT style.
+ */
+ private static int mapStyleToESWTStyle(int style) {
+ int retStyle = SWT.NORMAL;
+ if ((style & Font.STYLE_BOLD) == Font.STYLE_BOLD) {
+ retStyle |= SWT.BOLD;
+ }
+ if ((style & Font.STYLE_ITALIC) == Font.STYLE_ITALIC) {
+ retStyle |= SWT.ITALIC;
+ }
+ return retStyle;
+ }
+
+ /**
+ * Return LCDUI style.
+ *
+ * @param eswtStyle Font's eSWT style.
+ * @return Font's LCDUI style.
+ */
+ private static int mapESWTStyleToStyle(int eswtStyle) {
+ int retStyle = Font.STYLE_PLAIN;
+ if ((eswtStyle & SWT.BOLD) != 0) {
+ retStyle |= Font.STYLE_BOLD;
+ }
+ if ((eswtStyle & SWT.ITALIC) != 0) {
+ retStyle |= Font.STYLE_ITALIC;
+ }
+ return retStyle;
+ }
+
+}