Textpublic class Text extends Object Static method class use to draw and size text |
Fields Summary |
---|
private static final char[] | ellipsisString to represent an ellipsis (...) | private static final int | GNL_LINE_STARTline start | private static final int | GNL_LINE_ENDline end | private static final int | GNL_NEW_LINE_STARTnew line start | private static final int | GNL_WIDTHscreen width available | private static final int | GNL_HEIGHTscreen height available | private static final int | GNL_FONT_HEIGHTfont height | private static final int | GNL_NUM_LINESline number | private static final int | GNL_OPTIONStext options (NORMAL, INVERT...) see below. | private static final int | GNL_OFFSETtext pixel offset | private static final int | GNL_ELLIP_WIDTHwidth of the ellipsis in the current font | private static final int | GNL_LINE_WIDTHline width in pixels | private static final int | GNL_NUM_PARAMSnumber of GNL_ parameter constants | public static int | FG_COLORThe default foreground color | public static int | FG_H_COLORThe default foreground hilight color | public static javax.microedition.lcdui.Image | HYPERLINK_IMGThe image to draw for hyperlinks | public static final int | NORMALNORMAL text | public static final int | INVERTINVERTED text color | public static final int | HYPERLINKDraw a hyperlink for the text | public static final int | TRUNCATEtruncate the text and put a "..." if the text doesn't fit the bounds | public static final int | PAINT_USE_CURSOR_INDEXwhen a paint occurs use the cursor index to know when to
paint the cursor | public static final int | PAINT_GET_CURSOR_INDEXwhen a paint occurs try to find the best value for the cursor
index based on the x,y coordinates of the cursor | public static final int | PAINT_HIDE_CURSORdon't draw a cursor |
Methods Summary |
---|
public static void | drawHyperLink(javax.microedition.lcdui.Graphics g, int x, int y, int w)Draw a hyperlink image
int linkHeight = HYPERLINK_IMG.getHeight();
int linkWidth = HYPERLINK_IMG.getWidth();
int oldClipX = g.getClipX();
int oldClipW = g.getClipWidth();
int oldClipY = g.getClipY();
int oldClipH = g.getClipHeight();
g.clipRect(x, oldClipY, w, oldClipH);
// Then, loop from the end of the string to the beginning,
// drawing the image as we go
for (int j = x + w - linkWidth, first = x - linkWidth;
j > first; j -= linkWidth) {
g.drawImage(HYPERLINK_IMG, j, y,
Graphics.BOTTOM | Graphics.LEFT);
}
g.setClip(oldClipX, oldClipY, oldClipW, oldClipH);
| public static int | getHeightForWidth(java.lang.String str, javax.microedition.lcdui.Font font, int w, int offset)Get the height in pixels to render the given string
// Case 0: null or empty string, no height
if (str == null || str.length() == 0 || w <= 0) {
return 0;
}
// Case 1: text requires line wrapping
return (font.getHeight() *
linesOfText(str.toCharArray(), offset, w, font));
| private static boolean | getNextLine(char[] text, javax.microedition.lcdui.Font font, int[] inout)Calculate the starting and ending points for a new line of
text given the font and input parameters. Beware of the
multiple returns statements within the body.
//
// this inner loop will set lineEnd and newLineStart to
// the proper values so that a line is broken correctly
//
int curLoc = inout[GNL_LINE_START];
boolean foundBreak = false;
int leftWidth = 0;
inout[GNL_LINE_WIDTH] = 0;
while (curLoc < text.length) {
//
// a newLine forces a break and immediately terminates
// the loop
//
// a space will be remembered as a possible place to break
//
if (text[curLoc] == '\n") {
inout[GNL_LINE_END] = curLoc;
inout[GNL_NEW_LINE_START] = curLoc + 1;
break;
} else if (text[curLoc] == ' ") {
inout[GNL_LINE_END] = curLoc;
inout[GNL_NEW_LINE_START] = curLoc + 1;
foundBreak = true;
}
//
// if the text is longer than one line then we
// cut the word at a word boundary if possible,
// otherwise the word is broken.
//
inout[GNL_LINE_WIDTH] += font.charWidth(text[curLoc]);
if (((inout[GNL_OPTIONS] & TRUNCATE) == TRUNCATE)
&& ((inout[GNL_NUM_LINES] + 1) * inout[GNL_FONT_HEIGHT]
> inout[GNL_HEIGHT])
&& (inout[GNL_LINE_WIDTH] + inout[GNL_OFFSET] +
inout[GNL_ELLIP_WIDTH] > inout[GNL_WIDTH])) {
leftWidth = font.charsWidth(text, curLoc + 1,
text.length - curLoc - 1);
//
// we are on the last line and at the point where
// we will need to put an ellipsis if we can't fit
// the rest of the line
//
// if the rest of the line will fit, then don't
// put an ellipsis
//
if (inout[GNL_OFFSET] + inout[GNL_LINE_WIDTH] + leftWidth
> inout[GNL_WIDTH]) {
inout[GNL_LINE_WIDTH] += inout[GNL_ELLIP_WIDTH];
/*
if (!foundBreak) {
inout[GNL_LINE_END] = curLoc;
inout[GNL_NEW_LINE_START] = curLoc;
}
*/
inout[GNL_LINE_END] = curLoc;
inout[GNL_NEW_LINE_START] = curLoc;
return true;
} else {
inout[GNL_LINE_WIDTH] += leftWidth;
inout[GNL_LINE_END] = text.length;
inout[GNL_NEW_LINE_START] = text.length;
return false;
}
} else if (inout[GNL_OFFSET] + inout[GNL_LINE_WIDTH]
> inout[GNL_WIDTH]) {
if (!foundBreak) {
if (inout[GNL_OFFSET] > 0) {
// move to the next line which will have 0 offset
inout[GNL_LINE_END] = inout[GNL_LINE_START];
inout[GNL_NEW_LINE_START] = inout[GNL_LINE_START];
} else {
// the line is too long and we need to break it
inout[GNL_LINE_END] = curLoc;
inout[GNL_NEW_LINE_START] = curLoc;
}
}
return false;
}
curLoc++;
}
inout[GNL_LINE_END] = curLoc;
return false;
| public static int | getTwoStringsHeight(java.lang.String firstStr, java.lang.String secondStr, javax.microedition.lcdui.Font firstFont, javax.microedition.lcdui.Font secondFont, int width, int pad)Utility method to calculate the heightin which two strings can fit
given the strings, fonts and available width.
The offset in pixels for the first string is 0, second string is
laid out right after the first one with padding in between
equal to the passed in value.
if (((firstStr == null || firstStr.length() == 0) &&
(secondStr == null || secondStr.length() == 0)) ||
(width <= 0)) {
return 0;
}
int[] inout = new int[GNL_NUM_PARAMS];
char[] text;
int offset = 0;
int widest = 0;
int numLines = 0;
int height = 0;
int fontHeight = 0;
if (firstStr != null && firstStr.length() > 0) {
text = firstStr.toCharArray();
fontHeight = firstFont.getHeight();
inout[GNL_FONT_HEIGHT] = fontHeight;
inout[GNL_WIDTH] = width;
inout[GNL_OPTIONS] = Text.NORMAL;
inout[GNL_ELLIP_WIDTH] = firstFont.charsWidth(ellipsis, 0, 3);
inout[GNL_LINE_START] = 0;
inout[GNL_LINE_END] = 0;
inout[GNL_NEW_LINE_START] = 0;
inout[GNL_OFFSET] = 0;
inout[GNL_LINE_WIDTH] = 0;
do {
numLines++;
height += fontHeight;
inout[GNL_NUM_LINES] = numLines;
getNextLine(text, firstFont, inout);
inout[GNL_LINE_START] = inout[GNL_NEW_LINE_START];
} while (inout[GNL_LINE_END] < firstStr.length());
offset = inout[GNL_LINE_WIDTH];
if (secondStr == null || secondStr.length() == 0) {
// last \n in the two strings should be ignored
if (firstStr.charAt(firstStr.length() - 1) == '\n") {
height -= fontHeight;
}
return height;
}
}
// Second string is not null and it is not empty
if (secondStr != null && secondStr.length() > 0) {
if (offset > 0) {
offset += pad;
}
text = secondStr.toCharArray();
fontHeight = secondFont.getHeight();
// Line that has the end of the first string and the beginning
// of the second one is a special one;
// We have to make sure that it is not counted twice and that
// the right font height is beeing added (the max of the two)
if (numLines > 0) {
numLines--;
if (inout[GNL_FONT_HEIGHT] > fontHeight) {
height -= fontHeight;
} else {
height -= inout[GNL_FONT_HEIGHT];
}
}
inout[GNL_FONT_HEIGHT] = fontHeight;
inout[GNL_WIDTH] = width;
inout[GNL_OPTIONS] = Text.NORMAL;
inout[GNL_ELLIP_WIDTH] = secondFont.charsWidth(ellipsis, 0, 3);
inout[GNL_LINE_START] = 0;
inout[GNL_LINE_END] = 0;
inout[GNL_NEW_LINE_START] = 0;
inout[GNL_OFFSET] = offset;
inout[GNL_LINE_WIDTH] = 0;
do {
numLines++;
height += fontHeight;
inout[GNL_NUM_LINES] = numLines;
getNextLine(text, secondFont, inout);
inout[GNL_LINE_START] = inout[GNL_NEW_LINE_START];
inout[GNL_OFFSET] = 0;
} while (inout[GNL_LINE_END] < secondStr.length());
// last \n should be ignored
if (secondStr.charAt(secondStr.length() - 1) == '\n") {
height -= fontHeight;
}
}
return height;
| public static int | getTwoStringsWidth(java.lang.String firstStr, java.lang.String secondStr, javax.microedition.lcdui.Font firstFont, javax.microedition.lcdui.Font secondFont, int width, int pad)Utility method to calculate the width in which 2 strings can fit
given the strings, fonts and maximum width in which those strings
should fit. Returned value is either the passed in width or
a smaller.
The offset in pixels for the first string is 0, second string is
laid out right after the first one with padding in between
equal to the passed in value.
if (((firstStr == null || firstStr.length() == 0) &&
(secondStr == null || secondStr.length() == 0)) ||
(width <= 0)) {
return 0;
}
int[] inout = new int[GNL_NUM_PARAMS];
char[] text;
int offset = 0;
int widest = 0;
int numLines = 0;
if (firstStr != null && firstStr.length() > 0) {
text = firstStr.toCharArray();
inout[GNL_FONT_HEIGHT] = firstFont.getHeight();
inout[GNL_WIDTH] = width;
inout[GNL_OPTIONS] = Text.NORMAL;
inout[GNL_ELLIP_WIDTH] = firstFont.charsWidth(ellipsis, 0, 3);
inout[GNL_LINE_START] = 0;
inout[GNL_LINE_END] = 0;
inout[GNL_NEW_LINE_START] = 0;
inout[GNL_OFFSET] = offset;
inout[GNL_LINE_WIDTH] = 0;
do {
numLines++;
inout[GNL_NUM_LINES] = numLines;
getNextLine(text, firstFont, inout);
if (inout[GNL_LINE_WIDTH] > widest) {
widest = inout[GNL_LINE_WIDTH];
}
inout[GNL_LINE_START] = inout[GNL_NEW_LINE_START];
inout[GNL_OFFSET] = 0;
} while (inout[GNL_LINE_END] < firstStr.length());
offset = inout[GNL_LINE_WIDTH];
}
if (secondStr != null && secondStr.length() > 0) {
if (offset > 0) {
offset += pad;
}
text = secondStr.toCharArray();
if (numLines > 0) {
numLines--;
}
inout[GNL_FONT_HEIGHT] = secondFont.getHeight();
inout[GNL_WIDTH] = width;
inout[GNL_OPTIONS] = Text.NORMAL;
inout[GNL_ELLIP_WIDTH] = secondFont.charsWidth(ellipsis, 0, 3);
inout[GNL_LINE_START] = 0;
inout[GNL_LINE_END] = 0;
inout[GNL_NEW_LINE_START] = 0;
inout[GNL_OFFSET] = offset;
inout[GNL_LINE_WIDTH] = 0;
do {
numLines++;
inout[GNL_NUM_LINES] = numLines;
getNextLine(text, secondFont, inout);
if (inout[GNL_OFFSET] + inout[GNL_LINE_WIDTH] > widest) {
widest = inout[GNL_OFFSET] + inout[GNL_LINE_WIDTH];
}
inout[GNL_LINE_START] = inout[GNL_NEW_LINE_START];
inout[GNL_OFFSET] = 0;
} while (inout[GNL_LINE_END] < secondStr.length());
}
return widest;
| public static int | getWidestLineWidth(char[] text, int offset, int width, javax.microedition.lcdui.Font font)Utility method to retrieve the length of the longest line of the
text given the width. this may not necessarily be the entire
string if there are line breaks or word wraps.
int numLines = 0;
if (text == null || text.length == 0) {
return 0;
}
int[] inout = new int[GNL_NUM_PARAMS];
inout[GNL_FONT_HEIGHT] = font.getHeight();
inout[GNL_WIDTH] = width;
inout[GNL_OPTIONS] = Text.NORMAL;
inout[GNL_ELLIP_WIDTH] = font.charsWidth(ellipsis, 0, 3);
inout[GNL_LINE_START] = 0;
inout[GNL_LINE_END] = 0;
inout[GNL_NEW_LINE_START] = 0;
inout[GNL_OFFSET] = offset;
inout[GNL_LINE_WIDTH] = 0;
int widest = 0;
do {
numLines++;
inout[GNL_NUM_LINES] = numLines;
getNextLine(text, font, inout);
if (inout[GNL_LINE_WIDTH] > width && offset == 0) {
return width;
}
if (inout[GNL_LINE_WIDTH] > widest) {
widest = inout[GNL_LINE_WIDTH];
}
inout[GNL_LINE_START] = inout[GNL_NEW_LINE_START];
inout[GNL_OFFSET] = 0;
} while (inout[GNL_LINE_END] < text.length);
return widest;
| public static int | linesOfText(char[] text, int offset, int width, javax.microedition.lcdui.Font font)Utility method to return the number of lines it would take
to render the given text with the given first-line offset,
available width, and Font
int numLines = 0;
if (text == null || text.length == 0) {
return numLines;
}
int[] inout = new int[GNL_NUM_PARAMS];
inout[GNL_FONT_HEIGHT] = font.getHeight();
inout[GNL_WIDTH] = width;
inout[GNL_OPTIONS] = Text.NORMAL;
inout[GNL_ELLIP_WIDTH] = font.charsWidth(ellipsis, 0, 3);
inout[GNL_LINE_START] = 0;
inout[GNL_LINE_END] = 0;
inout[GNL_NEW_LINE_START] = 0;
inout[GNL_OFFSET] = offset;
inout[GNL_LINE_WIDTH] = 0;
do {
numLines++;
inout[GNL_NUM_LINES] = numLines;
getNextLine(text, font, inout);
inout[GNL_LINE_START] = inout[GNL_NEW_LINE_START];
inout[GNL_OFFSET] = 0;
} while (inout[GNL_LINE_END] < text.length);
return numLines;
| public static int | paint(java.lang.String str, javax.microedition.lcdui.Font font, javax.microedition.lcdui.Graphics g, int w, int h, int offset, int options, TextCursor cursor)Paint the text, linewrapping when necessary
if (w <= 0 ||
(cursor == null && (str == null || str.length() == 0))) {
return 0;
}
if (str == null) {
str = "";
}
Font oldFont = g.getFont();
if (oldFont != font) {
g.setFont(font);
}
char[] text = str.toCharArray();
int fontHeight = font.getHeight();
if (cursor != null && cursor.visible == false) {
cursor = null;
}
int[] inout = new int[GNL_NUM_PARAMS];
inout[GNL_FONT_HEIGHT] = fontHeight;
inout[GNL_WIDTH] = w;
inout[GNL_HEIGHT] = h;
inout[GNL_OPTIONS] = options;
inout[GNL_ELLIP_WIDTH] = font.charsWidth(ellipsis, 0, 3);
inout[GNL_LINE_START] = 0;
inout[GNL_LINE_END] = 0;
inout[GNL_NEW_LINE_START] = 0;
inout[GNL_OFFSET] = offset;
int numLines = 0;
int height = 0;
do {
numLines++;
height += fontHeight;
if (height > h) {
break;
}
inout[GNL_NUM_LINES] = numLines;
boolean truncate = getNextLine(text, font, inout);
int lineStart = inout[GNL_LINE_START];
int lineEnd = inout[GNL_LINE_END];
int newLineStart = inout[GNL_NEW_LINE_START];
//
// now we can get around to actually draw the text
// lineStart is the array index of the first character to
// start drawing, while lineEnd is the index just after
// the last character to draw.
//
if (lineEnd > lineStart) {
if ((options & INVERT) == INVERT) {
g.fillRect(offset, height - fontHeight,
inout[GNL_LINE_WIDTH], fontHeight);
g.setColor(FG_H_COLOR);
}
if ((options & HYPERLINK) == HYPERLINK) {
drawHyperLink(g, offset, height, inout[GNL_LINE_WIDTH]);
}
//
// we are given x,y coordinates and we must calculate
// the best array index to put the cursor
//
if (cursor != null &&
cursor.option == PAINT_GET_CURSOR_INDEX &&
cursor.x >= 0 &&
cursor.y == height) {
int bestIndex = lineStart;
int bestX = offset;
int curX = offset;
int curY = height;
//
// draw one character at a time and check its position
// against the supplied coordinates in cursor
//
for (int i = lineStart; i < lineEnd; i++) {
char ch = text[i];
g.drawChar(ch, curX, curY,
Graphics.BOTTOM | Graphics.LEFT);
if (Math.abs(curX - cursor.preferredX) <
Math.abs(bestX - cursor.preferredX)) {
bestIndex = i;
bestX = curX;
}
curX += font.charWidth(ch);
}
if (Math.abs(curX - cursor.preferredX) <
Math.abs(bestX - cursor.preferredX)) {
bestIndex = lineEnd;
bestX = curX;
}
cursor.index = bestIndex;
cursor.x = bestX;
cursor.y = height;
cursor.option = PAINT_USE_CURSOR_INDEX;
} else {
g.drawChars(text, lineStart, lineEnd - lineStart,
offset, height,
Graphics.BOTTOM | Graphics.LEFT);
}
//
// draw the ellipsis
//
if (truncate) {
int curX = inout[GNL_LINE_WIDTH];
g.drawChars(ellipsis, 0, 3,
curX + offset, height,
Graphics.BOTTOM | Graphics.LEFT);
}
}
//
// try to draw a vertical cursor indicator
//
if (cursor != null &&
cursor.option == PAINT_USE_CURSOR_INDEX &&
cursor.index >= lineStart && cursor.index <= lineEnd) {
int off = offset;
if (cursor.index > lineStart) {
off += font.charsWidth(text, lineStart,
cursor.index - lineStart);
}
cursor.x = off;
cursor.y = height;
cursor.width = 1;
cursor.height = fontHeight;
cursor.paint(g);
cursor = null;
}
if ((options & INVERT) == INVERT) {
g.setColor(FG_COLOR);
}
inout[GNL_LINE_START] = newLineStart;
inout[GNL_OFFSET] = 0;
offset = 0;
} while (inout[GNL_LINE_END] < text.length);
g.setFont(oldFont);
return inout[GNL_LINE_WIDTH];
|
|