예제 #1
0
  /**
   * Process this text Token to optimize tokens and evaluate the token bounding box.
   *
   * @param g Graphics to get the font metrics.
   * @param text Text to add to the current textTokan.
   * @param textTok Current TextToken.
   * @param isText True if the previous textToken was a Text Token so we can merge it with this.
   */
  private void updateText(Graphics g, String text, TextToken textTok, boolean isText) {
    // The text exists!
    if (text.length() > 0) {
      FontMetrics fm = g.getFontMetrics();
      int a = fm.getAscent(), d = fm.getDescent(), w = fm.stringWidth(text), h = fm.getHeight();

      // The previous token was a text too so we must merge it with this new one.
      if (isText) {
        textTok = (TextToken) m_tokens.lastElement();

        textTok.m_text += text;
        textTok.m_bounds.width += w;
        if (textTok.m_bounds.height < h) textTok.m_bounds.height = h;
      }
      // The previous token was a formating one.
      else {
        m_tokens.addElement(textTok);

        textTok.m_text = text;
        textTok.m_bounds = new Rectangle(0, 0, w, h);
      }

      if (a > m_body.m_aMax) m_body.m_aMax = a;
      if (d > m_body.m_dMax) m_body.m_dMax = d;

      m_wCur += w;
    }
  }
예제 #2
0
  /**
   * Creates a new HTMLText and sets its default formatting properties.
   *
   * @param inCol Color of the bounding box background.
   * @param outCol Color of the bounding box border.
   * @param textCol Default text color.
   * @param fontSiz Default font size.
   * @param fontStl Default font style.
   * @param fontNam Default font name.
   * @param flags Default text alignment flags.
   * @param margin Default margins size.
   */
  public HTMLText(
      Color inCol,
      Color outCol,
      int textCol,
      int fontSiz,
      int fontStl,
      String fontNam,
      int blur,
      int rounded,
      int flags,
      Insets margin) {
    m_body = new FormatToken();
    m_body.m_flags = flags;
    m_body.m_margin = margin;

    m_inCol = inCol;
    m_outCol = outCol;
    m_color = textCol;
    m_bkCol = -1;
    m_style = fontStl;
    m_size = fontSiz;
    m_name = fontNam;
    m_blur = blur;
    m_rounded = rounded;
    m_wCur = 0;
    m_tokens = new Vector();
    m_heap = new Vector();
    m_heap.addElement("c=#" + Integer.toHexString(textCol));
    m_heap.addElement("s=" + fontSiz);
    m_heap.addElement("f=" + fontNam);

    if ((fontStl & Font.BOLD) != 0) m_heap.addElement("b");
    if ((fontStl & Font.ITALIC) != 0) m_heap.addElement("i");
  }
