SkPDF: alloc less memory for strings
before:
micros bench
250.98 WritePDFText nonrendering
after:
micros bench
107.10 WritePDFText nonrendering
Also, be slightly more space-efficient in encoding strings.
Also, add a bench.
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2099463002
Review-Url: https://codereview.chromium.org/2099463002
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index 5b4ae93..b9e310d 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -1067,30 +1067,32 @@
// discarded. If true, the upper byte is encoded
// first. Otherwise, we assert the upper byte is
// zero.
-static SkString format_wide_string(const uint16_t* input,
- size_t len,
- bool wideChars) {
+static void write_wide_string(SkDynamicMemoryWStream* wStream,
+ const uint16_t* input,
+ size_t len,
+ bool wideChars) {
if (wideChars) {
SkASSERT(2 * len < 65535);
static const char gHex[] = "0123456789ABCDEF";
- SkString result(4 * len + 2);
- result[0] = '<';
+ wStream->writeText("<");
for (size_t i = 0; i < len; i++) {
- result[4 * i + 1] = gHex[(input[i] >> 12) & 0xF];
- result[4 * i + 2] = gHex[(input[i] >> 8) & 0xF];
- result[4 * i + 3] = gHex[(input[i] >> 4) & 0xF];
- result[4 * i + 4] = gHex[(input[i] ) & 0xF];
+ char result[4]; // Big-endian
+ result[0] = gHex[(input[i] >> 12) & 0xF];
+ result[1] = gHex[(input[i] >> 8) & 0xF];
+ result[2] = gHex[(input[i] >> 4) & 0xF];
+ result[3] = gHex[(input[i]) & 0xF];
+ wStream->write(result, 4);
}
- result[4 * len + 1] = '>';
- return result;
+ wStream->writeText(">");
} else {
SkASSERT(len <= 65535);
- SkString tmp(len);
+ SkAutoMalloc buffer(len); // Remove every other byte.
+ uint8_t* ptr = (uint8_t*)buffer.get();
for (size_t i = 0; i < len; i++) {
SkASSERT(0 == input[i] >> 8);
- tmp[i] = static_cast<uint8_t>(input[i]);
+ ptr[i] = static_cast<uint8_t>(input[i]);
}
- return SkPDFUtils::FormatString(tmp.c_str(), tmp.size());
+ SkPDFUtils::WriteString(wStream, (char*)buffer.get(), len);
}
}
@@ -1184,10 +1186,9 @@
fFontGlyphUsage->noteGlyphUsage(
font, glyphIDsCopy.begin() + consumedGlyphCount,
availableGlyphs);
- SkString encodedString =
- format_wide_string(glyphIDsCopy.begin() + consumedGlyphCount,
- availableGlyphs, font->multiByteGlyphs());
- content.entry()->fContent.writeText(encodedString.c_str());
+ write_wide_string(&content.entry()->fContent,
+ glyphIDsCopy.begin() + consumedGlyphCount,
+ availableGlyphs, font->multiByteGlyphs());
consumedGlyphCount += availableGlyphs;
content.entry()->fContent.writeText(" Tj\n");
}
@@ -1264,9 +1265,8 @@
align_text(glyphCacheProc, textPaint, glyphIDs + i, 1, &x, &y);
set_text_transform(x, y, textPaint.getTextSkewX(), &content.entry()->fContent);
- SkString encodedString =
- format_wide_string(&encodedValue, 1, font->multiByteGlyphs());
- content.entry()->fContent.writeText(encodedString.c_str());
+ write_wide_string(&content.entry()->fContent, &encodedValue, 1,
+ font->multiByteGlyphs());
content.entry()->fContent.writeText(" Tj\n");
}
content.entry()->fContent.writeText("ET\n");