Skip to content

Commit

Permalink
Merge pull request #194 from rototor/testcase_big_document
Browse files Browse the repository at this point in the history
Testcase big document #180 with perf improvements.
  • Loading branch information
danfickle authored Apr 8, 2018
2 parents 48d83c4 + 93623a9 commit ac4954d
Show file tree
Hide file tree
Showing 42 changed files with 1,095 additions and 467 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,7 @@ protected boolean isCounter(FSFunction function, String counterName) {

if (parameters.size() == 2) {
param = (PropertyValue)parameters.get(1);
if (param.getPrimitiveType() != CSSPrimitiveValue.CSS_IDENT) {
return false;
}
return param.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT;
}

return true;
Expand Down Expand Up @@ -175,18 +173,14 @@ public boolean canHandle(LayoutContext c, FSFunction function) {
FSFunction f = ((PropertyValue)parameters.get(0)).getFunction();
if (f == null ||
f.getParameters().size() != 1 ||
((PropertyValue)f.getParameters().get(0)).getPrimitiveType() != CSSPrimitiveValue.CSS_IDENT ||
! ((PropertyValue)f.getParameters().get(0)).getStringValue().equals("href")) {
f.getParameters().get(0).getPrimitiveType() != CSSPrimitiveValue.CSS_IDENT ||
! f.getParameters().get(0).getStringValue().equals("href")) {
return false;
}

PropertyValue param = (PropertyValue)parameters.get(1);
if (param.getPrimitiveType() != CSSPrimitiveValue.CSS_IDENT ||
! param.getStringValue().equals("page")) {
return false;
}

return true;
return param.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT &&
param.getStringValue().equals("page");
}
}

Expand Down Expand Up @@ -226,7 +220,7 @@ public String calculate(RenderingContext c, FSFunction function, InlineText text
}

