Package net.sf.jpluck.plucker

Source Code of net.sf.jpluck.plucker.Paragraph$ListBullet

package net.sf.jpluck.plucker;

import net.sf.jpluck.palm.PdbOutputStream;
import net.sf.jpluck.plucker.functions.EmbeddedImage;
import net.sf.jpluck.plucker.functions.EmbeddedTable;
import net.sf.jpluck.plucker.functions.Function;
import net.sf.jpluck.plucker.functions.LinkEnd;
import net.sf.jpluck.plucker.functions.LinkFunction;
import net.sf.jpluck.plucker.functions.LinkStart;
import net.sf.jpluck.plucker.functions.Margin;
import net.sf.jpluck.plucker.functions.Newline;
import net.sf.jpluck.plucker.functions.ParagraphLinkStart;
import net.sf.jpluck.plucker.functions.SignificantContent;
import net.sf.jpluck.plucker.functions.TextColor;
import net.sf.jpluck.util.URIUtil;

import java.awt.Color;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;


public class Paragraph implements Serializable {
  public static final int DEFAULT_SPACING = 2;
  transient TextRecord textRecord;
  private transient List anchorList = new ArrayList();
  private List contentList = new ArrayList();
  private transient List uriList = new ArrayList();
  private Set resourceSet = new HashSet();
  private int size;
  private int spacing;
  private int written;

  Paragraph(int spacing) {
    setSpacing(spacing);
  }

  Paragraph() {
    this(0);
  }

  public String[] getAnchors() {
    return (String[]) anchorList.toArray(new String[anchorList.size()]);
  }

  public boolean isEmpty() {
    return (contentList.size() == 0);
  }

  public int getMaximumSize() {
    int size = 0;
    for (Iterator iterator = contentList.iterator(); iterator.hasNext();) {
      Object obj = iterator.next();
      if (obj instanceof Text) {
        size += ((Text) obj).getSize();
      }
      if (obj instanceof EmbeddedImage) {
        EmbeddedImage image = (EmbeddedImage) obj;
        if ((textRecord.document.resolve(image.getURI()) == null) && (image.getAlt() != null)) {
          // Alt text if image is not found
          size += (2 + image.getAlt().getSize());
          continue;
        }
      }
      if (obj instanceof Function) {
        size += (1 + ((Function) obj).getSize()); // preceding NUL + size of the function itself
      }
      if ((obj instanceof LinkStart || obj instanceof ParagraphLinkStart || obj instanceof LinkEnd)) {
        size += (1 + 4); // We have to add 5 bytes for setting the link color.
      }
      if (obj instanceof ListBullet) {
        size += ((ListBullet) obj).getSize();
      }
      if (obj instanceof OrderedListItem) {
        size += ((OrderedListItem) obj).getSize();
      }
    }
    return size;
  }

  public Resource[] getResources() {
    return (Resource[]) resourceSet.toArray(new Resource[resourceSet.size()]);
  }

  public int getSize() {
    return size;
  }

  public void setSpacing(int spacing) {
    if ((spacing < 0) || (spacing > 7)) {
      throw new IllegalArgumentException("Invalid paragraph spacing " + spacing);
    }
    this.spacing = spacing;
  }

  public int getSpacing() {
    return spacing;
  }

  public Paragraph addAlignCenter() {
    return addFunction(Functions.alignCenter());
  }

  public Paragraph addAlignJustify() {
    return addFunction(Functions.alignJustify());
  }

  public Paragraph addAlignLeft() {
    return addFunction(Functions.alignLeft());
  }

  public Paragraph addAlignRight() {
    return addFunction(Functions.alignRight());
  }

  public void addAnchor(String anchor) {
    if (!anchorList.contains("anchor")) {
      anchorList.add(anchor);
    }
  }

  public Paragraph addEmbeddedImage(String uri) {
    return addFunction(new EmbeddedImage(uri));
  }

