text.java

来自「This is a resource based on j2me embedde」· Java 代码 · 共 1,274 行 · 第 1/3 页

JAVA
1,274
字号
/* *    * * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved.  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER  *   * This program is free software; you can redistribute it and/or  * modify it under the terms of the GNU General Public License version  * 2 only, as published by the Free Software Foundation.  *   * This program is distributed in the hope that it will be useful, but  * WITHOUT ANY WARRANTY; without even the implied warranty of  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  * General Public License version 2 for more details (a copy is  * included at /legal/license.txt).  *   * You should have received a copy of the GNU General Public License  * version 2 along with this work; if not, write to the Free Software  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  * 02110-1301 USA  *   * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa  * Clara, CA 95054 or visit www.sun.com if you need additional  * information or have any questions. */package com.sun.midp.lcdui;import javax.microedition.lcdui.Font;import javax.microedition.lcdui.Graphics;import com.sun.midp.chameleon.skins.StringItemSkin;import com.sun.midp.chameleon.skins.ScreenSkin;import com.sun.midp.chameleon.skins.TextFieldSkin;import com.sun.midp.i18n.Resource;import com.sun.midp.i18n.ResourceConstants;/** * Static method class use to draw and size text. */public class Text {    /** Character to be used as a truncation indiactor,     *  for example, \u2026 which is ellipsis (...). */    private static final char truncationMark = Resource.getString(ResourceConstants.TRUNCATION_MARK).charAt(0);//'\u2026';     // the following are used in calling the getNextLine method    /** Line start. */    private static final int GNL_LINE_START = 0;    /** Line end. */    private static final int GNL_LINE_END = 1;    /** New line start. */    private static final int GNL_NEW_LINE_START = 2;    /** Screen width available. */    private static final int GNL_WIDTH = 3;    /** Screen height available. */    private static final int GNL_HEIGHT = 4;    /** Font height. */    private static final int GNL_FONT_HEIGHT = 5;    /** Line number. */    private static final int GNL_NUM_LINES = 6;    /** Text options (NORMAL, INVERT...) see below. */    private static final int GNL_OPTIONS = 7;    /** Text pixel offset. */    private static final int GNL_OFFSET = 8;    /** Width of the ellipsis in the current font. */    private static final int GNL_ELLIP_WIDTH = 9;    /** Line width in pixels. */    private static final int GNL_LINE_WIDTH = 10;        /** Number of GNL_ parameter constants. */    private static final int GNL_NUM_PARAMS = 11;        // constants to affect how text drawing is handled    // These values can be OR'd together. no error checking is performed    /** NORMAL text. */    public static final int NORMAL    = 0x0;    /** INVERTED text color. */    public static final int INVERT    = 0x1;    /** Draw a hyperlink for the text. */    public static final int HYPERLINK = 0x2;    /** Truncate the text and put a "..." if the text doesn't fit the bounds. */    public static final int TRUNCATE  = 0x4;    // these values are stored used as setting in a TextCursor object    /**      * When a paint occurs use the cursor index to know when to     * paint the cursor.     */    public static final int PAINT_USE_CURSOR_INDEX = 0;    /**      * When 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_GET_CURSOR_INDEX = 1;    /**     * Don't draw a cursor.     */    public static final int PAINT_HIDE_CURSOR = 2;    /**     * Sets up a new inout structure used in various      * text methods.     * @param font the font to use     * @param w the available width for the text     * @param h the available height for the text     * @param options any of NORMAL | INVERT | HYPERLINK | TRUNCATE     * @param offset the first line pixel offset     * @return initialized GNL_struct      */    public static int[] initGNL(Font font, int w, int h, 				int options, int offset) {		int[] inout = new int[GNL_NUM_PARAMS];	        inout[GNL_FONT_HEIGHT] = font.getHeight();        inout[GNL_WIDTH] = w;        inout[GNL_HEIGHT] = h;        inout[GNL_OPTIONS] = options;        inout[GNL_OFFSET] = offset;        inout[GNL_ELLIP_WIDTH] = font.charWidth(truncationMark);        inout[GNL_LINE_START] = 0;        inout[GNL_LINE_END] = 0;        inout[GNL_NEW_LINE_START] = 0;	inout[GNL_LINE_WIDTH] = 0;	inout[GNL_NUM_LINES] = 0;		return inout;    }        /**     * Paints the text in a single line, scrolling left or right as      * necessary to keep the cursor visible within the available     * width for the text.  The offset of the text after the      * paintLine call, whether modified or not, is returned.     * <p>     * If the cursor is null, signifying an uneditable TextField is     * being painted, the text will not be scrolled left or right, and     * the returned value will always equal the <code>offset</code>     * argument passed in to this method.     *     * @param g the Graphics object to paint in     * @param str the String to paint     * @param font the font to use     * @param fgColor foreground color     * @param w the available width for the text     * @param h the available height for the text     * @param cursor TextCursor object to use for cursor placement     * @param offset the pixel offset of the text (possibly negative)     * @return the current scroll offset     */    public static int paintLine(Graphics g, String str, Font font, int fgColor, 				int w, int h, TextCursor cursor, int offset) {        if (w <= 0 ||            (cursor == null && (str == null || str.length() == 0))) {            return 0;        }	        if (str == null) {            str = "";        }	        g.setFont(font);        g.setColor(fgColor);	        char[] text = str.toCharArray();        int fontHeight = font.getHeight();	        if (cursor != null && cursor.visible == false) {            cursor = null;        }	        // side-scroll distance in pixels, with default        int scrollPix = w / 2;	//	// draw a vertical cursor indicator if required	//	if (cursor != null &&	    cursor.option == PAINT_USE_CURSOR_INDEX && 	    cursor.index >= 0 && cursor.index <= str.length()) {	    int pos = offset;	    if (cursor.index > 0) {            pos += font.charsWidth(text, 0, cursor.index);        }	    // IMPL_NOTE: optimize this with math instead of iteration        cursor.x = pos;        if (ScreenSkin.RL_DIRECTION) {            cursor.x = w - pos;            if (cursor.x <= 0) {            while (cursor.x <= 0) {                offset -= scrollPix;                cursor.x += scrollPix;            }            } else {            while ((cursor.x > w / 2) && (offset < 0)) {                offset += scrollPix;                cursor.x -= scrollPix;            }            }        } else {            if (cursor.x >= w) {            while (cursor.x >= w) {                offset -= scrollPix;                cursor.x -= scrollPix;            }            } else {            while ((cursor.x < w / 2) && (offset < 0)) {                offset += scrollPix;                cursor.x += scrollPix;            }            }        }        cursor.y      = fontHeight;	    cursor.width  = 1;	    cursor.height = fontHeight;	    	    cursor.paint(g);	    cursor = null;	}    g.drawChars(text, 0, text.length,  (ScreenSkin.RL_DIRECTION) ? w - offset : offset, h,		    Graphics.BOTTOM | ScreenSkin.TEXT_ORIENT);    return offset;    }    /**     * Creates a current TextInfo struct, linewraping text     * when necessary.  TextInfo struct is updated when     * <code>str</code> changes, or when scrolling happens.     * This method does not do any painting, but updates     * <code>info</code> to be current for use by the     * paint routine, <code>paintText</code>...     *     * @param str the text to use     * @param font the font to use for sizing     * @param w the available width for the text     * @param h the available height for the text     * @param offset the pixel offset of the text (possibly negative)     * @param options only TRUNCATE matters here     * @param cursor text cursor object for cursor position     * @param info TextInfo structure to fill     * @return true if successful, false if there was an error     */    // IMPL_NOTE: break into 3 simpler update methods: text, Y scroll, X scroll    public static boolean updateTextInfo(String str, Font font, 					 int w, int h, int offset, int options,					 TextCursor cursor, TextInfo info) {    if (w <= 0 ||	    (cursor == null && (str == null || str.length() == 0))) {	    return false;	}		if (str == null) {	    str = "";	}		char[] text = str.toCharArray();		int fontHeight = font.getHeight();		if (cursor != null && cursor.visible == false) {	    cursor = null;	}	    int oldNumLines = info.numLines;	if (info.isModified) {	    	    int[] inout = initGNL(font, w, h, options, offset);	    	    int numLines = 0;	    int height   = 0;	    	    do {		numLines++;		height += fontHeight;		info.numLines = numLines;		if (height < h) {		    info.visLines = info.numLines;		}				inout[GNL_NUM_LINES] = numLines;				getNextLine(text, font, inout);				int lineStart    = inout[GNL_LINE_START];		int lineEnd      = inout[GNL_LINE_END];		int newLineStart = inout[GNL_NEW_LINE_START];				// IMPL_NOTE: add accessor fn to TextInfo and hide this		//		// check that we don't exceed info's capacity		// before we cache line data and expand if needed		//		if (numLines > info.lineStart.length) {		    info.expand();		}		info.lineStart[numLines - 1] = lineStart;		info.lineEnd[numLines - 1] = lineEnd;				inout[GNL_LINE_START] = newLineStart;		inout[GNL_OFFSET] = 0;		offset = 0;	    } while (inout[GNL_LINE_END] < text.length);	    	    info.height = height;	}	if (info.scrollY) {            // if (lineEnd > lineStart) {	    	    // 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 curLine = (cursor.y / fontHeight) - 1;        int curX;        int bestIndex = info.lineStart[curLine];            if (ScreenSkin.RL_DIRECTION) {                curX = curLine == 0 ? w - offset - cursor.width : w;            } else {                curX = curLine == 0 ? offset : 0;            }        int curY = cursor.y;		int bestX = curX;        // take one character at a time and check its position		// against the supplied coordinates in cursor		//        int lineStart = info.lineStart[curLine];        int lineEnd = info.lineEnd[curLine];        for (int i = lineStart; i < lineEnd; i++) {            char ch = text[i];            if (Math.abs(curX - cursor.preferredX) <                 Math.abs(bestX - cursor.preferredX)) {                 bestIndex = i;                   bestX = curX;            }            if (ScreenSkin.RL_DIRECTION) {                curX -= font.charWidth(ch);            } else {                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;		info.cursorLine = curLine;	    }	}	if (info.scrollX || info.isModified) {	    if (cursor != null &&		cursor.option == PAINT_USE_CURSOR_INDEX) {		if (cursor.index >= info.lineStart[info.cursorLine] &&		    cursor.index <= info.lineEnd[info.cursorLine]) {		    // no change to info.cursorLine		} else {		    // IMPL_NOTE: start at cursorLine and search before/after		    //      as this search is non-optimal		    for (int i = 0; i < info.numLines; i++) {			// we are given an index...what line is it on? 			if (cursor.index >= info.lineStart[i] &&			    cursor.index <= info.lineEnd[i]) {			    info.cursorLine = i;			    break;			}		    }		}	    }	}	// check scroll position and move if needed	if (info.isModified ||info.scrollX || info.scrollY) {	    if (info.numLines > info.visLines) {            if (cursor != null) {                if (info.cursorLine > info.topVis + info.visLines - 1) {                    int diff = info.cursorLine -                         (info.topVis + info.visLines - 1);                    info.topVis += diff;                } else if (info.cursorLine < info.topVis) {                    int diff = info.topVis - info.cursorLine;                    info.topVis -= diff;                }            } else if (oldNumLines != 0) {                info.topVis = (info.topVis * info.numLines) / oldNumLines;            }                            if (info.topVis + info.visLines > info.numLines) {                info.topVis = info.numLines - info.visLines;            }	    } else {            info.topVis = 0;        }        if (cursor != null) {            cursor.yOffset = info.topVis * fontHeight;        }	}	info.scrollX = info.scrollY = info.isModified = false;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?