/**
  * Add an attribute only if it doesn't exist so that we don't loose information replacing it with
  * SimpleAttributeSet.EMPTY
  */
 private static void addAttribute(MutableAttributeSet to, Object key, Object value) {
   Object attr = to.getAttribute(key);
   if (attr == null || attr == SimpleAttributeSet.EMPTY) {
     to.addAttribute(key, value);
   } else {
     if (attr instanceof MutableAttributeSet && value instanceof AttributeSet) {
       ((MutableAttributeSet) attr).addAttributes((AttributeSet) value);
     }
   }
 }
  /**
   * Change the size of this image. This alters the HEIGHT and WIDTH attributes of the Element and
   * causes a re-layout.
   */
  protected void resize(int width, int height) {
    if (width == fWidth && height == fHeight) return;

    fWidth = width;
    fHeight = height;

    // Replace attributes in document:
    MutableAttributeSet attr = new SimpleAttributeSet();
    attr.addAttribute(HTML.Attribute.WIDTH, Integer.toString(width));
    attr.addAttribute(HTML.Attribute.HEIGHT, Integer.toString(height));
    ((StyledDocument) getDocument())
        .setCharacterAttributes(fElement.getStartOffset(), fElement.getEndOffset(), attr, false);
  }
 /**
  * Copies the given AttributeSet to a new set, converting any CSS attributes found to arguments of
  * an HTML style attribute.
  */
 private static void convertToHTML40(AttributeSet from, MutableAttributeSet to) {
   Enumeration keys = from.getAttributeNames();
   String value = "";
   while (keys.hasMoreElements()) {
     Object key = keys.nextElement();
     if (key instanceof CSS.Attribute) {
       value = value + " " + key + "=" + from.getAttribute(key) + ";";
     } else {
       to.addAttribute(key, from.getAttribute(key));
     }
   }
   if (value.length() > 0) {
     to.addAttribute(HTML.Attribute.STYLE, value);
   }
 }
 /**
  * Convert the give set of attributes to be html for the purpose of writing them out. Any keys
  * that have been converted will not appear in the resultant set. Any keys not converted will
  * appear in the resultant set the same as the received set.
  *
  * <p>This will put the converted values into <code>to</code>, unless it is null in which case a
  * temporary AttributeSet will be returned.
  */
 AttributeSet convertToHTML(AttributeSet from, MutableAttributeSet to) {
   if (to == null) {
     to = convAttr;
   }
   to.removeAttributes(to);
   if (writeCSS) {
     convertToHTML40(from, to);
   } else {
     convertToHTML32(from, to);
   }
   return to;
 }
 @Override
 public void handleStartTag(HTML.Tag tag, MutableAttributeSet attr, int pos) {
   // <B>が出たら次の地の文はカテゴリ名。なのでフラグを立てる。
   if (tag.equals(HTML.Tag.B)) {
     start_bold = true;
     start_category_flag = true;
   }
   // <A>タグが出たらurlを保持。あとで板名とペアにする。
   if (tag.equals(HTML.Tag.A)) {
     // 頭についてる広告タグは無視。
     if (parse_2ch_start_flag) {
       String href = (String) attr.getAttribute(HTML.Attribute.HREF);
       next_board_url = href;
     }
   }
 }
 /**
  * Create/update an HTML &lt;font&gt; tag attribute. The value of the attribute should be a
  * MutableAttributeSet so that the attributes can be updated as they are discovered.
  */
 private static void createFontAttribute(
     CSS.Attribute a, AttributeSet from, MutableAttributeSet to) {
   MutableAttributeSet fontAttr = (MutableAttributeSet) to.getAttribute(HTML.Tag.FONT);
   if (fontAttr == null) {
     fontAttr = new SimpleAttributeSet();
     to.addAttribute(HTML.Tag.FONT, fontAttr);
   }
   // edit the parameters to the font tag
   String htmlValue = from.getAttribute(a).toString();
   if (a == CSS.Attribute.FONT_FAMILY) {
     fontAttr.addAttribute(HTML.Attribute.FACE, htmlValue);
   } else if (a == CSS.Attribute.FONT_SIZE) {
     fontAttr.addAttribute(HTML.Attribute.SIZE, htmlValue);
   } else if (a == CSS.Attribute.COLOR) {
     fontAttr.addAttribute(HTML.Attribute.COLOR, htmlValue);
   }
 }
  /**
   * Create an older style of HTML attributes. This will convert character level attributes that
   * have a StyleConstants mapping over to an HTML tag/attribute. Other CSS attributes will be
   * placed in an HTML style attribute.
   */
  private static void convertToHTML32(AttributeSet from, MutableAttributeSet to) {
    if (from == null) {
      return;
    }
    Enumeration keys = from.getAttributeNames();
    String value = "";
    while (keys.hasMoreElements()) {
      Object key = keys.nextElement();
      if (key instanceof CSS.Attribute) {
        if ((key == CSS.Attribute.FONT_FAMILY)
            || (key == CSS.Attribute.FONT_SIZE)
            || (key == CSS.Attribute.COLOR)) {

          createFontAttribute((CSS.Attribute) key, from, to);
        } else if (key == CSS.Attribute.FONT_WEIGHT) {
          // add a bold tag is weight is bold
          CSS.FontWeight weightValue =
              (CSS.FontWeight) from.getAttribute(CSS.Attribute.FONT_WEIGHT);
          if ((weightValue != null) && (weightValue.getValue() > 400)) {
            addAttribute(to, HTML.Tag.B, SimpleAttributeSet.EMPTY);
          }
        } else if (key == CSS.Attribute.FONT_STYLE) {
          String s = from.getAttribute(key).toString();
          if (s.indexOf("italic") >= 0) {
            addAttribute(to, HTML.Tag.I, SimpleAttributeSet.EMPTY);
          }
        } else if (key == CSS.Attribute.TEXT_DECORATION) {
          String decor = from.getAttribute(key).toString();
          if (decor.indexOf("underline") >= 0) {
            addAttribute(to, HTML.Tag.U, SimpleAttributeSet.EMPTY);
          }
          if (decor.indexOf("line-through") >= 0) {
            addAttribute(to, HTML.Tag.STRIKE, SimpleAttributeSet.EMPTY);
          }
        } else if (key == CSS.Attribute.VERTICAL_ALIGN) {
          String vAlign = from.getAttribute(key).toString();
          if (vAlign.indexOf("sup") >= 0) {
            addAttribute(to, HTML.Tag.SUP, SimpleAttributeSet.EMPTY);
          }
          if (vAlign.indexOf("sub") >= 0) {
            addAttribute(to, HTML.Tag.SUB, SimpleAttributeSet.EMPTY);
          }
        } else if (key == CSS.Attribute.TEXT_ALIGN) {
          addAttribute(to, HTML.Attribute.ALIGN, from.getAttribute(key).toString());
        } else {
          // default is to store in a HTML style attribute
          if (value.length() > 0) {
            value = value + "; ";
          }
          value = value + key + ": " + from.getAttribute(key);
        }
      } else {
        Object attr = from.getAttribute(key);
        if (attr instanceof AttributeSet) {
          attr = ((AttributeSet) attr).copyAttributes();
        }
        addAttribute(to, key, attr);
      }
    }
    if (value.length() > 0) {
      to.addAttribute(HTML.Attribute.STYLE, value);
    }
  }