  public Paragraph addEmbeddedImage(String uri, String alt) {
    if (alt != null) {
      return addFunction(new EmbeddedImage(uri, new Text(alt, textRecord.getOutputEncoding())));
    } else {
      return addFunction(new EmbeddedImage(uri));
    }
  }

  public Paragraph addFontBold() {
    return addFunction(Functions.fontBold());
  }
   
  public Paragraph addFontFixedWidth() {
    return addFunction(Functions.fontFixedWidth());
  }

  // Small fonts are not supported by the viewer for now so we leave it out for the time being

  /*public Paragraph addFontSmall() {
      return addFunction(Functions.fontSmall());
  }*/

  public Paragraph addFontH1() {
    return addFunction(Functions.fontH1());
  }

  public Paragraph addFontH2() {
    return addFunction(Functions.fontH2());
  }

  public Paragraph addFontH3() {
    return addFunction(Functions.fontH3());
  }

  public Paragraph addFontH4() {
    return addFunction(Functions.fontH4());
  }

  public Paragraph addFontH5() {
    return addFunction(Functions.fontH5());
  }

  public Paragraph addFontH6() {
    return addFunction(Functions.fontH6());
  }

  public Paragraph addFontRegular() {
    return addFunction(Functions.fontRegular());
  }

  public Paragraph addFontSubscript() {
    return addFunction(Functions.fontSubscript());
  }

  public Paragraph addFontSuperscript() {
    return addFunction(Functions.fontSuperScript());
  }

  public Paragraph addFunction(Function function) {
    contentList.add(function);
    size += function.getSize();
    if (function instanceof LinkStart || function instanceof ParagraphLinkStart || function instanceof LinkEnd) {
      size += (1 + 4); // We have to add 5 bytes for setting the link color.
    }
    if (function instanceof LinkStart || function instanceof ParagraphLinkStart) {
      String uri = ((LinkFunction) function).getURI();
      if (!uriList.contains(uri)) {
        uriList.add(uri);
      }
    }
    return this;
  }

  public Paragraph addHorizontalRuleAbsolute(int width, int height) {
    return addFunction(Functions.horizontalRuleAbsolute(width, height));
  }

  public Paragraph addHorizontalRuleRelative(int width, int height) {
    return addFunction(Functions.horizontalRuleRelative(width, height));
  }

  public Paragraph addItalicEnd() {
    return addFunction(Functions.italicEnd());
  }

  public Paragraph addItalicStart() {
    return addFunction(Functions.italicStart());
  }

  public Paragraph addLinkEnd() {
    return addFunction(Functions.linkEnd());
  }

  public Paragraph addLinkStart(String uri) {
    return addFunction(new LinkStart(uri));
  }

  public Paragraph addLinkStart(String uri, int paragraphNumber) {
    return addFunction(new ParagraphLinkStart(uri, paragraphNumber));
  }

  public Paragraph addListBullet(int margin) {
    contentList.add(new ListBullet(margin, textRecord.isForHires()));
    return this;
  }

  public Paragraph addMargin(int left, int right) {
    return addFunction(Functions.margin(left, right));
  }

  public Paragraph addNewline() {
    if (contentList.size() > 0) {
      Object lastObject = contentList.get(contentList.size() - 1);
      if (lastObject instanceof Newline) {
        addText(Text.createNonBreakingSpace());
      } else if (lastObject instanceof Text) {
        Text text = (Text) lastObject;
        if (!(text.hasSignificantContent())) {
          contentList.remove(text);
          size -= text.getSize();
          addText(Text.createNonBreakingSpace());
        }
      }
    }
    return addFunction(Functions.newline());
  }

  public Paragraph addOrderedListItem(int margin, int number) {
    contentList.add(new OrderedListItem(margin, number));
    return this;
  }

  public Paragraph addPreformattedText(String text) {
    return addText(new Text(text, textRecord.outputEncoding), true);
  }

  public Paragraph addResource(Resource resource) {
    if (resource == null) {
      throw new NullPointerException("Resource cannot be null.");
    }
    if (!resourceSet.contains(resource)) {
      resourceSet.add(resource);
    }
    contentList.add(resource);
    size += resource.getSize();
    return this;
  }

