SkStream: remove some WStream functions from public api

move functions to SkStringPriv.h

also add SkStrAppendU32Hex() function, and re-write
SkString::insertHex() to use SkStrAppendU32Hex.

add unit tests.

Change-Id: Ieda98fb4106db71565b607e593713a91a5ddd892
Reviewed-on: https://skia-review.googlesource.com/151986
Reviewed-by: Cary Clark <caryclark@google.com>
Commit-Queue: Hal Canary <halcanary@google.com>
This commit is contained in:
Hal Canary 2018-09-05 22:32:41 -04:00 committed by Skia Commit-Bot
parent 71f8475a0d
commit 8b68110507
15 changed files with 246 additions and 185 deletions

View File

@ -16,6 +16,7 @@
#include "SkPixmap.h"
#include "SkRandom.h"
#include "SkStream.h"
#include "SkStreamPriv.h"
#include "SkTo.h"
namespace {
@ -85,7 +86,7 @@ static void test_pdf_object_serialization(const sk_sp<SkPDFObject> object) {
objNumMap.addObjectRecursively(object.get());
for (size_t i = 0; i < objNumMap.objects().size(); ++i) {
SkPDFObject* object = objNumMap.objects()[i].get();
wStream.writeDecAsText(i + 1);
SkWStreamWriteDecAsText(&wStream, i + 1);
wStream.writeText(" 0 obj\n");
object->emitObject(&wStream, objNumMap);
wStream.writeText("\nendobj\n");

View File

@ -260,13 +260,6 @@ public:
bool newline() { return this->write("\n", strlen("\n")); }
bool writeDecAsText(int32_t);
bool writeBigDecAsText(int64_t, int minDigits = 0);
bool writeHexAsText(uint32_t, int minDigits = 0);
bool writeScalarAsText(SkScalar);
bool writeBool(bool v) { return this->write8(v); }
bool writeScalar(SkScalar);
bool writePackedUInt(size_t);
bool writeStream(SkStream* input, size_t length);

View File

@ -89,6 +89,9 @@ char* SkStrAppendU32(char buffer[], uint32_t);
#define SkStrAppendU64_MaxSize 20
char* SkStrAppendU64(char buffer[], uint64_t, int minDigits);
#define SkStrAppendU32Hex_MaxSize 8
char* SkStrAppendU32Hex(char* dst, uint32_t value, int minDigits = 0);
#define SkStrAppendS32_MaxSize (SkStrAppendU32_MaxSize + 1)
char* SkStrAppendS32(char buffer[], int32_t);
#define SkStrAppendS64_MaxSize (SkStrAppendU64_MaxSize + 1)

View File

@ -63,45 +63,9 @@ bool SkStream::readPackedUInt(size_t* i) {
//////////////////////////////////////////////////////////////////////////////////////
SkWStream::~SkWStream()
{
}
SkWStream::~SkWStream() {}
void SkWStream::flush()
{
}
bool SkWStream::writeDecAsText(int32_t dec)
{
char buffer[SkStrAppendS32_MaxSize];
char* stop = SkStrAppendS32(buffer, dec);
return this->write(buffer, stop - buffer);
}
bool SkWStream::writeBigDecAsText(int64_t dec, int minDigits)
{
char buffer[SkStrAppendU64_MaxSize];
char* stop = SkStrAppendU64(buffer, dec, minDigits);
return this->write(buffer, stop - buffer);
}
bool SkWStream::writeHexAsText(uint32_t hex, int digits)
{
SkString tmp;
tmp.appendHex(hex, digits);
return this->write(tmp.c_str(), tmp.size());
}
bool SkWStream::writeScalarAsText(SkScalar value)
{
char buffer[SkStrAppendScalar_MaxSize];
char* stop = SkStrAppendScalar(buffer, value);
return this->write(buffer, stop - buffer);
}
bool SkWStream::writeScalar(SkScalar value) {
return this->write(&value, sizeof(value));
}
void SkWStream::flush() {}
int SkWStream::SizeOfPackedUInt(size_t value) {
if (value <= SK_MAX_BYTE_FOR_U8) {

View File

@ -9,10 +9,10 @@
#define SkStreamPriv_DEFINED
#include "SkRefCnt.h"
#include "SkString.h"
#include "SkStream.h"
class SkData;
class SkStream;
class SkWStream;
/**
* Copy the provided stream to an SkData variable.
@ -31,4 +31,30 @@ sk_sp<SkData> SkCopyStreamToData(SkStream* stream);
*/
bool SkStreamCopy(SkWStream* out, SkStream* input);
static inline bool SkWStreamWriteDecAsText(SkWStream* out, int32_t dec) {
char buffer[SkStrAppendS32_MaxSize];
return out->write(buffer, SkStrAppendS32(buffer, dec) - buffer);
}
static inline bool SkWStreamWriteBigDecAsText(SkWStream* out, int64_t dec, int minDigits = 0) {
char buffer[SkStrAppendU64_MaxSize];
return out->write(buffer, SkStrAppendU64(buffer, dec, minDigits) - buffer);
}
static inline bool SkWStreamWriteHexAsText(SkWStream* out, uint32_t hex, int minDigits = 0) {
char buffer[SkStrAppendU32Hex_MaxSize];
return out->write(buffer, SkStrAppendU32Hex(buffer, hex, minDigits) - buffer);
}
static inline bool SkWStreamWriteScalarAsText(SkWStream* out, SkScalar value) {
char buffer[SkStrAppendScalar_MaxSize];
return out->write(buffer, SkStrAppendScalar(buffer, value) - buffer);
}
static inline bool SkWStreamWriteScalar(SkWStream* out, SkScalar value) {
return out->write(&value, sizeof(value));
}
static inline bool SkWStreamWriteBool(SkWStream* out, bool v) { return out->write8(v); }
#endif // SkStreamPriv_DEFINED

View File

@ -120,6 +120,24 @@ char* SkStrAppendU32(char string[], uint32_t dec) {
return string;
}
char* SkStrAppendU32Hex(char* dst, uint32_t value, int minDigits) {
int digits = SkTClamp<int>(minDigits, 1, 8);
int optional = 8 - digits;
unsigned nibble = value >> 28; // 28 = 32 - 4
while (optional > 0 && nibble == 0) {
--optional;
nibble = (value <<= 4) >> 28;
}
digits += optional;
while (true) {
*dst++ = SkHexadecimalDigits::gUpper[nibble];
if (--digits == 0) {
return dst;
}
nibble = (value <<= 4) >> 28;
}
}
char* SkStrAppendS32(char string[], int32_t dec) {
uint32_t udec = dec;
if (dec < 0) {
@ -130,6 +148,7 @@ char* SkStrAppendS32(char string[], int32_t dec) {
}
char* SkStrAppendU64(char string[], uint64_t dec, int minDigits) {
minDigits = SkTClamp<int>(minDigits, 1, SkStrAppendU64_MaxSize);
SkDEBUGCODE(char* start = string;)
char buffer[SkStrAppendU64_MaxSize];
@ -479,23 +498,9 @@ void SkString::insertU64(size_t offset, uint64_t dec, int minDigits) {
}
void SkString::insertHex(size_t offset, uint32_t hex, int minDigits) {
minDigits = SkTPin(minDigits, 0, 8);
char buffer[8];
char* p = buffer + sizeof(buffer);
do {
*--p = SkHexadecimalDigits::gUpper[hex & 0xF];
hex >>= 4;
minDigits -= 1;
} while (hex != 0);
while (--minDigits >= 0) {
*--p = '0';
}
SkASSERT(p >= buffer);
this->insert(offset, p, buffer + sizeof(buffer) - p);
char buffer[SkStrAppendU32Hex_MaxSize];
char* stop = SkStrAppendU32Hex(buffer, hex, minDigits);
this->insert(offset, buffer, stop - buffer);
}
void SkString::insertScalar(size_t offset, SkScalar value) {

View File

@ -41,6 +41,7 @@
#include "SkRasterClip.h"
#include "SkScopeExit.h"
#include "SkString.h"
#include "SkStreamPriv.h"
#include "SkSurface.h"
#include "SkTemplates.h"
#include "SkTextBlob.h"
@ -436,7 +437,7 @@ void GraphicStackState::updateDrawingState(const SkPDFDevice::GraphicStateEntry&
static_assert(SkPaint::kFill_Style == 0, "enum_must_match_value");
static_assert(SkPaint::kStroke_Style == 1, "enum_must_match_value");
static_assert(SkPaint::kStrokeAndFill_Style == 2, "enum_must_match_value");
fContentStream->writeDecAsText(state.fTextFill);
SkWStreamWriteDecAsText(fContentStream, state.fTextFill);
fContentStream->writeText(" Tr\n");
currentEntry()->fTextFill = state.fTextFill;
}
@ -1106,7 +1107,7 @@ static void update_font(SkWStream* wStream, int fontIndex, SkScalar textSize) {
wStream->writeText("/");
char prefix = SkPDFResourceDict::GetResourceTypePrefix(SkPDFResourceDict::kFont_ResourceType);
wStream->write(&prefix, 1);
wStream->writeDecAsText(fontIndex);
SkWStreamWriteDecAsText(wStream, fontIndex);
wStream->writeText(" ");
SkPDFUtils::AppendScalar(textSize, wStream);
wStream->writeText(" Tf\n");

View File

@ -13,6 +13,7 @@
#include "SkPDFDevice.h"
#include "SkPDFUtils.h"
#include "SkStream.h"
#include "SkStreamPriv.h"
#include "SkTo.h"
SkPDFObjectSerializer::SkPDFObjectSerializer() : fBaseOffset(0), fNextToBeSerialized(0) {}
@ -64,7 +65,7 @@ void SkPDFObjectSerializer::serializeObjects(SkWStream* wStream) {
// the head of the linked list of free objects."
SkASSERT(fOffsets.size() == fNextToBeSerialized);
fOffsets.push_back(this->offset(wStream));
wStream->writeDecAsText(index);
SkWStreamWriteDecAsText(wStream, index);
wStream->writeText(" 0 obj\n"); // Generation number is always 0.
object->emitObject(wStream, fObjNumMap);
wStream->writeText("\nendobj\n");
@ -82,10 +83,10 @@ void SkPDFObjectSerializer::serializeFooter(SkWStream* wStream,
// Include the special zeroth object in the count.
int32_t objCount = SkToS32(fOffsets.size() + 1);
wStream->writeText("xref\n0 ");
wStream->writeDecAsText(objCount);
SkWStreamWriteDecAsText(wStream, objCount);
wStream->writeText("\n0000000000 65535 f \n");
for (size_t i = 0; i < fOffsets.size(); i++) {
wStream->writeBigDecAsText(fOffsets[i], 10);
SkWStreamWriteBigDecAsText(wStream, fOffsets[i], 10);
wStream->writeText(" 00000 n \n");
}
SkPDFDict trailerDict;
@ -100,7 +101,7 @@ void SkPDFObjectSerializer::serializeFooter(SkWStream* wStream,
wStream->writeText("trailer\n");
trailerDict.emitObject(wStream, fObjNumMap);
wStream->writeText("\nstartxref\n");
wStream->writeBigDecAsText(xRefFileOffset);
SkWStreamWriteBigDecAsText(wStream, xRefFileOffset);
wStream->writeText("\n%%EOF");
}

View File

@ -21,6 +21,7 @@
#include "SkRefCnt.h"
#include "SkScalar.h"
#include "SkStream.h"
#include "SkStreamPriv.h"
#include "SkTo.h"
#include "SkTypes.h"
#include "SkUTF.h"
@ -98,13 +99,13 @@ void setGlyphWidthAndBoundingBox(SkScalar width, SkIRect box,
// Specify width and bounding box for the glyph.
SkPDFUtils::AppendScalar(width, content);
content->writeText(" 0 ");
content->writeDecAsText(box.fLeft);
SkWStreamWriteDecAsText(content, box.fLeft);
content->writeText(" ");
content->writeDecAsText(box.fTop);
SkWStreamWriteDecAsText(content, box.fTop);
content->writeText(" ");
content->writeDecAsText(box.fRight);
SkWStreamWriteDecAsText(content, box.fRight);
content->writeText(" ");
content->writeDecAsText(box.fBottom);
SkWStreamWriteDecAsText(content, box.fBottom);
content->writeText(" d1\n");
}

View File

@ -8,6 +8,7 @@
#include "SkPDFMakeToUnicodeCmap.h"
#include "SkPDFUtils.h"
#include "SkStreamPriv.h"
#include "SkTo.h"
#include "SkUTF.h"
@ -88,7 +89,7 @@ static void append_bfchar_section(const std::vector<BFChar>& bfchar,
for (size_t i = 0; i < bfchar.size(); i += 100) {
int count = SkToInt(bfchar.size() - i);
count = SkMin32(count, 100);
cmap->writeDecAsText(count);
SkWStreamWriteDecAsText(cmap, count);
cmap->writeText(" beginbfchar\n");
for (int j = 0; j < count; ++j) {
cmap->writeText("<");
@ -108,7 +109,7 @@ static void append_bfrange_section(const std::vector<BFRange>& bfrange,
for (size_t i = 0; i < bfrange.size(); i += 100) {
int count = SkToInt(bfrange.size() - i);
count = SkMin32(count, 100);
cmap->writeDecAsText(count);
SkWStreamWriteDecAsText(cmap, count);
cmap->writeText(" beginbfrange\n");
for (int j = 0; j < count; ++j) {
cmap->writeText("<");

View File

@ -116,7 +116,7 @@ void SkPDFUnion::emitObject(SkWStream* stream,
const SkPDFObjNumMap& objNumMap) const {
switch (fType) {
case Type::kInt:
stream->writeDecAsText(fIntValue);
SkWStreamWriteDecAsText(stream, fIntValue);
return;
case Type::kColorComponent:
SkPDFUtils::AppendColorComponent(SkToU8(fIntValue), stream);
@ -145,7 +145,7 @@ void SkPDFUnion::emitObject(SkWStream* stream,
SkPDFUtils::WriteString(stream, fSkString.get().c_str(), fSkString.get().size());
return;
case Type::kObjRef:
stream->writeDecAsText(objNumMap.getObjectNumber(fObject));
SkWStreamWriteDecAsText(stream, objNumMap.getObjectNumber(fObject));
stream->writeText(" 0 R"); // Generation number is always 0.
return;
case Type::kObject:

View File

@ -9,6 +9,7 @@
#include "SkMalloc.h"
#include "SkStream.h"
#include "SkStreamPriv.h"
#include "SkString.h"
#include <cmath>
@ -777,7 +778,7 @@ void Write(const Value& v, SkWStream* stream) {
stream->writeText(*v.as<BoolValue>() ? "true" : "false");
break;
case Value::Type::kNumber:
stream->writeScalarAsText(*v.as<NumberValue>());
SkWStreamWriteScalarAsText(stream, *v.as<NumberValue>());
break;
case Value::Type::kString:
stream->writeText("\"");

View File

@ -7,13 +7,15 @@
#include "Test.h"
#include "SkRandom.h"
#include "SkString.h"
#include "SkStringUtils.h"
#include <cinttypes>
#include <stdarg.h>
#include <stdio.h>
#include <thread>
#include "SkString.h"
#include "SkStringUtils.h"
static const char* gThirtyWideDecimal = "%30d";
DEF_TEST(String, reporter) {
@ -115,9 +117,11 @@ DEF_TEST(String, reporter) {
a.set("");
a.appendS64(0x0000000001000000LL, 15);
REPORTER_ASSERT(reporter, a.equals("000000016777216"));
REPORTER_ASSERT(reporter, a.size() == 15);
a.set("");
a.appendS64(0xFFFFFFFFFF000000LL, 15);
REPORTER_ASSERT(reporter, a.equals("-000000016777216"));
REPORTER_ASSERT(reporter, a.size() == 16);
a.set("");
a.appendU64(0x7FFFFFFFFFFFFFFFULL, 0);
@ -335,3 +339,61 @@ DEF_TEST(String_fromUTF16, r) {
REPORTER_ASSERT(r, SkStringFromUTF16(test3, SK_ARRAY_COUNT(test3)).equals("αβγδε ζηθικ"));
}
template <size_t SIZE, typename T, typename U>
void str_append_test(skiatest::Reporter* rep,
SkRandom& rand,
U (SkRandom::*get)(),
char* (*fn)(char*, T),
const char* fmtString) {
T value = (rand.*get)();
char buffer[SIZE + 1];
char* p = fn(buffer, value);
REPORTER_ASSERT(rep, p < buffer + SK_ARRAY_COUNT(buffer));
*p = '\0';
char buffer2[SIZE + 1];
sprintf(buffer2, fmtString, value);
if (0 != strcmp(buffer, buffer2)) {
ERRORF(rep, "'%s' '%s'\n", buffer2, buffer);
}
}
template <size_t SIZE, typename T, typename U>
void str_append_test(skiatest::Reporter* rep,
SkRandom& rand,
U (SkRandom::*get)(),
char* (*fn)(char*, T, int),
const char* fmtString) {
T value = (rand.*get)();
int minDigits = rand.nextU() % (SIZE - 1) + 1;
char buffer[SIZE + 1];
char* p = fn(buffer, value, minDigits);
REPORTER_ASSERT(rep, p < buffer + SK_ARRAY_COUNT(buffer));
*p = '\0';
char buffer2[SIZE + 1];
if (value < 0) {
++minDigits;
}
sprintf(buffer2, fmtString, minDigits, value);
if (0 != strcmp(buffer, buffer2)) {
ERRORF(rep, "'%s' '%s'\n", buffer2, buffer);
}
}
DEF_TEST(String_StrAppend, rep) {
SkRandom rand;
for (int i = 0; i < 100; ++i) {
str_append_test<SkStrAppendU32_MaxSize>(
rep, rand, &SkRandom::nextU, SkStrAppendU32, "%u");
str_append_test<SkStrAppendS32_MaxSize>(
rep, rand, &SkRandom::nextS, SkStrAppendS32, "%d");
str_append_test<SkStrAppendScalar_MaxSize>(
rep, rand, &SkRandom::nextF, SkStrAppendFloat, "%.8g");
str_append_test<SkStrAppendU64_MaxSize>(
rep, rand, &SkRandom::next64, SkStrAppendU64, "%0*" PRIu64);
str_append_test<SkStrAppendS64_MaxSize>(
rep, rand, &SkRandom::next64, SkStrAppendS64, "%0*" PRId64);
str_append_test<SkStrAppendU32Hex_MaxSize>(
rep, rand, &SkRandom::nextU, SkStrAppendU32Hex, "%0*X");
}
}

View File

@ -38,6 +38,7 @@
#include "SkScalerContext.h"
#include "SkSize.h"
#include "SkStream.h"
#include "SkStreamPriv.h"
#include "SkSurface.h"
#include "SkTDArray.h"
#include "SkTemplates.h"
@ -306,16 +307,16 @@ void SkTestSVGTypeface::exportTtxCommon(SkWStream* out, const char* type,
out->writeText(" <GlyphOrder>\n");
for (int i = 0; i < fGlyphCount; ++i) {
out->writeText(" <GlyphID name=\"glyf");
out->writeHexAsText(i, 4);
SkWStreamWriteHexAsText(out, i, 4);
out->writeText("\"/>\n");
}
if (glyfInfo) {
for (int i = 0; i < fGlyphCount; ++i) {
for (int j = 0; j < (*glyfInfo)[i].fLayers.count(); ++j) {
out->writeText(" <GlyphID name=\"glyf");
out->writeHexAsText(i, 4);
SkWStreamWriteHexAsText(out, i, 4);
out->writeText("l");
out->writeHexAsText(j, 4);
SkWStreamWriteHexAsText(out, j, 4);
out->writeText("\"/>\n");
++totalGlyphs;
}
@ -330,22 +331,22 @@ void SkTestSVGTypeface::exportTtxCommon(SkWStream* out, const char* type,
out->writeText(" <magicNumber value=\"0x5f0f3cf5\"/>\n");
out->writeText(" <flags value=\"00000000 00011011\"/>\n");
out->writeText(" <unitsPerEm value=\"");
out->writeDecAsText(fUpem);
SkWStreamWriteDecAsText(out, fUpem);
out->writeText("\"/>\n");
out->writeText(" <created value=\"Thu Feb 15 12:55:49 2018\"/>\n");
out->writeText(" <modified value=\"Thu Feb 15 12:55:49 2018\"/>\n");
// TODO: not recalculated for bitmap fonts?
out->writeText(" <xMin value=\"");
out->writeScalarAsText(fFontMetrics.fXMin);
SkWStreamWriteScalarAsText(out, fFontMetrics.fXMin);
out->writeText("\"/>\n");
out->writeText(" <yMin value=\"");
out->writeScalarAsText(-fFontMetrics.fBottom);
SkWStreamWriteScalarAsText(out, -fFontMetrics.fBottom);
out->writeText("\"/>\n");
out->writeText(" <xMax value=\"");
out->writeScalarAsText(fFontMetrics.fXMax);
SkWStreamWriteScalarAsText(out, fFontMetrics.fXMax);
out->writeText("\"/>\n");
out->writeText(" <yMax value=\"");
out->writeScalarAsText(-fFontMetrics.fTop);
SkWStreamWriteScalarAsText(out, -fFontMetrics.fTop);
out->writeText("\"/>\n");
char macStyle[16] = {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
@ -383,19 +384,19 @@ void SkTestSVGTypeface::exportTtxCommon(SkWStream* out, const char* type,
out->writeText(" <hhea>\n");
out->writeText(" <tableVersion value=\"0x00010000\"/>\n");
out->writeText(" <ascent value=\"");
out->writeDecAsText(-fFontMetrics.fAscent);
SkWStreamWriteDecAsText(out, -fFontMetrics.fAscent);
out->writeText("\"/>\n");
out->writeText(" <descent value=\"");
out->writeDecAsText(-fFontMetrics.fDescent);
SkWStreamWriteDecAsText(out, -fFontMetrics.fDescent);
out->writeText("\"/>\n");
out->writeText(" <lineGap value=\"");
out->writeDecAsText(fFontMetrics.fLeading);
SkWStreamWriteDecAsText(out, fFontMetrics.fLeading);
out->writeText("\"/>\n");
out->writeText(" <advanceWidthMax value=\"0\"/>\n");
out->writeText(" <minLeftSideBearing value=\"0\"/>\n");
out->writeText(" <minRightSideBearing value=\"0\"/>\n");
out->writeText(" <xMaxExtent value=\"");
out->writeScalarAsText(fFontMetrics.fXMax - fFontMetrics.fXMin);
SkWStreamWriteScalarAsText(out, fFontMetrics.fXMax - fFontMetrics.fXMin);
out->writeText("\"/>\n");
out->writeText(" <caretSlopeRise value=\"1\"/>\n");
out->writeText(" <caretSlopeRun value=\"0\"/>\n");
@ -412,7 +413,7 @@ void SkTestSVGTypeface::exportTtxCommon(SkWStream* out, const char* type,
out->writeText(" <maxp>\n");
out->writeText(" <tableVersion value=\"0x10000\"/>\n");
out->writeText(" <numGlyphs value=\"");
out->writeDecAsText(totalGlyphs);
SkWStreamWriteDecAsText(out, totalGlyphs);
out->writeText("\"/>\n");
out->writeText(" <maxPoints value=\"4\"/>\n");
out->writeText(" <maxContours value=\"1\"/>\n");
@ -432,13 +433,13 @@ void SkTestSVGTypeface::exportTtxCommon(SkWStream* out, const char* type,
out->writeText(" <OS_2>\n");
out->writeText(" <version value=\"4\"/>\n");
out->writeText(" <xAvgCharWidth value=\"");
out->writeScalarAsText(fFontMetrics.fAvgCharWidth);
SkWStreamWriteScalarAsText(out, fFontMetrics.fAvgCharWidth);
out->writeText("\"/>\n");
out->writeText(" <usWeightClass value=\"");
out->writeDecAsText(this->fontStyle().weight());
SkWStreamWriteDecAsText(out, this->fontStyle().weight());
out->writeText("\"/>\n");
out->writeText(" <usWidthClass value=\"");
out->writeDecAsText(this->fontStyle().width());
SkWStreamWriteDecAsText(out, this->fontStyle().width());
out->writeText("\"/>\n");
out->writeText(" <fsType value=\"00000000 00000000\"/>\n");
out->writeText(" <ySubscriptXSize value=\"665\"/>\n");
@ -450,10 +451,10 @@ void SkTestSVGTypeface::exportTtxCommon(SkWStream* out, const char* type,
out->writeText(" <ySuperscriptXOffset value=\"0\"/>\n");
out->writeText(" <ySuperscriptYOffset value=\"491\"/>\n");
out->writeText(" <yStrikeoutSize value=\"");
out->writeScalarAsText(fFontMetrics.fStrikeoutThickness);
SkWStreamWriteScalarAsText(out, fFontMetrics.fStrikeoutThickness);
out->writeText("\"/>\n");
out->writeText(" <yStrikeoutPosition value=\"");
out->writeScalarAsText(-fFontMetrics.fStrikeoutPosition);
SkWStreamWriteScalarAsText(out, -fFontMetrics.fStrikeoutPosition);
out->writeText("\"/>\n");
out->writeText(" <sFamilyClass value=\"0\"/>\n");
out->writeText(" <panose>\n");
@ -502,27 +503,27 @@ void SkTestSVGTypeface::exportTtxCommon(SkWStream* out, const char* type,
out->writeText(" <usFirstCharIndex value=\"0\"/>\n");
out->writeText(" <usLastCharIndex value=\"0\"/>\n");
out->writeText(" <sTypoAscender value=\"");
out->writeScalarAsText(-fFontMetrics.fAscent);
SkWStreamWriteScalarAsText(out, -fFontMetrics.fAscent);
out->writeText("\"/>\n");
out->writeText(" <sTypoDescender value=\"");
out->writeScalarAsText(-fFontMetrics.fDescent);
SkWStreamWriteScalarAsText(out, -fFontMetrics.fDescent);
out->writeText("\"/>\n");
out->writeText(" <sTypoLineGap value=\"");
out->writeScalarAsText(fFontMetrics.fLeading);
SkWStreamWriteScalarAsText(out, fFontMetrics.fLeading);
out->writeText("\"/>\n");
out->writeText(" <usWinAscent value=\"");
out->writeScalarAsText(-fFontMetrics.fAscent);
SkWStreamWriteScalarAsText(out, -fFontMetrics.fAscent);
out->writeText("\"/>\n");
out->writeText(" <usWinDescent value=\"");
out->writeScalarAsText(fFontMetrics.fDescent);
SkWStreamWriteScalarAsText(out, fFontMetrics.fDescent);
out->writeText("\"/>\n");
out->writeText(" <ulCodePageRange1 value=\"00000000 00000000 00000000 00000000\"/>\n");
out->writeText(" <ulCodePageRange2 value=\"00000000 00000000 00000000 00000000\"/>\n");
out->writeText(" <sxHeight value=\"");
out->writeScalarAsText(fFontMetrics.fXHeight);
SkWStreamWriteScalarAsText(out, fFontMetrics.fXHeight);
out->writeText("\"/>\n");
out->writeText(" <sCapHeight value=\"");
out->writeScalarAsText(fFontMetrics.fCapHeight);
SkWStreamWriteScalarAsText(out, fFontMetrics.fCapHeight);
out->writeText("\"/>\n");
out->writeText(" <usDefaultChar value=\"0\"/>\n");
out->writeText(" <usBreakChar value=\"32\"/>\n");
@ -532,29 +533,29 @@ void SkTestSVGTypeface::exportTtxCommon(SkWStream* out, const char* type,
out->writeText(" <hmtx>\n");
for (int i = 0; i < fGlyphCount; ++i) {
out->writeText(" <mtx name=\"glyf");
out->writeHexAsText(i, 4);
SkWStreamWriteHexAsText(out, i, 4);
out->writeText("\" width=\"");
out->writeDecAsText(fGlyphs[i].fAdvance);
SkWStreamWriteDecAsText(out, fGlyphs[i].fAdvance);
out->writeText("\" lsb=\"");
int lsb = fGlyphs[i].fOrigin.fX;
if (glyfInfo) {
lsb += (*glyfInfo)[i].fBounds.fLeft;
}
out->writeDecAsText(lsb);
SkWStreamWriteDecAsText(out, lsb);
out->writeText("\"/>\n");
}
if (glyfInfo) {
for (int i = 0; i < fGlyphCount; ++i) {
for (int j = 0; j < (*glyfInfo)[i].fLayers.count(); ++j) {
out->writeText(" <mtx name=\"glyf");
out->writeHexAsText(i, 4);
SkWStreamWriteHexAsText(out, i, 4);
out->writeText("l");
out->writeHexAsText(j, 4);
SkWStreamWriteHexAsText(out, j, 4);
out->writeText("\" width=\"");
out->writeDecAsText(fGlyphs[i].fAdvance);
SkWStreamWriteDecAsText(out, fGlyphs[i].fAdvance);
out->writeText("\" lsb=\"");
int32_t lsb = fGlyphs[i].fOrigin.fX + (*glyfInfo)[i].fLayers[j].fBounds.fLeft;
out->writeDecAsText(lsb);
SkWStreamWriteDecAsText(out, lsb);
out->writeText("\"/>\n");
}
}
@ -571,9 +572,9 @@ void SkTestSVGTypeface::exportTtxCommon(SkWStream* out, const char* type,
return;
}
out->writeText(" <map code=\"0x");
out->writeHexAsText(c, 4);
SkWStreamWriteHexAsText(out, c, 4);
out->writeText("\" name=\"glyf");
out->writeHexAsText(g, 4);
SkWStreamWriteHexAsText(out, g, 4);
out->writeText("\"/>\n");
});
out->writeText(" </cmap_format_4>\n");
@ -581,9 +582,9 @@ void SkTestSVGTypeface::exportTtxCommon(SkWStream* out, const char* type,
out->writeText(" <cmap_format_12 platformID=\"3\" platEncID=\"10\" format=\"12\" reserved=\"0\" length=\"1\" language=\"0\" nGroups=\"0\">\n");
fCMap.foreach([&out](const SkUnichar& c, const SkGlyphID& g) {
out->writeText(" <map code=\"0x");
out->writeHexAsText(c, 6);
SkWStreamWriteHexAsText(out, c, 6);
out->writeText("\" name=\"glyf");
out->writeHexAsText(g, 4);
SkWStreamWriteHexAsText(out, g, 4);
out->writeText("\"/>\n");
});
out->writeText(" </cmap_format_12>\n");
@ -607,10 +608,10 @@ void SkTestSVGTypeface::exportTtxCommon(SkWStream* out, const char* type,
out->writeText(" <formatType value=\"3.0\"/>\n");
out->writeText(" <italicAngle value=\"0.0\"/>\n");
out->writeText(" <underlinePosition value=\"");
out->writeScalarAsText(fFontMetrics.fUnderlinePosition);
SkWStreamWriteScalarAsText(out, fFontMetrics.fUnderlinePosition);
out->writeText("\"/>\n");
out->writeText(" <underlineThickness value=\"");
out->writeScalarAsText(fFontMetrics.fUnderlineThickness);
SkWStreamWriteScalarAsText(out, fFontMetrics.fUnderlineThickness);
out->writeText("\"/>\n");
out->writeText(" <isFixedPitch value=\"0\"/>\n");
out->writeText(" <minMemType42 value=\"0\"/>\n");
@ -636,7 +637,7 @@ void SkTestSVGTypeface::exportTtxCbdt(SkWStream* out) const {
for (size_t strikeIndex = 0; strikeIndex < SK_ARRAY_COUNT(strikeSizes); ++strikeIndex) {
paint.setTextSize(strikeSizes[strikeIndex]);
out->writeText(" <strikedata index=\"");
out->writeDecAsText(strikeIndex);
SkWStreamWriteDecAsText(out, strikeIndex);
out->writeText("\">\n");
for (int i = 0; i < fGlyphCount; ++i) {
SkGlyphID gid = i;
@ -660,23 +661,23 @@ void SkTestSVGTypeface::exportTtxCbdt(SkWStream* out) const {
sk_sp<SkData> data = image->encodeToData(SkEncodedImageFormat::kPNG, 100);
out->writeText(" <cbdt_bitmap_format_17 name=\"glyf");
out->writeHexAsText(i, 4);
SkWStreamWriteHexAsText(out, i, 4);
out->writeText("\">\n");
out->writeText(" <SmallGlyphMetrics>\n");
out->writeText(" <height value=\"");
out->writeDecAsText(image->height());
SkWStreamWriteDecAsText(out, image->height());
out->writeText("\"/>\n");
out->writeText(" <width value=\"");
out->writeDecAsText(image->width());
SkWStreamWriteDecAsText(out, image->width());
out->writeText("\"/>\n");
out->writeText(" <BearingX value=\"");
out->writeDecAsText(bounds.fLeft);
SkWStreamWriteDecAsText(out, bounds.fLeft);
out->writeText("\"/>\n");
out->writeText(" <BearingY value=\"");
out->writeScalarAsText(-bounds.fTop);
SkWStreamWriteScalarAsText(out, -bounds.fTop);
out->writeText("\"/>\n");
out->writeText(" <Advance value=\"");
out->writeScalarAsText(advance);
SkWStreamWriteScalarAsText(out, advance);
out->writeText("\"/>\n");
out->writeText(" </SmallGlyphMetrics>\n");
out->writeText(" <rawimagedata>");
@ -687,7 +688,7 @@ void SkTestSVGTypeface::exportTtxCbdt(SkWStream* out) const {
} else if (((i - 1) % 0x4) == 0x3) {
out->writeText(" ");
}
out->writeHexAsText(bytes[i], 2);
SkWStreamWriteHexAsText(out, bytes[i], 2);
}
out->writeText("\n");
out->writeText(" </rawimagedata>\n");
@ -704,18 +705,18 @@ void SkTestSVGTypeface::exportTtxCbdt(SkWStream* out) const {
paint.setTextSize(strikeSizes[strikeIndex]);
paint.getFontMetrics(&fm);
out->writeText(" <strike index=\"");
out->writeDecAsText(strikeIndex);
SkWStreamWriteDecAsText(out, strikeIndex);
out->writeText("\">\n");
out->writeText(" <bitmapSizeTable>\n");
out->writeText(" <sbitLineMetrics direction=\"hori\">\n");
out->writeText(" <ascender value=\"");
out->writeScalarAsText(-fm.fTop);
SkWStreamWriteScalarAsText(out, -fm.fTop);
out->writeText("\"/>\n");
out->writeText(" <descender value=\"");
out->writeScalarAsText(-fm.fBottom);
SkWStreamWriteScalarAsText(out, -fm.fBottom);
out->writeText("\"/>\n");
out->writeText(" <widthMax value=\"");
out->writeScalarAsText(fm.fXMax - fm.fXMin);
SkWStreamWriteScalarAsText(out, fm.fXMax - fm.fXMin);
out->writeText("\"/>\n");
out->writeText(" <caretSlopeNumerator value=\"0\"/>\n");
out->writeText(" <caretSlopeDenominator value=\"0\"/>\n");
@ -729,13 +730,13 @@ void SkTestSVGTypeface::exportTtxCbdt(SkWStream* out) const {
out->writeText(" </sbitLineMetrics>\n");
out->writeText(" <sbitLineMetrics direction=\"vert\">\n");
out->writeText(" <ascender value=\"");
out->writeScalarAsText(-fm.fTop);
SkWStreamWriteScalarAsText(out, -fm.fTop);
out->writeText("\"/>\n");
out->writeText(" <descender value=\"");
out->writeScalarAsText(-fm.fBottom);
SkWStreamWriteScalarAsText(out, -fm.fBottom);
out->writeText("\"/>\n");
out->writeText(" <widthMax value=\"");
out->writeScalarAsText(fm.fXMax - fm.fXMin);
SkWStreamWriteScalarAsText(out, fm.fXMax - fm.fXMin);
out->writeText("\"/>\n");
out->writeText(" <caretSlopeNumerator value=\"0\"/>\n");
out->writeText(" <caretSlopeDenominator value=\"0\"/>\n");
@ -751,10 +752,10 @@ void SkTestSVGTypeface::exportTtxCbdt(SkWStream* out) const {
out->writeText(" <startGlyphIndex value=\"1\"/>\n");
out->writeText(" <endGlyphIndex value=\"1\"/>\n");
out->writeText(" <ppemX value=\"");
out->writeDecAsText(strikeSizes[strikeIndex]);
SkWStreamWriteDecAsText(out, strikeSizes[strikeIndex]);
out->writeText("\"/>\n");
out->writeText(" <ppemY value=\"");
out->writeDecAsText(strikeSizes[strikeIndex]);
SkWStreamWriteDecAsText(out, strikeSizes[strikeIndex]);
out->writeText("\"/>\n");
out->writeText(" <bitDepth value=\"32\"/>\n");
out->writeText(" <flags value=\"1\"/>\n");
@ -768,7 +769,7 @@ void SkTestSVGTypeface::exportTtxCbdt(SkWStream* out) const {
continue;
}
out->writeText(" <glyphLoc name=\"glyf");
out->writeHexAsText(i, 4);
SkWStreamWriteHexAsText(out, i, 4);
out->writeText("\"/>\n");
}
out->writeText(" </eblc_index_sub_table_1>\n");
@ -809,28 +810,28 @@ void SkTestSVGTypeface::exportTtxSbix(SkWStream* out) const {
containerSize.fWidth, containerSize.fHeight);
SkIRect ibounds = bounds.roundOut();
out->writeText(" <TTGlyph name=\"glyf");
out->writeHexAsText(i, 4);
SkWStreamWriteHexAsText(out, i, 4);
out->writeText("\" xMin=\"");
out->writeDecAsText(ibounds.fLeft);
SkWStreamWriteDecAsText(out, ibounds.fLeft);
out->writeText("\" yMin=\"");
out->writeDecAsText(-ibounds.fBottom);
SkWStreamWriteDecAsText(out, -ibounds.fBottom);
out->writeText("\" xMax=\"");
out->writeDecAsText(ibounds.fRight);
SkWStreamWriteDecAsText(out, ibounds.fRight);
out->writeText("\" yMax=\"");
out->writeDecAsText(-ibounds.fTop);
SkWStreamWriteDecAsText(out, -ibounds.fTop);
out->writeText("\">\n");
out->writeText(" <contour>\n");
out->writeText(" <pt x=\"");
out->writeDecAsText(ibounds.fLeft);
SkWStreamWriteDecAsText(out, ibounds.fLeft);
out->writeText("\" y=\"");
out->writeDecAsText(-ibounds.fBottom);
SkWStreamWriteDecAsText(out, -ibounds.fBottom);
out->writeText("\" on=\"1\"/>\n");
out->writeText(" </contour>\n");
out->writeText(" <contour>\n");
out->writeText(" <pt x=\"");
out->writeDecAsText(ibounds.fRight);
SkWStreamWriteDecAsText(out, ibounds.fRight);
out->writeText("\" y=\"");
out->writeDecAsText(-ibounds.fTop);
SkWStreamWriteDecAsText(out, -ibounds.fTop);
out->writeText("\" on=\"1\"/>\n");
out->writeText(" </contour>\n");
out->writeText(" <instructions/>\n");
@ -850,7 +851,7 @@ void SkTestSVGTypeface::exportTtxSbix(SkWStream* out) const {
paint.setTextSize(strikeSizes[strikeIndex]);
out->writeText(" <strike>\n");
out->writeText(" <ppem value=\"");
out->writeDecAsText(strikeSizes[strikeIndex]);
SkWStreamWriteDecAsText(out, strikeSizes[strikeIndex]);
out->writeText("\"/>\n");
out->writeText(" <resolution value=\"72\"/>\n");
for (int i = 0; i < fGlyphCount; ++i) {
@ -875,11 +876,11 @@ void SkTestSVGTypeface::exportTtxSbix(SkWStream* out) const {
sk_sp<SkData> data = image->encodeToData(SkEncodedImageFormat::kPNG, 100);
out->writeText(" <glyph name=\"glyf");
out->writeHexAsText(i, 4);
SkWStreamWriteHexAsText(out, i, 4);
out->writeText("\" graphicType=\"png \" originOffsetX=\"");
out->writeDecAsText(bounds.fLeft);
SkWStreamWriteDecAsText(out, bounds.fLeft);
out->writeText("\" originOffsetY=\"");
out->writeScalarAsText(bounds.fBottom);
SkWStreamWriteScalarAsText(out, bounds.fBottom);
out->writeText("\">\n");
out->writeText(" <hexdata>");
@ -890,7 +891,7 @@ void SkTestSVGTypeface::exportTtxSbix(SkWStream* out) const {
} else if (((i - 1) % 0x4) == 0x3) {
out->writeText(" ");
}
out->writeHexAsText(bytes[i], 2);
SkWStreamWriteHexAsText(out, bytes[i], 2);
}
out->writeText("\n");
out->writeText(" </hexdata>\n");
@ -1033,9 +1034,9 @@ public:
void writePoint(SkScalar x, SkScalar y, bool on) {
fOut->writeText(" <pt x=\"");
fOut->writeDecAsText(SkScalarRoundToInt(x));
SkWStreamWriteDecAsText(fOut, SkScalarRoundToInt(x));
fOut->writeText("\" y=\"");
fOut->writeDecAsText(SkScalarRoundToInt(y));
SkWStreamWriteDecAsText(fOut, SkScalarRoundToInt(y));
fOut->writeText("\" on=\"");
fOut->write8(on ? '1' : '0');
fOut->writeText("\"/>\n");
@ -1049,19 +1050,19 @@ public:
SkIRect ibounds = bounds.roundOut();
// The bounds will be re-calculated anyway.
fOut->writeText(" <TTGlyph name=\"glyf");
fOut->writeHexAsText(fGlyphId, 4);
SkWStreamWriteHexAsText(fOut, fGlyphId, 4);
if (layer) {
fOut->writeText("l");
fOut->writeHexAsText(fLayerId, 4);
SkWStreamWriteHexAsText(fOut, fLayerId, 4);
}
fOut->writeText("\" xMin=\"");
fOut->writeDecAsText(ibounds.fLeft);
SkWStreamWriteDecAsText(fOut, ibounds.fLeft);
fOut->writeText("\" yMin=\"");
fOut->writeDecAsText(ibounds.fTop);
SkWStreamWriteDecAsText(fOut, ibounds.fTop);
fOut->writeText("\" xMax=\"");
fOut->writeDecAsText(ibounds.fRight);
SkWStreamWriteDecAsText(fOut, ibounds.fRight);
fOut->writeText("\" yMax=\"");
fOut->writeDecAsText(ibounds.fBottom);
SkWStreamWriteDecAsText(fOut, ibounds.fBottom);
fOut->writeText("\">\n");
SkPath::RawIter iter(quads);
@ -1257,16 +1258,16 @@ void SkTestSVGTypeface::exportTtxColr(SkWStream* out) const {
continue;
}
out->writeText(" <ColorGlyph name=\"glyf");
out->writeHexAsText(i, 4);
SkWStreamWriteHexAsText(out, i, 4);
out->writeText("\">\n");
for (int j = 0; j < glyfInfos[i].fLayers.count(); ++j) {
const int colorIndex = glyfInfos[i].fLayers[j].fLayerColorIndex;
out->writeText(" <layer colorID=\"");
out->writeDecAsText(colorIndex);
SkWStreamWriteDecAsText(out, colorIndex);
out->writeText("\" name=\"glyf");
out->writeHexAsText(i, 4);
SkWStreamWriteHexAsText(out, i, 4);
out->writeText("l");
out->writeHexAsText(j, 4);
SkWStreamWriteHexAsText(out, j, 4);
out->writeText("\"/>\n");
}
out->writeText(" </ColorGlyph>\n");
@ -1281,18 +1282,18 @@ void SkTestSVGTypeface::exportTtxColr(SkWStream* out) const {
out->writeText(" <CPAL>\n");
out->writeText(" <version value=\"0\"/>\n");
out->writeText(" <numPaletteEntries value=\"");
out->writeDecAsText(colors.count());
SkWStreamWriteDecAsText(out, colors.count());
out->writeText("\"/>\n");
out->writeText(" <palette index=\"0\">\n");
for (int i = 0; i < colors.count(); ++i) {
SkColor c = colorsInOrder[i];
out->writeText(" <color index=\"");
out->writeDecAsText(i);
SkWStreamWriteDecAsText(out, i);
out->writeText("\" value=\"#");
out->writeHexAsText(SkColorGetR(c), 2);
out->writeHexAsText(SkColorGetG(c), 2);
out->writeHexAsText(SkColorGetB(c), 2);
out->writeHexAsText(SkColorGetA(c), 2);
SkWStreamWriteHexAsText(out, SkColorGetR(c), 2);
SkWStreamWriteHexAsText(out, SkColorGetG(c), 2);
SkWStreamWriteHexAsText(out, SkColorGetB(c), 2);
SkWStreamWriteHexAsText(out, SkColorGetA(c), 2);
out->writeText("\"/>\n");
}
out->writeText(" </palette>\n");

View File

@ -8,6 +8,7 @@
#include "skdiff.h"
#include "skdiff_html.h"
#include "SkStream.h"
#include "SkStreamPriv.h"
#include "SkTime.h"
/// Make layout more consistent by scaling image to 240 height, 360 width,
@ -39,28 +40,28 @@ static void print_table_header(SkFILEWStream* stream,
SkTime::DateTime dt;
SkTime::GetDateTime(&dt);
stream->writeText("SkDiff run at ");
stream->writeDecAsText(dt.fHour);
SkWStreamWriteDecAsText(stream, dt.fHour);
stream->writeText(":");
if (dt.fMinute < 10) {
stream->writeText("0");
}
stream->writeDecAsText(dt.fMinute);
SkWStreamWriteDecAsText(stream, dt.fMinute);
stream->writeText(":");
if (dt.fSecond < 10) {
stream->writeText("0");
}
stream->writeDecAsText(dt.fSecond);
SkWStreamWriteDecAsText(stream, dt.fSecond);
stream->writeText("<br>");
}
stream->writeDecAsText(matchCount);
SkWStreamWriteDecAsText(stream, matchCount);
stream->writeText(" of ");
stream->writeDecAsText(differences.count());
SkWStreamWriteDecAsText(stream, differences.count());
stream->writeText(" diffs matched ");
if (colorThreshold == 0) {
stream->writeText("exactly");
} else {
stream->writeText("within ");
stream->writeDecAsText(colorThreshold);
SkWStreamWriteDecAsText(stream, colorThreshold);
stream->writeText(" color units per component");
}
stream->writeText(".<br>");
@ -78,12 +79,12 @@ static void print_table_header(SkFILEWStream* stream,
static void print_pixel_count(SkFILEWStream* stream, const DiffRecord& diff) {
stream->writeText("<br>(");
stream->writeDecAsText(static_cast<int>(diff.fFractionDifference *
SkWStreamWriteDecAsText(stream, static_cast<int>(diff.fFractionDifference *
diff.fBase.fBitmap.width() *
diff.fBase.fBitmap.height()));
stream->writeText(" pixels)");
/*
stream->writeDecAsText(diff.fWeightedFraction *
SkWStreamWriteDecAsText(stream, diff.fWeightedFraction *
diff.fBaseWidth *
diff.fBaseHeight);
stream->writeText(" weighted pixels)");
@ -127,22 +128,22 @@ static void print_label_cell(SkFILEWStream* stream, const DiffRecord& diff) {
stream->writeText("<br>");
if (SkScalarRoundToInt(diff.fAverageMismatchA) > 0) {
stream->writeText("<br>Average alpha channel mismatch ");
stream->writeDecAsText(SkScalarRoundToInt(diff.fAverageMismatchA));
SkWStreamWriteDecAsText(stream, SkScalarRoundToInt(diff.fAverageMismatchA));
}
stream->writeText("<br>Max alpha channel mismatch ");
stream->writeDecAsText(SkScalarRoundToInt(diff.fMaxMismatchA));
SkWStreamWriteDecAsText(stream, SkScalarRoundToInt(diff.fMaxMismatchA));
stream->writeText("<br>Total alpha channel mismatch ");
stream->writeDecAsText(static_cast<int>(diff.fTotalMismatchA));
SkWStreamWriteDecAsText(stream, static_cast<int>(diff.fTotalMismatchA));
stream->writeText("<br>");
stream->writeText("<br>Average color mismatch ");
stream->writeDecAsText(SkScalarRoundToInt(MAX3(diff.fAverageMismatchR,
SkWStreamWriteDecAsText(stream, SkScalarRoundToInt(MAX3(diff.fAverageMismatchR,
diff.fAverageMismatchG,
diff.fAverageMismatchB)));
stream->writeText("<br>Max color mismatch ");
stream->writeDecAsText(MAX3(diff.fMaxMismatchR,
SkWStreamWriteDecAsText(stream, MAX3(diff.fMaxMismatchR,
diff.fMaxMismatchG,
diff.fMaxMismatchB));
stream->writeText("</td>");
@ -166,7 +167,7 @@ static void print_image_cell(SkFILEWStream* stream, const SkString& path, int he
stream->writeText("\"><img src=\"");
stream->writeText(path.c_str());
stream->writeText("\" height=\"");
stream->writeDecAsText(height);
SkWStreamWriteDecAsText(stream, height);
stream->writeText("px\"></a></td>");
}