// Get leader value and value width
PropertyValue param = (PropertyValue)function.getParameters().get(0);
PropertyValue param = function.getParameters().get(0);
String value = param.getStringValue();
if (param.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT) {
if (value.equals("dotted")) {
Expand All @@ -241,7 +235,7 @@ public String calculate(RenderingContext c, FSFunction function, InlineText text
// Compute value width using 100x string to get more precise width.
// Otherwise there might be a small gap at the right side. This is
// necessary because a TextRenderer usually use double/float for width.
StringBuffer tmp = new StringBuffer(100 * value.length());
StringBuilder tmp = new StringBuilder(100 * value.length());
for (int i = 0; i < 100; i++) {
tmp.append(value);
}
Expand All @@ -255,7 +249,7 @@ public String calculate(RenderingContext c, FSFunction function, InlineText text
int count = (int) ((leaderWidth - (2 * spaceWidth)) / valueWidth);

// build leader string
StringBuffer buf = new StringBuffer(count * value.length() + 2);
StringBuilder buf = new StringBuilder(count * value.length() + 2);
buf.append(' ');
for (int i = 0; i < count; i++) {
buf.append(value);
Expand Down Expand Up @@ -284,15 +278,11 @@ public boolean canHandle(LayoutContext c, FSFunction function) {
List parameters = function.getParameters();
if (parameters.size() == 1) {
PropertyValue param = (PropertyValue)parameters.get(0);
if (param.getPrimitiveType() != CSSPrimitiveValue.CSS_STRING &&
(param.getPrimitiveType() != CSSPrimitiveValue.CSS_IDENT ||
(!param.getStringValue().equals("dotted") &&
!param.getStringValue().equals("solid") &&
!param.getStringValue().equals("space")))) {
return false;
}

return true;
return param.getPrimitiveType() == CSSPrimitiveValue.CSS_STRING ||
(param.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT &&
(param.getStringValue().equals("dotted") ||
param.getStringValue().equals("solid") ||
param.getStringValue().equals("space")));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,10 @@ public boolean isHoverStyled(Element e) {
* @param e The DOM Element for which to find properties
* @return Map of CSS property names to CSSValue instance assigned to it.
*/
public java.util.Map getCascadedPropertiesMap(Element e) {
public java.util.Map<String, org.w3c.dom.css.CSSPrimitiveValue> getCascadedPropertiesMap(Element e) {
CascadedStyle cs = _matcher.getCascadedStyle(e, false);//this is only for debug, I think
java.util.LinkedHashMap props = new java.util.LinkedHashMap();
for (java.util.Iterator i = cs.getCascadedPropertyDeclarations(); i.hasNext();) {
PropertyDeclaration pd = (PropertyDeclaration) i.next();

java.util.Map<String, org.w3c.dom.css.CSSPrimitiveValue> props = new java.util.LinkedHashMap<String, org.w3c.dom.css.CSSPrimitiveValue>();
for (PropertyDeclaration pd : cs.getCascadedPropertyDeclarations()) {
String propName = pd.getPropertyName();
CSSName cssName = CSSName.getByPropertyName(propName);
props.put(propName, cs.propertyByName(cssName).getValue());
Expand Down Expand Up @@ -239,8 +237,8 @@ public void flushAllStyleSheets() {
*
* @return The stylesheets value
*/
private List getStylesheets() {
List infos = new LinkedList();
private List<StylesheetInfo> getStylesheets() {
List<StylesheetInfo> infos = new ArrayList<StylesheetInfo>();
long st = System.currentTimeMillis();

StylesheetInfo defaultStylesheet = _nsh.getDefaultStylesheet(_stylesheetFactory);
Expand All @@ -251,22 +249,22 @@ private List getStylesheets() {
StylesheetInfo[] refs = _nsh.getStylesheets(_doc);
int inlineStyleCount = 0;
if (refs != null) {
for (int i = 0; i < refs.length; i++) {
for (StylesheetInfo ref : refs) {
String uri;
if (! refs[i].isInline()) {
uri = _uac.resolveURI(refs[i].getUri());
refs[i].setUri(uri);

if (!ref.isInline()) {
uri = _uac.resolveURI(ref.getUri());
ref.setUri(uri);
} else {
refs[i].setUri(_uac.getBaseURL() + "#inline_style_" + (++inlineStyleCount));
ref.setUri(_uac.getBaseURL() + "#inline_style_" + (++inlineStyleCount));
Stylesheet sheet = _stylesheetFactory.parse(
new StringReader(refs[i].getContent()), refs[i]);
refs[i].setStylesheet(sheet);
refs[i].setUri(null);
new StringReader(ref.getContent()), ref);
ref.setStylesheet(sheet);
ref.setUri(null);
}
}
infos.addAll(Arrays.asList(refs));
}
infos.addAll(Arrays.asList(refs));

// TODO: here we should also get user stylesheet from userAgent

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public String getLang(Object e) {

public String getElementStyling(Object el) {
Element e = ((Element) el);
StringBuffer style = new StringBuffer();
StringBuilder style = new StringBuilder();
if (e.getNodeName().equals("td")) {
String s;
if (!(s = e.getAttribute("colspan")).equals("")) {
Expand Down Expand Up @@ -114,8 +114,7 @@ public boolean isHover(Object e) {

public boolean isLink(Object el) {
Element e = ((Element) el);
if (e.getNodeName().equalsIgnoreCase("a") && !e.getAttribute("href").equals("")) return true;
return false;
return e.getNodeName().equalsIgnoreCase("a") && !e.getAttribute("href").equals("");
}

public boolean isVisited(Object e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,21 +60,26 @@ public class CascadedStyle {
/**
* Map of PropertyDeclarations, keyed by {@link CSSName}
*/
private Map cascadedProperties;
private Map<CSSName, PropertyDeclaration> cascadedProperties;

private String fingerprint;

/**
* Creates a <code>CascadedStyle</code>, setting the display property to
* to the value of the <code>display</code> parameter.
* Constructs a new CascadedStyle, given an {@link java.util.Iterator} of
* {@link com.openhtmltopdf.css.sheet.PropertyDeclaration}s already sorted
* by specificity of the CSS selector they came from. The Iterator can have
* multiple PropertyDeclarations with the same name; the property cascade
* will be resolved during instantiation, resulting in a set of
* PropertyDeclarations. Once instantiated, properties may be retrieved
* using the normal API for the class.
*
* @param iter An Iterator containing PropertyDeclarations in order of
* specificity.
*/
public static CascadedStyle createAnonymousStyle(IdentValue display) {
CSSPrimitiveValue val = new PropertyValue(display);

List props = Collections.singletonList(
new PropertyDeclaration(CSSName.DISPLAY, val, true, StylesheetInfo.USER));

return new CascadedStyle(props.iterator());
CascadedStyle(java.util.Iterator<PropertyDeclaration> iter) {
this();

addProperties(iter);
}

/**
Expand Down Expand Up @@ -118,60 +123,59 @@ public static PropertyDeclaration createLayoutPropertyDeclaration(
return new PropertyDeclaration(cssName, val, true, StylesheetInfo.USER);
}

private CascadedStyle(CascadedStyle startingPoint, Iterator<PropertyDeclaration> props) {
cascadedProperties = new TreeMap<CSSName, PropertyDeclaration>(startingPoint.cascadedProperties);

addProperties(props);
}

/**
* Constructs a new CascadedStyle, given an {@link java.util.Iterator} of
* {@link com.openhtmltopdf.css.sheet.PropertyDeclaration}s already sorted
* by specificity of the CSS selector they came from. The Iterator can have
* multiple PropertyDeclarations with the same name; the property cascade
* will be resolved during instantiation, resulting in a set of
* PropertyDeclarations. Once instantiated, properties may be retrieved
* using the normal API for the class.
*
* @param iter An Iterator containing PropertyDeclarations in order of
* specificity.
* Default constructor with no initialization. Don't use this to instantiate
* the class, as the class is immutable and this will leave it without any
* properties.
*/
CascadedStyle(java.util.Iterator iter) {
this();
private CascadedStyle() {
cascadedProperties = new TreeMap<CSSName, PropertyDeclaration>();
}
/**
* Creates a <code>CascadedStyle</code>, setting the display property to
* to the value of the <code>display</code> parameter.
*/
public static CascadedStyle createAnonymousStyle(IdentValue display) {
CSSPrimitiveValue val = new PropertyValue(display);

addProperties(iter);
List<PropertyDeclaration> props = Collections.singletonList(
new PropertyDeclaration(CSSName.DISPLAY, val, true, StylesheetInfo.USER));

return new CascadedStyle(props.iterator());
}

private void addProperties(java.util.Iterator iter) {
//do a bucket-sort on importance and origin
//properties should already be in order of specificity
java.util.List[] buckets = new java.util.List[PropertyDeclaration.IMPORTANCE_AND_ORIGIN_COUNT];
for (int i = 0; i < buckets.length; i++) {
buckets[i] = new java.util.LinkedList();
}
private void addProperties(java.util.Iterator<PropertyDeclaration> iter) {
/*
* do a bucket-sort on importance and origin /properties should already be in
* order of specificity
*/
//noinspection unchecked
java.util.List<PropertyDeclaration>[] buckets = (java.util.List<PropertyDeclaration>[])new java.util.List[PropertyDeclaration.IMPORTANCE_AND_ORIGIN_COUNT];

while (iter.hasNext()) {
PropertyDeclaration prop = (PropertyDeclaration) iter.next();
buckets[prop.getImportanceAndOrigin()].add(prop);
PropertyDeclaration prop = iter.next();
List<PropertyDeclaration> bucket = buckets[prop.getImportanceAndOrigin()];
if (bucket == null) {
bucket = new ArrayList<PropertyDeclaration>();
buckets[prop.getImportanceAndOrigin()] = bucket;
}
bucket.add(prop);
}

for (int i = 0; i < buckets.length; i++) {
for (java.util.Iterator it = buckets[i].iterator(); it.hasNext();) {
PropertyDeclaration prop = (PropertyDeclaration) it.next();
for (List<PropertyDeclaration> bucket : buckets) {
if (bucket == null)
continue;
for (PropertyDeclaration prop : bucket) {
cascadedProperties.put(prop.getCSSName(), prop);
}
}
}

private CascadedStyle(CascadedStyle startingPoint, Iterator props) {
cascadedProperties = new TreeMap(startingPoint.cascadedProperties);

addProperties(props);
}


/**
* Default constructor with no initialization. Don't use this to instantiate
* the class, as the class is immutable and this will leave it without any
* properties.
*/
private CascadedStyle() {
cascadedProperties = new TreeMap();
}

/**
* Get an empty singleton, used to negate inheritance of properties
Expand All @@ -186,10 +190,8 @@ private CascadedStyle() {
* @return True if the property is defined in this set.
*/
public boolean hasProperty(CSSName cssName) {
return cascadedProperties.get( cssName ) != null;
return cascadedProperties.get(cssName) != null;
}


/**
* Returns a {@link com.openhtmltopdf.css.sheet.PropertyDeclaration} by CSS
* property name, e.g. "font-family". Properties are already cascaded during
Expand All @@ -201,9 +203,7 @@ public boolean hasProperty(CSSName cssName) {
* if not found.
*/
public PropertyDeclaration propertyByName(CSSName cssName) {
PropertyDeclaration prop = (PropertyDeclaration)cascadedProperties.get(cssName);

return prop;
return cascadedProperties.get(cssName);
}

/**
Expand All @@ -227,23 +227,17 @@ public IdentValue getIdent(CSSName cssName) {
*
* @return Iterator over a set of properly cascaded PropertyDeclarations.
*/
public java.util.Iterator getCascadedPropertyDeclarations() {
List list = new ArrayList(cascadedProperties.size());
Iterator iter = cascadedProperties.values().iterator();
while ( iter.hasNext()) {
list.add(iter.next());
}
return list.iterator();
public java.util.Collection<PropertyDeclaration> getCascadedPropertyDeclarations() {
return cascadedProperties.values();
}

public int countAssigned() { return cascadedProperties.size(); }

public String getFingerprint() {
if (this.fingerprint == null) {
StringBuffer sb = new StringBuffer();
Iterator iter = cascadedProperties.values().iterator();
while (iter.hasNext()) {
sb.append(((PropertyDeclaration)iter.next()).getFingerprint());
StringBuilder sb = new StringBuilder();
for (PropertyDeclaration o : cascadedProperties.values()) {
sb.append(o.getFingerprint());
}
this.fingerprint = sb.toString();
}
Expand Down
Loading

0 comments on commit ac4954d

Please sign in to comment.