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