Package com.adobe.dp.epub.ops

Source Code of com.adobe.dp.epub.ops.Element$SizeRemains

/*******************************************************************************
* Copyright (c) 2009, Adobe Systems Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* ·        Redistributions of source code must retain the above copyright
*          notice, this list of conditions and the following disclaimer.
*
* ·        Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*
* ·        Neither the name of Adobe Systems Incorporated nor the names of its
*       contributors may be used to endorse or promote products derived from
*       this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/

package com.adobe.dp.epub.ops;

import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.Stack;
import java.util.Vector;

import com.adobe.dp.css.CSSValue;
import com.adobe.dp.css.CascadeEngine;
import com.adobe.dp.css.CascadeResult;
import com.adobe.dp.css.InlineRule;
import com.adobe.dp.epub.otf.FontSubsetter;
import com.adobe.dp.epub.style.Stylesheet;
import com.adobe.dp.xml.util.SMapImpl;
import com.adobe.dp.xml.util.XMLSerializer;

abstract public class Element {

  OPSDocument document;

  String className;

  InlineRule style;

  CascadeResult cascade;

  boolean assignStyle;

  String elementName;

  String id;

  Vector children = new Vector();

  XRef selfRef;
 
  String lang;

  private static class SizeRemains {
    int size;
  }

  Element(OPSDocument document, String name) {
    this.document = document;
    elementName = name;
  }

  abstract public String getNamespaceURI();

  abstract Element cloneElementShallow(OPSDocument newDoc);

  public Element cloneElementShallow() {
    return cloneElementShallow(document);
  }

  protected Object getBuiltInProperty(String propName) {
    return null;
  }

  public String getLang() {
    return lang;
  }

  public void setLang(String lang) {
    this.lang = lang;
  }

  public Object getCascadedProperty(String propName) {

    // style attribute: highest specificity
    InlineRule style = getStyle();
    if (style != null) {
      Object value = style.get(propName);
      if (value != null)
        return value;
    }

    // CSS cascade from stylesheets
    if (cascade != null) {
      Object value = cascade.getProperties().getPropertySet().get(propName);
      if (value != null)
        return value;
    }

    // built-in stylesheet
    return getBuiltInProperty(propName);
  }

  public String getElementName() {
    return elementName;
  }

  public String getClassName() {
    return className;
  }

  public void setClassName(String className) {
    this.className = className;
  }

  public void add(Object child) {
    children.add(child);
  }

  public String getId() {
    return id;
  }

  public void setId(String id) {
    document.setElementId(this, id);
  }

  public Iterator content() {
    return children.iterator();
  }

  public Object getLastChild() {
    if (children.isEmpty())
      return null;
    return children.lastElement();
  }

  public XRef getSelfRef() {
    if (selfRef == null) {
      document.assignId(this);
      selfRef = new XRef(document.resource, this);
    }
    return selfRef;
  }

  SMapImpl getAttributes() {
    SMapImpl attrs = new SMapImpl();
    if (className != null)
      attrs.put(null, "class", className);
    if (id != null)
      attrs.put(null, "id", id);
    if (style != null)
      attrs.put(null, "style", style);
    if (lang != null)
      attrs.put(OPSDocument.xmlns, "lang", lang);
    return attrs;
  }

  public void addFonts(FontSubsetter subsetter) {
    subsetter.push(this);
    try {
      Iterator children = content();
      if (children != null) {
        while (children.hasNext()) {
          Object child = children.next();
          if (child instanceof Element) {
            ((Element) child).addFonts(subsetter);
          } else if (child instanceof String) {
            subsetter.play((String) child);
          }
        }
      }
    } finally {
      subsetter.pop(this);
    }
  }

  boolean isSection() {
    return false;
  }

  private static int getUTF8Length(String s) {
    try {
      return s.getBytes("UTF-8").length;
    } catch (UnsupportedEncodingException e) {
      throw new Error("UTF-8 unsupported???");
    }
  }

  int getElementSize() {
    int size = elementName.length() + 3;
    if (className != null) {
      size += className.length() + 9;
    }
    if (selfRef != null)
      size += 10;
    if (children.size() == 0)
      size++;
    else
      size += elementName.length() + 5;
    return size;
  }

  int getPeelingBonus() {
    return 0;
  }

  boolean forcePeel() {
    return false;
  }

  boolean canPeelChild() {
    return false;
  }

  final int getEstimatedSize() {
    int size = getElementSize();
    Iterator it = content();
    if (!it.hasNext())
      return size;
    while (it.hasNext()) {
      Object next = it.next();
      if (next instanceof Element)
        size += ((Element) next).getEstimatedSize();
      else if (next instanceof String) {
        size += getUTF8Length((String) next);
      }
      size++;
    }
    return size;
  }

  void transferToDocument(OPSDocument newDoc) {
    if (id != null)
      document.idMap.remove(id);
    document = newDoc;
    if (id != null)
      document.idMap.put(id, this);
    if (selfRef != null) {
      selfRef.targetResource = newDoc.resource.getResourceRef();
    }
    Iterator it = content();
    while (it.hasNext()) {
      Object next = it.next();
      if (next instanceof Element)
        ((Element) next).transferToDocument(newDoc);
    }
  }

  final Element peelElements(OPSDocument newDoc, int targetSize, boolean first) {
    SizeRemains sr = new SizeRemains();
    sr.size = targetSize + 1000;
    return peelElements(newDoc, sr, first);
  }

  final Element peelElements(OPSDocument newDoc, SizeRemains remains, boolean first) {
    int size = getElementSize();
    int bonus = getPeelingBonus();
    remains.size -= size;
    if (!first && (forcePeel() || (bonus >= 0 && bonus > remains.size))) {
      // System.out.println("Break for bonus " + bonus);
      transferToDocument(newDoc);
      return this;
    }
    Element result = null;
    boolean canPeelChild = canPeelChild();
    int i = 0;
    while (i < children.size()) {
      Object next = children.elementAt(i);
      if (next instanceof Element) {
        Element child = (Element) next;
        if (result == null) {
          if (canPeelChild) {
            Element p = child.peelElements(newDoc, remains, i == 0);
            if (p != null) {
              result = cloneElementShallow(newDoc);
              result.add(p);
              if (p == child) {
                children.remove(i);
                continue;
              }
            }
          } else {
            remains.size -= child.getEstimatedSize();
          }
        } else {
          children.remove(i);
          child.transferToDocument(newDoc);
          result.add(child);
          continue;
        }
      } else if (next instanceof String) {
        remains.size -= getUTF8Length((String) next);
      }
      remains.size--;
      i++;
    }
    return result;
  }

  public void generateTOCFromHeadings(Stack headings, int depth) {
    Iterator it = content();
    while (it.hasNext()) {
      Object next = it.next();
      if (next instanceof Element)
        ((Element) next).generateTOCFromHeadings(headings, depth);
    }
  }

  void serializeChildren(XMLSerializer ser) {
    boolean section = isSection();
    Iterator it = content();
    while (it.hasNext()) {
      Object next = it.next();
      if (next instanceof Element)
        ((Element) next).serialize(ser);
      else if (next instanceof String) {
        char[] arr = ((String) next).toCharArray();
        ser.text(arr, 0, arr.length);
      }
      if (section)
        ser.newLine();
    }
  }

  boolean makeNSDefault() {
    return false;
  }

  void serialize(XMLSerializer ser) {
    boolean section = isSection();
    String ns = getNamespaceURI();
    ser.startElement(ns, elementName, getAttributes(), makeNSDefault());
    if (section)
      ser.newLine();
    serializeChildren(ser);
    ser.endElement(ns, elementName);
  }

  public String getText() {
    StringBuffer sb = new StringBuffer();
    Iterator it = content();
    while (it.hasNext()) {
      Object next = it.next();
      if (next instanceof Element)
        sb.append(((Element) next).getText());
      else if (next instanceof String) {
        sb.append((String) next);
      }
    }
    return sb.toString();
  }

  public CascadeResult getCascadeResult() {
    if (cascade == null)
      cascade = new CascadeResult();
    return cascade;
  }

  public void setDesiredCascadeResult(InlineRule s) {
    CascadeResult cr = new CascadeResult();
    InlineRule t = cr.getProperties().getPropertySet();
    if (s != null) {
      Iterator it = s.properties();
      if (it != null) {
        while (it.hasNext()) {
          String p = (String) it.next();
          CSSValue value = s.get(p);
          t.set(p, value);
        }
      }
    }
    setDesiredCascadeResult(cr);
  }

  public void setDesiredCascadeResult(CascadeResult cascade) {
    this.cascade = cascade;
    this.assignStyle = true;
  }

  public InlineRule getStyle() {
    return style;
  }

  public void setStyle(InlineRule style) {
    this.style = style;
  }

  public int assignPlayOrder(int playOrder) {
    if (selfRef != null && selfRef.playOrderNeeded()) {
      selfRef.setPlayOrder(++playOrder);
    }
    Iterator it = content();
    while (it.hasNext()) {
      Object next = it.next();
      if (next instanceof Element)
        playOrder = ((Element) next).assignPlayOrder(playOrder);
    }
    return playOrder;
  }

  public void cascade(CascadeEngine engine) {
    engine.pushElement(getNamespaceURI(), getElementName(), getAttributes());
    cascade = engine.getCascadeResult();
    Iterator it = content();
    while (it.hasNext()) {
      Object next = it.next();
      if (next instanceof Element)
        ((Element) next).cascade(engine);
    }
    engine.popElement();
  }

  public void generateStyles(Stylesheet stylesheet) {
    if (assignStyle) {
      if (cascade != null && !cascade.isEmpty())
        className = stylesheet.makeClass(className, cascade);
      else
        className = null;
      assignStyle = false;
    }
    Iterator it = content();
    while (it.hasNext()) {
      Object next = it.next();
      if (next instanceof Element)
        ((Element) next).generateStyles(stylesheet);
    }
  }
 
  public void setAssignStylesFlag() {
    assignStyle = true;
    Iterator it = content();
    while (it.hasNext()) {
      Object next = it.next();
      if (next instanceof Element)
        ((Element) next).setAssignStylesFlag();
    }
  }

 

}
TOP

Related Classes of com.adobe.dp.epub.ops.Element$SizeRemains

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.