Skip to content

Commit

Permalink
For #180 - Performance: Replace collapse white-space regular expressi…
Browse files Browse the repository at this point in the history
…ons with more performant loop for normal and no-wrap mode white-space settings.
  • Loading branch information
danfickle committed Apr 5, 2018
1 parent 65b7faa commit 36c52aa
Showing 1 changed file with 42 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -145,19 +145,55 @@ private static boolean stripWhitespace(InlineBox iB, boolean collapseLeading) {
}
return text.equals("") ? collapseLeading : collapseNext;
}

/**
* Collapse whitespace for normal or no-wrap modes. Much faster (15x in simple testing)
* than using multiple regular expressions.
*
* NOTE: Slightly different behavior to using regular expressions as definition of space characters
* differ, but I believe this is the correct definition according to CSS specifications.
* @param text
* @param collapseLeading
* @return
*/
private static String collapseWhitespaceNormalOrNoWrap(String text, boolean collapseLeading) {
char[] chs = text.toCharArray();
StringBuilder builder = new StringBuilder(chs.length);
boolean spaceAdded = collapseLeading;

for (int i = 0; i < chs.length; i++) {
char ch = chs[i];

if (spaceAdded) {
if (ch != '\n' &&
ch != '\t' &&
ch != ' ') {
builder.append(ch);
spaceAdded = false;
}
} else {
if (ch == '\n' ||
ch == '\t' ||
ch == ' ') {
builder.append(' ');
spaceAdded = true;
} else {
builder.append(ch);
}
}
}

return builder.toString();
}

private static String collapseWhitespace(InlineBox iB, IdentValue whitespace, String text, boolean collapseLeading) {
if (whitespace == IdentValue.NORMAL || whitespace == IdentValue.NOWRAP) {
text = linefeed_space_collapse.matcher(text).replaceAll(EOL);
return collapseWhitespaceNormalOrNoWrap(text, collapseLeading);
} else if (whitespace == IdentValue.PRE) {
text = space_before_linefeed_collapse.matcher(text).replaceAll(EOL);
}

if (whitespace == IdentValue.NORMAL || whitespace == IdentValue.NOWRAP) {
text = linefeed_to_space.matcher(text).replaceAll(SPACE);
text = tab_to_space.matcher(text).replaceAll(SPACE);
text = space_collapse.matcher(text).replaceAll(SPACE);
} else if (whitespace == IdentValue.PRE || whitespace == IdentValue.PRE_WRAP) {
if (whitespace == IdentValue.PRE || whitespace == IdentValue.PRE_WRAP) {
int tabSize = (int) iB.getStyle().asFloat(CSSName.TAB_SIZE);
char[] tabs = new char[tabSize];
Arrays.fill(tabs, ' ');
Expand All @@ -167,14 +203,6 @@ private static String collapseWhitespace(InlineBox iB, IdentValue whitespace, St
text = space_collapse.matcher(text).replaceAll(SPACE);
}

if (whitespace == IdentValue.NORMAL || whitespace == IdentValue.NOWRAP) {
// collapse first space against prev inline
if (text.startsWith(SPACE) &&
collapseLeading) {
text = text.substring(1, text.length());
}
}

return text;
}
}
Expand Down

0 comments on commit 36c52aa

Please sign in to comment.