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 + -
显示快捷键?