  public Paragraph addResource(String uri) {
    Resource resource = Resource.getResource(uri);
    if (resource != null) {
      addResource(resource);
    } else {
      throw new IllegalArgumentException("Resource not found \"" + uri + "\"");
    }
    return this;
  }

  public Paragraph addStrikethroughEnd() {
    return addFunction(Functions.strikethroughEnd());
  }

  public Paragraph addStrikethroughStart() {
    return addFunction(Functions.strikethroughStart());
  }

  public Paragraph addTable(String uri) {
    return addFunction(new EmbeddedTable(uri));
  }
 
  public Paragraph addText(String text) {
    return addText(new Text(text, textRecord.outputEncoding), false);
  }
 
  public Paragraph addText(Text text, boolean preformatted) {
    if (!preformatted) {
      if (contentList.size() > 0) {
        // Collapse adjacent Text sections.
        Object obj = contentList.get(contentList.size() - 1);
        if (obj instanceof Text) {
          Text prevText = (Text) obj;
          size += prevText.add(text);
          return this;
        }
        if (obj instanceof OrderedListItem || obj instanceof ListBullet) {
          text.stripLeadingSpace();
        }
      }
    }
    if (text.getSize() > 0) {
      contentList.add(text);
      size += text.getSize();
    }
    return this;
  }

  public Paragraph addText(Text text) {
    return addText(text, false);
  }

  public Paragraph addTextColor(int red, int green, int blue) {
    return addFunction(Functions.textColor(red, green, blue));
  }

  public Paragraph addTextColor(Color color) {
    return addFunction(Functions.textColor(color));
  }

  public Paragraph addUnderlineEnd() {
    return addFunction(Functions.underlineEnd());
  }

  public Paragraph addUnderlineStart() {
    return addFunction(Functions.underlineStart());
  }

  public void clear() {
    contentList.clear();
    size = 0;
  }

  public boolean containsListItemOnly() {
    boolean containsListItem = false;
    for (Iterator iterator = contentList.iterator(); iterator.hasNext();) {
      Object o = iterator.next();
      if (o instanceof Text) {
        if (((Text) o).hasSignificantContent()) {
          return false;
        }
      }
      if (o instanceof SignificantContent) {
        return false;
      }
      if (o instanceof ListBullet || o instanceof OrderedListItem) {
        containsListItem = true;
      }
    }
    return containsListItem;
  }

  public boolean containsSignificantContent() {
    for (Iterator iterator = contentList.iterator(); iterator.hasNext();) {
      Object o = iterator.next();
      if (o instanceof Text) {
        if (((Text) o).hasSignificantContent()) {
          return true;
        }
      }
      if (o instanceof SignificantContent) {
        return true;
      }
    }
    return false;
  }

