/** GPL >= 2.0 * Based upon RSS Reader MIDlet * Copyright (C) 2004 Gösta Jonasson <gosta(at)brothas.net> * Copyright (C) 2006-2008 eIrOcA (eNrIcO Croce & sImOnA Burzio) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * 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 for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This was first modified no earlier than May 27, 2008. * */ // Expand to define MIDP define //#define DMIDP20 // Expand to define test define //#define DNOTEST // Expand to define logging define //#define DNOLOGGING //#ifdef DMIDP20 package net.eiroca.j2me.RSSReader.presentation; import java.util.Vector; import javax.microedition.lcdui.Font; import cz.cacek.ebook.AbstractView; import com.substanceofcode.utils.EncodingUtil; //#ifdef DLOGGING import net.sf.jlogmicro.util.logging.Logger; import net.sf.jlogmicro.util.logging.LogManager; import net.sf.jlogmicro.util.logging.Level; //#endif public class RenderedWord { public static int fontSize = -1; public static int heightFont; public static Font[] font; public static int[] fontWidth; public int offset; public int row; public int style; public int color; public String word; private static boolean debug = false; //#ifdef DLOGGING private Logger logger = Logger.getLogger("RenderedWord"); private boolean fineLoggable = logger.isLoggable(Level.FINE); private boolean finerLoggable = logger.isLoggable(Level.FINER); private boolean finestLoggable = logger.isLoggable(Level.FINEST); //#endif /** Createt array of fonts with style index 'i'. */ static { RenderedWord.font = new Font[7]; RenderedWord.fontWidth = new int[7]; RenderedWord.updFontData(Font.SIZE_MEDIUM); } public static void updFontData(int fontSize) { if (RenderedWord.fontSize == fontSize) { return; } RenderedWord.fontSize = fontSize; for (int i = 0; i < 7; i++) { Font f = Font.getFont(Font.FACE_PROPORTIONAL, i, fontSize); RenderedWord.font[i] = f; RenderedWord.fontWidth[i] = f.stringWidth(" "); } RenderedWord.heightFont = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_PLAIN, fontSize).getHeight() + AbstractView.getLineSpace(); } /** * Create a RenderedWord which is used to display HTML minmally formatted * and font. A 'word' may be several words concatenated with blanks that * are to be displayed with the same atributes. * * Constructor * @param offset * @param row * @param style * @param color * @param word * @author Irv Bunton */ public RenderedWord(final int offset, final int row, final int style, final int color, final String word) { this.offset = offset; this.style = style; this.word = word; this.color = color; this.row = row; } /** * Create list of words with color, style, x, y, height and word text * * @param text * @param width * @param height * @param colTxt * @param colTit * @return Vector * @author Irv Bunton */ public static final Vector createWordList(final String text, final int width, final int height, final int colTxt, final int colTit) { //#ifdef DLOGGING Logger logger = Logger.getLogger( "RenderedWord"); boolean finestLoggable = logger.isLoggable(Level.FINEST); if (finestLoggable){logger.finest("text=" + text);} //#endif final Vector wordList = new Vector(); RenderedWord oldWord; final String tmpText = text.replace('\n', ' '); char[] ctmpText = tmpText.toCharArray(); int apos = tmpText.indexOf('&'); boolean ampPres; if (apos >= 0) { int spos = tmpText.indexOf(';'); ampPres = (apos < spos); } else { ampPres = false; } int color = colTxt; int index = 0; final int lung = tmpText.length(); int row = 0; int offset = 0; int style = 0; boolean fine = false; String tag = ""; oldWord = null; while (!fine) { int spaceIndex; int tagIndex; int endTagIndex; String word = ""; if (ctmpText[index] == ' ') { index++; if (index == lung) { fine = true; } word = " "; } else { if (ctmpText[index] == '<') { endTagIndex = tmpText.indexOf(">", index); if (endTagIndex < 0) { fine = true; } else { tag = tmpText.substring(index + 1, endTagIndex).toLowerCase( ).trim(); int pos = tag.indexOf(" "); if (pos >= 0) { tag = tag.substring(0, pos); } int tagLen = tag.length(); //#ifdef DTEST if (debug) { //#ifdef DLOGGING if (finestLoggable){logger.finest("tag,tagLen=" + tag + "," + tagLen);} //#endif } //#endif if (tagLen >= 1) { switch(tag.charAt(0)) { case 'b': if (tagLen == 1) { style |= Font.STYLE_BOLD; } else if ((tag.equals("br")) || (tag.equals("br/"))) { row += RenderedWord.heightFont; offset = 0; } break; case 'c': if ((tagLen == 4) && tag.equals("cite")) { style |= Font.STYLE_ITALIC; } break; case 'e': if (tag.equals("em")) { style |= Font.STYLE_ITALIC; } break; case 'h': if (tagLen >= 2) { char schar = tag.charAt(1); if ((schar == 'r') && ((tagLen == 2) || tag.equals("hr/"))) { row += RenderedWord.heightFont; offset = 0; } else if ((tagLen == 2) && ('1' <= schar) && (schar <= '6')) { style |= Font.STYLE_BOLD; /* If not at the beginning of the line, need to start a new line so that the header is alone. */ if (offset != 0) { row += RenderedWord.heightFont; offset = 0; } } } break; case 'i': if (tagLen == 1) { style |= Font.STYLE_ITALIC; } else if ((tagLen == 3) && tag.equals("ins")) { style |= Font.STYLE_UNDERLINED; } break; case 'l': if ((tagLen == 2) && tag.equals("li")) { row += RenderedWord.heightFont; offset = 0; } break; case 'p': if (tagLen == 1) { row += RenderedWord.heightFont; offset = 0; } break; case 's': if (tag.equals("strong")) { style |= Font.STYLE_BOLD; } break; case 't': if (tag.equals("tit")) { color = colTit; style |= Font.STYLE_BOLD; } break; case 'u': if (tagLen == 1) { style |= Font.STYLE_UNDERLINED; } else if ((tagLen == 2) && (tag.charAt(1) == 'l')) { if (offset != 0) { row += RenderedWord.heightFont; offset = 0; } } break; case 'v': if ((tagLen == 3) && tag.equals("var")) { style |= Font.STYLE_ITALIC; } break; case '/': if (tagLen >= 2) { switch(tag.charAt(1)) { case 'b': if (tagLen == 2) { style &= ~Font.STYLE_BOLD; } break; case 'c': if ((tagLen == 5) && tag.equals("/cite")) { style &= ~Font.STYLE_ITALIC; } break; case 'e': if (tag.equals("/em")) { style &= ~Font.STYLE_ITALIC; } break; case 'h': if ((tagLen == 3) && ('1' <= tag.charAt(2)) && (tag.charAt(2) <= '6')) { style &= ~Font.STYLE_BOLD; row += RenderedWord.heightFont; offset = 0; } break; case 'i': if (tagLen == 2) { style &= ~Font.STYLE_ITALIC; } else if ((tagLen == 3) && tag.equals("ins")) { style &= ~Font.STYLE_UNDERLINED; } break; case 'p': if (tagLen == 2) { row += RenderedWord.heightFont; offset = 0; } break; case 's': if (tag.equals("/strong")) { style &= ~Font.STYLE_BOLD; } break; case 't': if (tag.equals("/tit")) { color = colTxt; style &= ~Font.STYLE_BOLD; row += 14 * RenderedWord.heightFont / 10; offset = 0; } break; case 'u': if (tagLen == 2) { style &= ~Font.STYLE_UNDERLINED; } break; case 'v': if ((tagLen == 4) && tag.equals("/var")) { style &= ~Font.STYLE_ITALIC; } break; default: break; } } break; default: break; } } if ((style < 0) || (style > 7)) { style = 0; } index = endTagIndex + 1; if ((index == lung) || (index == -1)) { fine = true; } } } else { spaceIndex = tmpText.indexOf(" ", index); tagIndex = tmpText.indexOf("<", index); if ((spaceIndex == -1) && (tagIndex == -1)) { word = tmpText.substring(index); fine = true; } else { if ((spaceIndex == -1) && (tagIndex != -1)) { word = tmpText.substring(index, tagIndex); index = tagIndex; } else { if ((spaceIndex != -1) && (tagIndex == -1)) { word = tmpText.substring(index, spaceIndex); index = spaceIndex; } else { if (spaceIndex < tagIndex) { word = tmpText.substring(index, spaceIndex); index = spaceIndex; } else { word = tmpText.substring(index, tagIndex); index = tagIndex; } } } } if ((word != null) && (word.length() != 0)) { if (ampPres) { word = EncodingUtil.replaceAlphaEntities(true, word); } final int l = RenderedWord.font[style].stringWidth(word); int pos = offset; if ((offset + l) < width) { offset = offset + l + RenderedWord.fontWidth[style]; } else { if (offset != 0) { row += RenderedWord.heightFont; } pos = 0; offset = l + RenderedWord.fontWidth[style]; } if (oldWord == null) { oldWord = new RenderedWord(pos, row, style, color, word); } else { if ((oldWord.row == row) && (oldWord.style == style) && (oldWord.color == color)) { oldWord.word += " " + word; } else { wordList.addElement(oldWord); oldWord = new RenderedWord(pos, row, style, color, word); } } } } } } if (oldWord != null) { wordList.addElement(oldWord); } return wordList; } } //#endif