Revert "Revert "serialize fonts instead of paints""
This reverts commit 576633cf57cf05761f950ac503cec01b03b1e75b.
Fix: add new version to both variants of SkReadBuffer
Bug: skia:
Change-Id: I8ba60d374860718402328398a4a09b8c97d65e33
Reviewed-on: https://skia-review.googlesource.com/c/179845
Commit-Queue: Mike Reed <reed@google.com>
Auto-Submit: Mike Reed <reed@google.com>
Reviewed-by: Mike Reed <reed@google.com>
diff --git a/include/core/SkFont.h b/include/core/SkFont.h
index 68f9824..5f3c27a 100644
--- a/include/core/SkFont.h
+++ b/include/core/SkFont.h
@@ -495,7 +495,7 @@
kEmbolden_PrivFlag = 1 << 4,
};
- static constexpr unsigned kAllFlags = 0x07F;
+ static constexpr unsigned kAllFlags = 0x1F;
sk_sp<SkTypeface> fTypeface;
SkScalar fSize;
diff --git a/include/core/SkPicture.h b/include/core/SkPicture.h
index 70f26f2..9e29197 100644
--- a/include/core/SkPicture.h
+++ b/include/core/SkPicture.h
@@ -265,10 +265,11 @@
// V64: Remove occluder feature from blur maskFilter
// V65: Float4 paint color
// V66: Add saveBehind
+ // V67: Blobs serialize fonts instead of paints
// Only SKPs within the min/current picture version range (inclusive) can be read.
static const uint32_t MIN_PICTURE_VERSION = 56; // august 2017
- static const uint32_t CURRENT_PICTURE_VERSION = 66;
+ static const uint32_t CURRENT_PICTURE_VERSION = 67;
static_assert(MIN_PICTURE_VERSION <= 62, "Remove kFontAxes_bad from SkFontDescriptor.cpp");
diff --git a/src/core/SkFont.cpp b/src/core/SkFont.cpp
index 56a6bc5..956f832 100644
--- a/src/core/SkFont.cpp
+++ b/src/core/SkFont.cpp
@@ -585,3 +585,111 @@
SkUnichar uni[]) {
font.glyphsToUnichars(glyphs, count, uni);
}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+#include "SkReadBuffer.h"
+#include "SkWriteBuffer.h"
+
+// packed int at the beginning of the serialized font:
+//
+// control_bits:8 size_as_byte:8 flags:12 edging:2 hinting:2
+
+enum {
+ kSize_Is_Byte_Bit = 1 << 31,
+ kHas_ScaleX_Bit = 1 << 30,
+ kHas_SkewX_Bit = 1 << 29,
+ kHas_Typeface_Bit = 1 << 28,
+
+ kShift_for_Size = 16,
+ kMask_For_Size = 0xFF,
+
+ kShift_For_Flags = 4,
+ kMask_For_Flags = 0xFFF,
+
+ kShift_For_Edging = 2,
+ kMask_For_Edging = 0x3,
+
+ kShift_For_Hinting = 0,
+ kMask_For_Hinting = 0x3
+};
+
+static bool scalar_is_byte(SkScalar x) {
+ int ix = (int)x;
+ return ix == x && ix >= 0 && ix <= kMask_For_Size;
+}
+
+void SkFontPriv::Flatten(const SkFont& font, SkWriteBuffer& buffer) {
+ SkASSERT((font.fFlags & ~kMask_For_Flags) == 0);
+ SkASSERT((font.fEdging & ~kMask_For_Edging) == 0);
+ SkASSERT((font.fHinting & ~kMask_For_Hinting) == 0);
+
+ uint32_t packed = 0;
+ packed |= font.fFlags << kShift_For_Flags;
+ packed |= font.fEdging << kShift_For_Edging;
+ packed |= font.fHinting << kShift_For_Hinting;
+
+ if (scalar_is_byte(font.fSize)) {
+ packed |= kSize_Is_Byte_Bit;
+ packed |= (int)font.fSize << kShift_for_Size;
+ }
+ if (font.fScaleX != 1) {
+ packed |= kHas_ScaleX_Bit;
+ }
+ if (font.fSkewX != 0) {
+ packed |= kHas_SkewX_Bit;
+ }
+ if (font.fTypeface) {
+ packed |= kHas_Typeface_Bit;
+ }
+
+ buffer.write32(packed);
+ if (!(packed & kSize_Is_Byte_Bit)) {
+ buffer.writeScalar(font.fSize);
+ }
+ if (packed & kHas_ScaleX_Bit) {
+ buffer.writeScalar(font.fScaleX);
+ }
+ if (packed & kHas_SkewX_Bit) {
+ buffer.writeScalar(font.fSkewX);
+ }
+ if (packed & kHas_Typeface_Bit) {
+ buffer.writeTypeface(font.fTypeface.get());
+ }
+}
+
+bool SkFontPriv::Unflatten(SkFont* font, SkReadBuffer& buffer) {
+ const uint32_t packed = buffer.read32();
+
+ if (packed & kSize_Is_Byte_Bit) {
+ font->fSize = (packed >> kShift_for_Size) & kMask_For_Size;
+ } else {
+ font->fSize = buffer.readScalar();
+ }
+ if (packed & kHas_ScaleX_Bit) {
+ font->fScaleX = buffer.readScalar();
+ }
+ if (packed & kHas_SkewX_Bit) {
+ font->fSkewX = buffer.readScalar();
+ }
+ if (packed & kHas_Typeface_Bit) {
+ font->fTypeface = buffer.readTypeface();
+ }
+
+ SkASSERT(SkFont::kAllFlags <= kMask_For_Flags);
+ // we & with kAllFlags, to clear out any unknown flag bits
+ font->fFlags = SkToU8((packed >> kShift_For_Flags) & SkFont::kAllFlags);
+
+ unsigned edging = (packed >> kShift_For_Edging) & kMask_For_Edging;
+ if (edging > (unsigned)SkFont::Edging::kSubpixelAntiAlias) {
+ edging = 0;
+ }
+ font->fEdging = SkToU8(edging);
+
+ unsigned hinting = (packed >> kShift_For_Hinting) & kMask_For_Hinting;
+ if (hinting > (unsigned)kFull_SkFontHinting) {
+ hinting = 0;
+ }
+ font->fHinting = SkToU8(hinting);
+
+ return buffer.isValid();
+}
diff --git a/src/core/SkFontPriv.h b/src/core/SkFontPriv.h
index 6b34aa0..b6b74d2 100644
--- a/src/core/SkFontPriv.h
+++ b/src/core/SkFontPriv.h
@@ -12,6 +12,9 @@
#include "SkMatrix.h"
#include "SkTypeface.h"
+class SkReadBuffer;
+class SkWriteBuffer;
+
class SkFontPriv {
public:
/**
@@ -63,6 +66,9 @@
static int CountTextElements(const void* text, size_t byteLength, SkTextEncoding);
static void GlyphsToUnichars(const SkFont&, const uint16_t glyphs[], int count, SkUnichar[]);
+
+ static void Flatten(const SkFont&, SkWriteBuffer& buffer);
+ static bool Unflatten(SkFont*, SkReadBuffer& buffer);
};
class SkAutoToGlyphs {
diff --git a/src/core/SkReadBuffer.h b/src/core/SkReadBuffer.h
index a9b0d02..bbb036f 100644
--- a/src/core/SkReadBuffer.h
+++ b/src/core/SkReadBuffer.h
@@ -44,6 +44,7 @@
kRemoveOccluderFromBlurMaskFilter = 64,
kFloat4PaintColor_Version = 65,
kSaveBehind_Version = 66,
+ kSerializeFonts_Version = 67,
};
/**
@@ -247,6 +248,7 @@
kRemoveOccluderFromBlurMaskFilter = 64,
kFloat4PaintColor_Version = 65,
kSaveBehind_Version = 66,
+ kSerializeFonts_Version = 67,
};
bool isVersionLT(Version) const { return false; }
diff --git a/src/core/SkTextBlob.cpp b/src/core/SkTextBlob.cpp
index 4240973..2dfa381 100644
--- a/src/core/SkTextBlob.cpp
+++ b/src/core/SkTextBlob.cpp
@@ -696,9 +696,6 @@
///////////////////////////////////////////////////////////////////////////////////////////////////
void SkTextBlobPriv::Flatten(const SkTextBlob& blob, SkWriteBuffer& buffer) {
- buffer.writeRect(blob.fBounds);
-
- SkPaint runPaint;
SkTextBlobRunIterator it(&blob);
while (!it.done()) {
SkASSERT(it.glyphCount() > 0);
@@ -716,9 +713,8 @@
buffer.write32(textSize);
}
buffer.writePoint(it.offset());
- // This should go away when switching to SkFont
- it.applyFontToPaint(&runPaint);
- buffer.writePaint(runPaint);
+
+ SkFontPriv::Flatten(it.font(), buffer);
buffer.writeByteArray(it.glyphs(), it.glyphCount() * sizeof(uint16_t));
buffer.writeByteArray(it.pos(),
@@ -738,8 +734,11 @@
}
sk_sp<SkTextBlob> SkTextBlobPriv::MakeFromBuffer(SkReadBuffer& reader) {
- SkRect bounds;
- reader.readRect(&bounds);
+ if (reader.isVersionLT(SkReadBuffer::kSerializeFonts_Version)) {
+ SkRect bounds;
+ reader.readRect(&bounds);
+ // ignored
+ }
SkTextBlobBuilder blobBuilder;
SkSafeMath safe;
@@ -763,9 +762,14 @@
SkPoint offset;
reader.readPoint(&offset);
- SkPaint paint;
- reader.readPaint(&paint);
- SkFont font = SkFont::LEGACY_ExtractFromPaint(paint);
+ SkFont font;
+ if (reader.isVersionLT(SkReadBuffer::kSerializeFonts_Version)) {
+ SkPaint paint;
+ reader.readPaint(&paint);
+ font = SkFont::LEGACY_ExtractFromPaint(paint);
+ } else {
+ SkFontPriv::Unflatten(&font, reader);
+ }
// Compute the expected size of the buffer and ensure we have enough to deserialize
// a run before allocating it.
@@ -785,17 +789,17 @@
switch (pos) {
case SkTextBlob::kDefault_Positioning:
buf = &blobBuilder.allocRunText(font, glyphCount, offset.x(), offset.y(),
- textSize, SkString(), &bounds);
+ textSize, SkString(), nullptr);
break;
case SkTextBlob::kHorizontal_Positioning:
buf = &blobBuilder.allocRunTextPosH(font, glyphCount, offset.y(),
- textSize, SkString(), &bounds);
+ textSize, SkString(), nullptr);
break;
case SkTextBlob::kFull_Positioning:
- buf = &blobBuilder.allocRunTextPos(font, glyphCount, textSize, SkString(), &bounds);
+ buf = &blobBuilder.allocRunTextPos(font, glyphCount, textSize, SkString(), nullptr);
break;
case SkTextBlob::kRSXform_Positioning:
- buf = &blobBuilder.allocRunRSXform(font, glyphCount, textSize, SkString(), &bounds);
+ buf = &blobBuilder.allocRunRSXform(font, glyphCount, textSize, SkString(), nullptr);
break;
}
diff --git a/tests/TextBlobTest.cpp b/tests/TextBlobTest.cpp
index 51ff457..a52540e 100644
--- a/tests/TextBlobTest.cpp
+++ b/tests/TextBlobTest.cpp
@@ -415,8 +415,8 @@
sk_sp<SkTypeface> tf = SkTypeface::MakeDefault();
SkTextBlobBuilder builder;
- add_run(&builder, "Hello", 10, 20, nullptr); // we don't flatten this in the paint
- add_run(&builder, "World", 10, 40, tf); // we will flatten this in the paint
+ add_run(&builder, "Hello", 10, 20, nullptr); // don't flatten a typeface
+ add_run(&builder, "World", 10, 40, tf); // do flatten this typeface
return builder.make();
}();
@@ -425,7 +425,7 @@
serializeProcs.fTypefaceProc = &SerializeTypeface;
serializeProcs.fTypefaceCtx = (void*) &array;
sk_sp<SkData> data = blob0->serialize(serializeProcs);
- REPORTER_ASSERT(reporter, array.count() == 2);
+ REPORTER_ASSERT(reporter, array.count() == 1);
SkDeserialProcs deserializeProcs;
deserializeProcs.fTypefaceProc = &DeserializeTypeface;
deserializeProcs.fTypefaceCtx = (void*) &array;