예제 #3
0
  /**
   * get next format token Note: Supported format specifieres i,d,u - decimal o - octal x,X -
   * hexa-decimal c - character e,E,f,F,g,G,a,A - float/double s - string S - string with quotes y -
   * boolean Supported options: #,0,-, ,+,* - flags 1-9 - width . - precision {<name>}s -
   * enumeration <name> <x>s, <x>S - quoting character <x> <space>s,<space>S - accept spaces, ignore
   * quotes *s - accept all to eol h,l,j,z,t - length modifier
   *
   * @param format format string
   * @param formatIndex index in format string
   * @param formatToken format token
   * @return next format string index
   */
  private static int getNextFormatToken(String format, int formatIndex, FormatToken formatToken) {
    formatToken.token = new StringBuffer();
    formatToken.length = 0;
    formatToken.alternateFlag = false;
    formatToken.zeroPaddingFlag = false;
    formatToken.leftAdjustedFlag = false;
    formatToken.blankFlag = false;
    formatToken.greedyFlag = false;
    formatToken.width = 0;
    formatToken.precision = 0;
    formatToken.lengthType = LengthTypes.INTEGER;
    formatToken.quoteChar = '\0';
    formatToken.enumClassName = null;
    formatToken.conversionChar = '\0';

    /* format start character */
    assert format.charAt(formatIndex) == '%';
    formatToken.token.append('%');
    formatIndex++;
    if (formatIndex >= format.length()) {
      return -1;
    }

    /* flags */
    while ((formatIndex < format.length())
        && ((format.charAt(formatIndex) == '#')
            || (format.charAt(formatIndex) == '0')
            || (format.charAt(formatIndex) == '-')
            || (format.charAt(formatIndex) == ' ')
            || (format.charAt(formatIndex) == '+')
            || (format.charAt(formatIndex) == '*'))) {
      formatToken.token.append(format.charAt(formatIndex));
      switch (format.charAt(formatIndex)) {
        case '#':
          formatToken.alternateFlag = true;
          break;
        case '0':
          formatToken.zeroPaddingFlag = true;
          break;
        case '-':
          formatToken.leftAdjustedFlag = true;
          break;
        case ' ':
          formatToken.blankFlag = true;
          break;
        case '+':
          formatToken.blankFlag = true;
          break;
        case '*':
          formatToken.greedyFlag = true;
          break;
        default:
          return -1;
      }
      formatIndex++;
    }
    if (formatIndex >= format.length()) {
      return -1;
    }

    /* width, precision */
    while ((formatIndex < format.length()) && (Character.isDigit(format.charAt(formatIndex)))) {
      formatToken.token.append(format.charAt(formatIndex));

      formatToken.width = formatToken.width * 10 + (format.charAt(formatIndex) - '0');
      formatIndex++;
    }
    if (formatIndex >= format.length()) {
      return -1;
    }

    /* precision */
    if (format.charAt(formatIndex) == '.') {
      formatToken.token.append(format.charAt(formatIndex));
      formatIndex++;
      while ((formatIndex < format.length()) && Character.isDigit(format.charAt(formatIndex))) {
        formatToken.token.append(format.charAt(formatIndex));

        formatToken.precision = formatToken.precision * 10 + (format.charAt(formatIndex) - '0');
        formatIndex++;
      }
    }

    /* quoting character */
    if ((formatIndex + 1 < format.length())
        && (format.charAt(formatIndex) != '{')
        && ((format.charAt(formatIndex + 1) == 's') || (format.charAt(formatIndex + 1) == 'S'))) {
      formatToken.quoteChar = format.charAt(formatIndex);
      formatIndex++;
    }

    /* length modifier */
    if ((formatIndex + 1 < format.length())
        && (format.charAt(formatIndex) == 'h')
        && (format.charAt(formatIndex + 1) == 'h')) {
      formatToken.token.append(format.charAt(formatIndex + 0));
      formatToken.token.append(format.charAt(formatIndex + 1));

      formatToken.lengthType = LengthTypes.INTEGER;
      formatIndex += 2;
    } else if ((formatIndex < format.length()) && (format.charAt(formatIndex) == 'h')) {
      formatToken.token.append(format.charAt(formatIndex));

      formatToken.lengthType = LengthTypes.INTEGER;
      formatIndex++;
    } else if ((formatIndex + 1 < format.length())
        && (format.charAt(formatIndex) == 'l')
        && (format.charAt(formatIndex + 1) == 'l')) {
      formatToken.token.append(format.charAt(formatIndex + 0));
      formatToken.token.append(format.charAt(formatIndex + 1));

      formatToken.lengthType = LengthTypes.LONG;
      formatIndex += 2;
    } else if ((formatIndex < format.length()) && (format.charAt(formatIndex) == 'l')) {
      formatToken.token.append(format.charAt(formatIndex));

      formatToken.lengthType = LengthTypes.LONG;
      formatIndex++;
    } else if ((formatIndex < format.length()) && (format.charAt(formatIndex) == 'j')) {
      formatToken.token.append(format.charAt(formatIndex));

      formatToken.lengthType = LengthTypes.INTEGER;
      formatIndex++;
    } else if ((formatIndex < format.length()) && (format.charAt(formatIndex) == 'z')) {
      formatToken.token.append(format.charAt(formatIndex));

      formatToken.lengthType = LengthTypes.INTEGER;
      formatIndex++;
    } else if ((formatIndex < format.length()) && (format.charAt(formatIndex) == 't')) {
      formatToken.token.append(format.charAt(formatIndex));

      formatToken.lengthType = LengthTypes.INTEGER;
      formatIndex++;
    }

    if ((formatIndex < format.length()) && (format.charAt(formatIndex) == '{')) {
      /* enum name */
      formatToken.token.append(format.charAt(formatIndex));
      formatIndex++;

      StringBuffer buffer = new StringBuffer();
      while ((formatIndex < format.length()) && (format.charAt(formatIndex) != '}')) {
        char ch = format.charAt(formatIndex);
        formatToken.token.append(ch);
        buffer.append((ch != '.') ? ch : '$');
        formatIndex++;
      }
      formatIndex++;

      formatToken.enumClassName = buffer.toString();
    }

    if (formatIndex >= format.length()) {
      return -1;
    }

    /* conversion character */
    switch (format.charAt(formatIndex)) {
      case 'S':
        formatToken.token.append('s');
        formatToken.conversionChar = 'S';
        break;
      default:
        formatToken.token.append(format.charAt(formatIndex));
        formatToken.conversionChar = format.charAt(formatIndex);
        break;
    }
    formatIndex++;

    return formatIndex;
  }
