unflatten directly to font for legacy skps

All of this extra code/parameter-passing for fonts to the paint unflattener
can go away when we can drop support for older skps

Bug: skia:
Change-Id: I4d626f0925a54564b7c386ed80953a0291c8bc1a
Reviewed-on: https://skia-review.googlesource.com/c/183863
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Mike Reed <reed@google.com>
This commit is contained in:
Mike Reed 2019-01-14 17:36:54 -05:00 committed by Skia Commit-Bot
parent f69f370706
commit 31ba6feaf6
9 changed files with 112 additions and 38 deletions

View File

@ -390,8 +390,49 @@ static inline int BPF_Mask(int bits) {
return (1 << bits) - 1;
}
static FlatFlags unpack_paint_flags(SkPaint* paint, uint32_t packed) {
paint->setFlags(packed >> 16);
// SkPaint originally defined flags, some of which now apply to SkFont. These are renames
// of those flags, split into categories depending on which objects they (now) apply to.
enum PaintFlagsForPaint {
kAA_PaintFlagForPaint = 0x01,
kDither_PaintFlagForPaint = 0x04,
};
enum PaintFlagsForFont {
kFakeBold_PaintFlagForFont = 0x20,
kLinear_PaintFlagForFont = 0x40,
kSubpixel_PaintFlagForFont = 0x80,
kLCD_PaintFlagForFont = 0x200,
kEmbeddedBitmap_PaintFlagForFont = 0x400,
kAutoHinting_PaintFlagForFont = 0x800,
};
static FlatFlags unpack_paint_flags(SkPaint* paint, uint32_t packed, SkFont* font) {
uint32_t f = packed >> 16;
#ifdef SK_SUPPORT_LEGACY_PAINT_FONT_FIELDS
paint->setFlags(f);
#else
paint->setAntiAlias((f & kAA_PaintFlagForPaint) != 0);
paint->setDither((f & kDither_PaintFlagForPaint) != 0);
#endif
if (font) {
font->setEmbolden((f & kFakeBold_PaintFlagForFont) != 0);
font->setLinearMetrics((f & kLinear_PaintFlagForFont) != 0);
font->setSubpixel((f & kSubpixel_PaintFlagForFont) != 0);
font->setEmbeddedBitmaps((f & kEmbeddedBitmap_PaintFlagForFont) != 0);
font->setForceAutoHinting((f & kAutoHinting_PaintFlagForFont) != 0);
if (f & kAA_PaintFlagForPaint) {
if (f & kLCD_PaintFlagForFont) {
font->setEdging(SkFont::Edging::kSubpixelAntiAlias);
} else {
font->setEdging(SkFont::Edging::kAntiAlias);
}
} else {
font->setEdging(SkFont::Edging::kAlias);
}
}
paint->setHinting((SkFontHinting)((packed >> 14) & BPF_Mask(kHint_BPF)));
paint->setFilterQuality((SkFilterQuality)((packed >> 10) & BPF_Mask(kFilter_BPF)));
return (FlatFlags)(packed & kFlatFlagMask);
@ -475,12 +516,25 @@ void SkPaintPriv::Flatten(const SkPaint& paint, SkWriteBuffer& buffer) {
}
}
bool SkPaintPriv::Unflatten_PreV68(SkPaint* paint, SkReadBuffer& buffer) {
SkReadPaintResult SkPaintPriv::Unflatten_PreV68(SkPaint* paint, SkReadBuffer& buffer, SkFont* font) {
SkSafeRange safe;
paint->setTextSize(buffer.readScalar());
paint->setTextScaleX(buffer.readScalar());
paint->setTextSkewX(buffer.readScalar());
{
SkScalar sz = buffer.readScalar();
SkScalar sx = buffer.readScalar();
SkScalar kx = buffer.readScalar();
#ifdef SK_SUPPORT_LEGACY_PAINT_FONT_FIELDS
paint->setTextSize(sz);
paint->setTextScaleX(sx);
paint->setTextSkewX(kx);
#endif
if (font) {
font->setSize(sz);
font->setScaleX(sx);
font->setSkewX(kx);
}
}
paint->setStrokeWidth(buffer.readScalar());
paint->setStrokeMiter(buffer.readScalar());
if (buffer.isVersionLT(SkReadBuffer::kFloat4PaintColor_Version)) {
@ -491,7 +545,7 @@ bool SkPaintPriv::Unflatten_PreV68(SkPaint* paint, SkReadBuffer& buffer) {
paint->setColor4f(color, sk_srgb_singleton());
}
unsigned flatFlags = unpack_paint_flags(paint, buffer.readUInt());
unsigned flatFlags = unpack_paint_flags(paint, buffer.readUInt(), font);
uint32_t tmp = buffer.readUInt();
paint->setStrokeCap(safe.checkLE((tmp >> 24) & 0xFF, SkPaint::kLast_Cap));
@ -500,10 +554,15 @@ bool SkPaintPriv::Unflatten_PreV68(SkPaint* paint, SkReadBuffer& buffer) {
paint->private_internal_setTextEncoding(safe.checkLE((tmp >> 8) & 0xF, kGlyphID_SkTextEncoding));
paint->setBlendMode(safe.checkLE(tmp & 0xFF, SkBlendMode::kLastMode));
sk_sp<SkTypeface> tf;
if (flatFlags & kHasTypeface_FlatFlag) {
paint->setTypeface(buffer.readTypeface());
} else {
paint->setTypeface(nullptr);
tf = buffer.readTypeface();
}
#ifdef SK_SUPPORT_LEGACY_PAINT_FONT_FIELDS
paint->setTypeface(tf);
#endif
if (font) {
font->setTypeface(tf);
}
if (flatFlags & kHasEffects_FlatFlag) {
@ -525,14 +584,14 @@ bool SkPaintPriv::Unflatten_PreV68(SkPaint* paint, SkReadBuffer& buffer) {
if (!buffer.validate(safe)) {
paint->reset();
return false;
return kFailed_ReadPaint;
}
return true;
return kSuccess_PaintAndFont;
}
bool SkPaintPriv::Unflatten(SkPaint* paint, SkReadBuffer& buffer) {
SkReadPaintResult SkPaintPriv::Unflatten(SkPaint* paint, SkReadBuffer& buffer, SkFont* font) {
if (buffer.isVersionLT(SkReadBuffer::kPaintDoesntSerializeFonts_Version)) {
return Unflatten_PreV68(paint, buffer);
return Unflatten_PreV68(paint, buffer, font);
}
SkSafeRange safe;
@ -565,9 +624,9 @@ bool SkPaintPriv::Unflatten(SkPaint* paint, SkReadBuffer& buffer) {
if (!buffer.validate(safe)) {
paint->reset();
return false;
return kFailed_ReadPaint;
}
return true;
return kSuccess_JustPaint;
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -18,6 +18,12 @@ class SkImage;
class SkReadBuffer;
class SkWriteBuffer;
enum SkReadPaintResult {
kFailed_ReadPaint,
kSuccess_JustPaint,
kSuccess_PaintAndFont,
};
class SkPaintPriv {
public:
enum ShaderOverrideOpacity {
@ -91,18 +97,22 @@ public:
static void Flatten(const SkPaint& paint, SkWriteBuffer& buffer);
/** Populates SkPaint, typically from a serialized stream, created by calling
flatten() at an earlier time.
flatten() at an earlier time.
SkReadBuffer class is not public, so unflatten() cannot be meaningfully called
by the client.
SkReadBuffer class is not public, so unflatten() cannot be meaningfully called
by the client.
@param buffer serialized data describing SkPaint content
@return false if the buffer contains invalid data
Older formats also stored font info in the serialized data. On success, this
returns if it deserialized just a paint, or both a font and paint. The font
param is optional.
@param buffer serialized data describing SkPaint content
@return false if the buffer contains invalid data
*/
static bool Unflatten(SkPaint* paint, SkReadBuffer& buffer);
static SkReadPaintResult Unflatten(SkPaint* paint, SkReadBuffer& buffer, SkFont* font);
private:
static bool Unflatten_PreV68(SkPaint* paint, SkReadBuffer& buffer);
static SkReadPaintResult Unflatten_PreV68(SkPaint* paint, SkReadBuffer& buffer, SkFont*);
};
#endif

View File

@ -410,7 +410,8 @@ void SkPictureData::parseBufferTag(SkReadBuffer& buffer, uint32_t tag, uint32_t
const int count = SkToInt(size);
for (int i = 0; i < count; ++i) {
if (!buffer.readPaint(&fPaints.push_back())) {
// Do we need to keep an array of fFonts for legacy draws?
if (!buffer.readPaint(&fPaints.push_back(), nullptr)) {
return;
}
}

View File

@ -11,6 +11,7 @@
#include "SkColorFilter.h"
#include "SkSerialProcs.h"
#include "SkDrawLooper.h"
#include "SkFont.h"
#include "SkImageFilter.h"
#include "SkMaskFilterBase.h"
#include "SkPaintPriv.h"
@ -112,7 +113,10 @@ public:
void readRegion(SkRegion* region);
void readPath(SkPath* path);
bool readPaint(SkPaint* paint) { return SkPaintPriv::Unflatten(paint, *this); }
SkReadPaintResult readPaint(SkPaint* paint, SkFont* font) {
return SkPaintPriv::Unflatten(paint, *this, font);
}
SkFlattenable* readFlattenable(SkFlattenable::Type);
template <typename T> sk_sp<T> readFlattenable() {
@ -288,7 +292,13 @@ public:
void readRegion (SkRegion* out) { *out = SkRegion(); }
void readString (SkString* out) { *out = SkString(); }
void readPath (SkPath* out) { *out = SkPath(); }
bool readPaint (SkPaint* out) { *out = SkPaint(); return false; }
SkReadPaintResult readPaint (SkPaint* out, SkFont* font) {
*out = SkPaint();
if (font) {
*font = SkFont();
}
return kFailed_ReadPaint;
}
SkPoint readPoint() { return {0,0}; }

View File

@ -758,14 +758,8 @@ sk_sp<SkTextBlob> SkTextBlobPriv::MakeFromBuffer(SkReadBuffer& reader) {
reader.readPoint(&offset);
SkFont font;
if (reader.isVersionLT(SkReadBuffer::kSerializeFonts_Version)) {
#ifdef SK_SUPPORT_LEGACY_PAINT_FONT_FIELDS
SkPaint paint;
reader.readPaint(&paint);
font = SkFont::LEGACY_ExtractFromPaint(paint);
#else
reader.validate(false);
return nullptr;
#endif
reader.readPaint(&paint, &font);
} else {
SkFontPriv::Unflatten(&font, reader);
}

View File

@ -268,7 +268,7 @@ sk_sp<SkFlattenable> SkLayerDrawLooper::CreateProc(SkReadBuffer& buffer) {
info.fColorMode = (SkBlendMode)buffer.readInt();
buffer.readPoint(&info.fOffset);
info.fPostTranslate = buffer.readBool();
buffer.readPaint(builder.addLayerOnTop(info));
buffer.readPaint(builder.addLayerOnTop(info), nullptr);
if (!buffer.isValid()) {
return nullptr;
}

View File

@ -27,7 +27,7 @@ SkPaintImageFilter::SkPaintImageFilter(const SkPaint& paint, const CropRect* cro
sk_sp<SkFlattenable> SkPaintImageFilter::CreateProc(SkReadBuffer& buffer) {
SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 0);
SkPaint paint;
buffer.readPaint(&paint);
buffer.readPaint(&paint, nullptr);
return SkPaintImageFilter::Make(paint, &common.cropRect());
}

View File

@ -71,7 +71,7 @@ public:
static sk_sp<SkFlattenable> CreateProc(SkReadBuffer& buffer) {
SkPaint paint;
buffer.readPaint(&paint);
buffer.readPaint(&paint, nullptr);
return sk_sp<PaintDrawable>(new PaintDrawable(paint));
}

View File

@ -240,7 +240,7 @@ DEF_TEST(Paint_flattening, reporter) {
SkReadBuffer reader(buf.get(), writer.bytesWritten());
SkPaint paint2;
SkPaintPriv::Unflatten(&paint2, reader);
SkPaintPriv::Unflatten(&paint2, reader, nullptr);
REPORTER_ASSERT(reporter, paint2 == paint);
}}}}
@ -282,7 +282,7 @@ DEF_TEST(Paint_MoreFlattening, r) {
SkReadBuffer reader(buf.get(), writer.bytesWritten());
SkPaint other;
SkPaintPriv::Unflatten(&other, reader);
SkPaintPriv::Unflatten(&other, reader, nullptr);
ASSERT(reader.offset() == writer.bytesWritten());
// No matter the encoding, these must always hold.