text.java
来自「This is a resource based on j2me embedde」· Java 代码 · 共 1,274 行 · 第 1/3 页
JAVA
1,274 行
/** * Calculates 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. * * @param text text to process. this must not be null * @param font font to use for width information * @param inout an array of in/out parameters, the GNL_ constants * define the meaning of each element; * this array implements a structure that keeps data * between invocations of getNextLine. * @return true if the text had to be truncated, false otherwise */ private static boolean getNextLine(char[] text, Font font, int[] inout) { // // 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; int prevLineWidth = 0; int curLineWidth = 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; inout[GNL_LINE_WIDTH] = prevLineWidth; return ( ((inout[GNL_OPTIONS] & TRUNCATE) == TRUNCATE) && ((inout[GNL_NUM_LINES] + 1) * inout[GNL_FONT_HEIGHT] > inout[GNL_HEIGHT]) ); // we allow \r\n as an alternative delimiter, but not \r alone } else if ( text[curLoc] == '\r' && curLoc+1 < text.length && text[curLoc+1] == '\n') { inout[GNL_LINE_END] = curLoc; inout[GNL_NEW_LINE_START] = curLoc + 2; inout[GNL_LINE_WIDTH] = prevLineWidth; return ( ((inout[GNL_OPTIONS] & TRUNCATE) == TRUNCATE) && ((inout[GNL_NUM_LINES] + 1) * inout[GNL_FONT_HEIGHT] > inout[GNL_HEIGHT]) ); } else if (text[curLoc] == ' ') { inout[GNL_LINE_END] = curLoc; inout[GNL_NEW_LINE_START] = curLoc + 1; inout[GNL_LINE_WIDTH] = prevLineWidth; 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. // curLineWidth = prevLineWidth + font.charWidth(text[curLoc]); // check up the mode is "truncate" and we reached the end of // the last line that we can put into the specifed rectangle area // (inout[GNL_WIDTH] x inout[GNL_HEIGHT]) if (((inout[GNL_OPTIONS] & TRUNCATE) == TRUNCATE) && ((inout[GNL_NUM_LINES] + 1) * inout[GNL_FONT_HEIGHT] > inout[GNL_HEIGHT]) && (inout[GNL_OFFSET] + curLineWidth + 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] + curLineWidth + leftWidth > inout[GNL_WIDTH]) { prevLineWidth += inout[GNL_ELLIP_WIDTH]; inout[GNL_LINE_END] = curLoc; inout[GNL_NEW_LINE_START] = curLoc; inout[GNL_LINE_WIDTH] = prevLineWidth; return true; } else { curLineWidth += leftWidth; inout[GNL_LINE_END] = text.length; inout[GNL_NEW_LINE_START] = text.length; inout[GNL_LINE_WIDTH] = curLineWidth; return false; } // reached the end of the line } else if (inout[GNL_OFFSET] + curLineWidth > 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]; inout[GNL_LINE_WIDTH] = 0; } else { // the line is too long and we need to break it inout[GNL_LINE_END] = curLoc; inout[GNL_NEW_LINE_START] = curLoc; inout[GNL_LINE_WIDTH] = prevLineWidth; } } return false; } // go to next character curLoc++; prevLineWidth = curLineWidth; } // while end // we reach this code only if we reach the end of the text inout[GNL_LINE_END] = text.length; inout[GNL_NEW_LINE_START] = text.length; inout[GNL_LINE_WIDTH] = curLineWidth; return false; } /** * Utility method to calculate the width and height in which 2 * strings can fit given the strings, fonts and maximum width * in which those strings should fit. Returned width is either * the passed in width or a smaller one. * 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. * * The width in which both strings would fit given the maximum * is returned in size[WIDTH]. The height in which both strings * would fit is returned in size[HEIGHT]; * * @param size The array that returns contents size * @param firstStr the first string to use. * @param secondStr the first string to use. * @param width the available width for the text * @param firstFont the font to render the first string in * @param secondFont the font to render the second string in * @param pad the horizontal padding that should be used between strings */ public static void getTwoStringsSize(int[] size, String firstStr, String secondStr, Font firstFont, Font secondFont, int width, int pad) { if (((firstStr == null || firstStr.length() == 0) && (secondStr == null || secondStr.length() == 0)) || (width <= 0)) { size[WIDTH] = size[HEIGHT] = 0; return; } 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 = initGNL(firstFont, width, 0, Text.NORMAL, 0); do { numLines++; height += fontHeight; 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]; } 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; } size[HEIGHT] = height; size[WIDTH] = widest; return; } } // 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 being 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 = initGNL(secondFont, width, 0, Text.NORMAL, offset); do { numLines++; height += fontHeight; 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()); // last \n should be ignored if (secondStr.charAt(secondStr.length() - 1) == '\n') { height -= fontHeight; } } size[WIDTH] = widest; size[HEIGHT] = height; return; } // IMPL_NOTE: remove these - there must be a common place to get them /** Used as an index into the size[], for the x. */ public final static int X = 0; /** Used as an index into the size[], for the y. */ public final static int Y = 1; /** Used as an index into the size[], for the width. */ public final static int WIDTH = 2; /** Used as an index into the size[], for the height. */ public final static int HEIGHT = 3; /** * * * @param g the Graphics to paint with * @param text the string to be painted * @param font the font to be used * @param fgColor foreground text color * @param shdColor shadow color * @param shdAlign shadow alignment * @param titlew width */ public static void drawTruncStringShadowed(Graphics g, String text, Font font, int fgColor, int shdColor, int shdAlign, int titlew) { int dx=1, dy=1; // draw the shadow if (shdColor != fgColor) { switch (shdAlign) { case (Graphics.TOP | Graphics.LEFT): dx=-1; dy=-1; break; case (Graphics.TOP | Graphics.RIGHT): dx=1; dy=-1; break; case (Graphics.BOTTOM | Graphics.LEFT): dx=-1; dy=1; break; case (Graphics.BOTTOM | Graphics.RIGHT): default: dx=1; dy=1; break; } g.translate(dx, dy); drawTruncString(g, text, font, shdColor, titlew);/* if we wanted multi-line text output, we would use this: paint(g, text, font, shdColor, 0, titlew, titleh, 0, TRUNCATE, null);*/ g.translate(-dx, -dy); } // now draw the text whose shadow we have drawn above drawTruncString(g, text, font, fgColor, titlew);/* if we wanted multi-line text output, we would use this: paint(g, text, font, fgColor, 0, titlew, titleh, 0, TRUNCATE, null);*/ } /** * Given a string, determine the length of a substring that can be drawn * within the current clipping area. * If the whole string fits into the clip area, * return the length of the string. * Else, return the length of a substring (starting from the beginning * of the original string) that can be drawn within the current clipping * area before the truncation indicator. * The truncation indicator, typically, ellipsis, is not included into * the returned length. * * @param g the Graphics to paint with * @param str the string to be painted * @param width the available width, including room * for the truncation indicator * @return either the length of str (if it fits into the clip area), * or the length of the substring that can fit into the clip area * (not including the truncation mark) */ public static int canDrawStringPart(Graphics g, String str, int width) { if (width < 0) { return 0; } final Font font = g.getFont(); final int stringWidth = font.stringWidth(str); if (width >= stringWidth) { return str.length(); } final int widthForTruncatedText = width - font.charWidth(truncationMark); int availableLength; for (availableLength = str.length() - 1 ; font.substringWidth(str,0,availableLength) > widthForTruncatedText; availableLength-- ) {}; return availableLength; } /** * Draw the string within the specified width. * If the string does not fit in the available width, * it is truncated at the end, * and a truncation indicator is displayed (usually, * an ellipsis, but this can be changed). * Use Graphics.translate(x,y) to specify the anchor point location * (the alignment will be TOP|LEFT relative to 0,0). * * @param g the Graphics to paint with * @param str the string to be painted * @param font the font to be used * @param fgColor the color to paint with * @param width the width available for painting */ public static void drawTruncString(Graphics g, String str, Font font, int fgColor, int width) { int offset = 0; if (ScreenSkin.RL_DIRECTION) { offset = width - offset; } g.setFont(font); g.setColor(fgColor); int lengthThatCanBeShown = canDrawStringPart(g, str, width); if (lengthThatCanBeShown == str.length()) { g.drawString(str, offset, 0, Graphics.TOP | ScreenSkin.TEXT_ORIENT); } else { String s = str.substring(0,lengthThatCanBeShown) + truncationMark; g.drawString(s, offset, 0, Graphics.TOP | ScreenSkin.TEXT_ORIENT); } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?