예제 #4
0
  /**
   * Creates a new TextToken by parsing a pseudo-HTML tag.
   *
   * @param g Graphics used to retrieve the font metric.
   * @param tag A pseudo HTML tag without '<' and '>'.
   * @return a new TextToken initialized according to the tag.
   */
  private TextToken updateTag(Graphics g, String tag) {
    String tempTag;
    TextToken textTok = null;
    char begChar;

    if (tag.length() > 0) {
      tag = tag.toLowerCase();
      begChar = tag.charAt(0);

      // End of Tag, we returns except for the case </p>
      if (begChar == '/') {
        char nxtChar = tag.charAt(1);

        tempTag = (String) m_heap.lastElement();

        if (tempTag.charAt(0) == nxtChar) // ! very simple verification !
        {
          textTok = closeTag(g, tempTag);
          if (nxtChar != 'p') return textTok;
        } else {
          System.out.println("[updateTag] no corresponding opened Tag : " + tag);
          return null;
        }
      }

      FormatToken prevTok = m_curTok;
      Insets prevMrg = prevTok.m_margin, margin = m_body.m_margin;
      int flags = m_body.m_flags,
          width = m_wCur + (prevMrg != null ? prevMrg.left + prevMrg.right : 0);

      // Start of Tag	+ </p>
      if (tag.equals("br") || begChar == 'p' || tag.equals("/p")) {
        if (tag.equals("br")) {
          if (prevMrg != null) margin = prevMrg;
          flags = prevTok.m_flags;
        }

        // We specify new margins
        if (begChar == 'p') {
          String alignStr = readAtt(tag, "a");

          if (alignStr != null) {
            char align = Character.toLowerCase(alignStr.charAt(0));

            flags = align == 'r' ? RIGHT_BIT : (align == 'c' ? CENTER_BIT : 0);
          }

          margin = readMargin(tag);

          if (tag.length() > 1 && alignStr == null && margin == null) {
            flags = m_body.m_flags;
            System.out.println("[updateTag] syntax error Tag : " + tag);
            return null;
          } else {
            m_heap.addElement(tag);
          }
        }

        // update pr�vious format Token
        prevTok.m_aMax = m_body.m_aMax;
        prevTok.m_dMax = m_body.m_dMax;
        prevTok.m_width = width;

        // reset current vars
        m_body.m_aMax = 0;
        m_body.m_dMax = 0;
        m_wCur = 0;

        // Stores the max width of all lines including its margins
        if (width > m_body.m_width) m_body.m_width = width;

        m_curTok = new FormatToken();
        m_curTok.m_flags = flags;
        m_curTok.m_margin = margin == null ? m_body.m_margin : margin;

        m_tokens.addElement(m_curTok);

        textTok = new TextToken();
        textTok.m_color = new Color(m_color);
        textTok.m_font = new Font(m_name, m_style, m_size);
      } else if (isGfx(begChar)) {
        textTok = updateGfx(g, tag);
        m_heap.addElement(tag);
      } else {
        System.out.println("[updateTag] Unknown Tag : " + tag);
        textTok = null;
      }
    }
    return textTok;
  }
예제 #5
0
  /**
   * Parses this to extract the Tokens using a line of text. This is necessary to evaluate the
   * rendering of the text (color, size, alignment...).
   *
   * @param g The graphics used to retrieve the font metrics.
   * @param htmlText A string of text with or without HTML tags to parse.
   */
  protected void parseText(Graphics g, String htmlText) {
    StringTokenizer tokenizer = new StringTokenizer(htmlText, "<>", true);
    String tokenStr, nextStr, prevStr = tokenizer.nextToken();
    boolean hasMore = tokenizer.hasMoreTokens(), isText = false;
    Font font = new Font(m_name, m_style, m_size);
    TextToken textTok = new TextToken();

    textTok.m_color = new Color(m_color);
    textTok.m_font = font;

    m_curTok = new FormatToken();
    m_curTok.m_flags = m_body.m_flags;
    m_curTok.m_margin = m_body.m_margin;

    m_tokens.addElement(m_curTok);

    g.setFont(font);

    while (hasMore) {
      tokenStr = tokenizer.nextToken();
      hasMore = tokenizer.hasMoreTokens();

      // A start of Tag
      if (prevStr.equals("<")) {
        nextStr = hasMore ? tokenizer.nextToken() : null;

        // A closed Tag
        if (hasMore && nextStr.equals(">")) // tag
        {
          textTok = updateTag(g, tokenStr);

          // An real Tag
          if (textTok != null) {
            isText = false;
          }
          // An unknown Tag. Handle it as normal text.
          else {
            textTok = new TextToken();
            updateText(g, "<" + tokenStr + ">", textTok, isText);
            isText = true;
          }

          prevStr = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : null;
        }
        // An unclosed Tag. Handle it as normal text.
        else {
          updateText(g, "<" + tokenStr, textTok, isText);
          prevStr = nextStr;
          isText = true;
        }
      }
      // Normal text
      else {
        updateText(g, prevStr, textTok, isText);
        prevStr = tokenStr;
        isText = true;
      }

      hasMore = tokenizer.hasMoreTokens();
    }

    // Don't forget the last or only piece of text
    if (prevStr != null) {
      updateText(g, prevStr, textTok, isText);
    }

    updateTag(g, "br"); // to set last line position

    updateBounds();
  }