  public void write(PdbOutputStream out) throws IOException {
    // Write Paragraph records in Text Record
    int prevSize = out.size();
    Color linkColor = textRecord.document.getDefaultLinkColor();
    if (linkColor == null) {
      linkColor = textRecord.getLinkColor();
    }

    boolean linkColored = false;
    boolean linkStarted = true;
    for (int i = 0, n = contentList.size(); i < n; i++) {
      Object obj = contentList.get(i);

      //boolean fullSizeLink = false;
      if (obj instanceof Text) {
        Text text = (Text) obj;

        // Skip insignificant content at the start of the Paragraph.
        if (!((i == 0) && !text.hasSignificantContent())) {
          text.write(out);
        }
      } else if (obj instanceof Function) {
        Function function = (Function) obj;
        if (function instanceof EmbeddedImage) {
          EmbeddedImage image = (EmbeddedImage) function;
          if (textRecord.document.getLinkableRecord(image.getURI()) == null) {
            // If the image is not found in the Document then we try to write the alt text instead.
            if ((image.getAlt() != null) && (image.getAlt().getSize() > 0) &&
                textRecord.document.isIncludeImageAltText()) {
              out.writeString("[");
              image.getAlt().write(out);
              out.writeString("]");
            }
            continue;
          }
        }
        if (function instanceof LinkFunction) {
          LinkFunction linkFunction = (LinkFunction) function;
          linkFunction.setURIResolver(textRecord.document);
        }
        if (function instanceof LinkEnd && !linkStarted) {
          continue;
        }
        if (function instanceof LinkStart) {
          LinkFunction linkFunction = (LinkFunction) function;
          boolean brokenLink = !textRecord.document.contains(URIUtil.removeAnchor(linkFunction.getURI()));
          if (brokenLink && textRecord.document.isRemoveUnresolvedLinks()) {
            linkStarted = false;
            continue;
          } else {
            linkStarted = true;
          }
          if (textRecord.document.isUseLinkColoring()) {
            Color brokenLinkColor = textRecord.document.getUnresolvedLinkColor();
            if (brokenLink && (brokenLinkColor != null)) {
              // Add a text color function to color the link
              TextColor textColor = new TextColor(brokenLinkColor);

              // Preceding NUL
              out.writeByte(0);
              textColor.write(out);
              linkColored = true;
            } else if (linkColor != null) {
              // Add a text color function to color the link
              TextColor textColor = new TextColor(linkColor);
              // Preceding NUL
              out.writeByte(0);
              textColor.write(out);
              linkColored = true;
            }
          }
        }
        if (function instanceof TextColor) {
          if (textRecord.document.isUseTextColors()) {
            textRecord.currentTextColor = ((TextColor) function).getColor();
          } else {
            continue;
          }
        }
        out.writeByte(0); // Preceding NUL
        function.write(out);
        if (function instanceof LinkEnd && linkColored) {
          // Preceding NUL
          out.writeByte(0);
          if (textRecord.currentTextColor != null) {
            new TextColor(textRecord.currentTextColor).write(out);
          } else {
            // Assume black
            Functions.TEXT_COLOR_BLACK.write(out);
          }
          linkColored = false;
        }
      } else if (obj instanceof Resource) {
        ((Resource) obj).write(out);
      } else if (obj instanceof ListBullet) {
        ((ListBullet) obj).write(out);
      } else if (obj instanceof OrderedListItem) {
        ((OrderedListItem) obj).write(out);
      }
    }
    out.flush();
    written = out.size() - prevSize;
  }

  String[] getLinkURIs() {
    return (String[]) uriList.toArray(new String[uriList.size()]);
  }

  int getWrittenSize() {
    return written;
  }

  private static class ListBullet implements Serializable {
    private byte[] content = new byte[6];

    ListBullet(int margin, boolean hires) {
      content[0] = (byte) 0x95; // MID-DOT;
      content[1] = ' ';
      content[2] = 0;
      content[3] = Function.SET_MARGIN;
      content[4] = (byte) (margin + (6 * (hires? 2 : 1)));
      content[5] = 0;
    }

    public int getSize() {
      return content.length;
    }

    public void write(PdbOutputStream out) throws IOException {
      out.write(content);
    }
  }

  private static class OrderedListItem implements Serializable {
    private byte[] content;

    OrderedListItem(int margin, int number) {
      try {
        margin += 9;
        if (number > 9) {
          margin += 5;
        }
        if (number > 99) {
          margin += 5;
        }

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PdbOutputStream out = new PdbOutputStream(baos);
        new Text(number + ". ", "ISO-8859-1").write(out);
        out.writeByte(0);
        new Margin(margin, 0).write(out);
        out.close();
        content = baos.toByteArray();
      } catch (IOException e) {
        // Should not occur
        throw new RuntimeException(e);
      }
    }

    public int getSize() {
      return content.length;
    }

    public void write(PdbOutputStream out) throws IOException {
      out.write(content);
    }
  }
}
TOP

Related Classes of net.sf.jpluck.plucker.Paragraph$ListBullet

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.