Esempio n. 1
0
  /**
   * parse the text. When the text is parsed the width, height, leading are all calculated. The text
   * will only be truly parsed if the graphics context has changed or the text has changed or the
   * font has changed. Otherwise nothing is done when this method is called.
   *
   * @param g Graphics context.
   */
  public void parseText(Graphics g) {
    FontMetrics fm;
    TextState current = new TextState();
    char ch;
    Stack state = new Stack();
    int w = 0;

    if (lg != g) parse = true;
    lg = g;

    if (!parse) return;

    parse = false;
    width = 0;
    leading = 0;
    ascent = 0;
    descent = 0;
    height = 0;
    maxAscent = 0;
    maxDescent = 0;

    if (text == null || g == null) return;

    list.removeAllElements();

    if (font == null) current.f = g.getFont();
    else current.f = font;

    state.push(current);
    list.addElement(current);

    fm = g.getFontMetrics(current.f);

    for (int i = 0; i < text.length(); i++) {
      ch = text.charAt(i);

      switch (ch) {
        case '$':
          i++;
          if (i < text.length()) current.s.append(text.charAt(i));
          break;
          /*
           **                    Push the current state onto the state stack
           **                    and start a new storage string
           */
        case '{':
          w = current.getWidth(g);
          if (!current.isEmpty()) {
            current = current.copyState();
            list.addElement(current);
          }

          state.push(current);
          current.x += w;
          break;
          /*
           **                    Pop the state off the state stack and set the current
           **                    state to the top of the state stack
           */
        case '}':
          w = current.x + current.getWidth(g);
          state.pop();
          current = ((TextState) state.peek()).copyState();
          list.addElement(current);
          current.x = w;
          break;
        case '^':
          w = current.getWidth(g);
          if (!current.isEmpty()) {
            current = current.copyState();
            list.addElement(current);
          }
          current.f = getScriptFont(current.f);
          current.x += w;
          current.y -= (int) ((double) (current.getAscent(g)) * sup_offset + 0.5);
          break;
        case '_':
          w = current.getWidth(g);
          if (!current.isEmpty()) {
            current = current.copyState();
            list.addElement(current);
          }
          current.f = getScriptFont(current.f);
          current.x += w;
          current.y += (int) ((double) (current.getDescent(g)) * sub_offset + 0.5);
          break;

        default:
          current.s.append(ch);
          break;
      }
    }

    for (int i = 0; i < list.size(); i++) {
      current = ((TextState) (list.elementAt(i)));

      if (!current.isEmpty()) {
        width += current.getWidth(g);
        ascent = Math.max(ascent, Math.abs(current.y) + current.getAscent(g));
        descent = Math.max(descent, Math.abs(current.y) + current.getDescent(g));
        leading = Math.max(leading, current.getLeading(g));

        maxDescent = Math.max(maxDescent, Math.abs(current.y) + current.getMaxDescent(g));
        maxAscent = Math.max(maxAscent, Math.abs(current.y) + current.getMaxAscent(g));
      }
    }

    height = ascent + descent + leading;

    return;
  }