| Index: src/core/SkPaint.cpp
|
| diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
|
| index 5774839ed84c9a888eadb968441c9116a07c06d7..c61167f5a0bb9a77173b1eb862666a1d2440737e 100644
|
| --- a/src/core/SkPaint.cpp
|
| +++ b/src/core/SkPaint.cpp
|
| @@ -1597,121 +1597,177 @@ void SkScalerContext::PostMakeRec(const SkPaint&, SkScalerContext::Rec* rec) {
|
| #define TEST_DESC
|
| #endif
|
|
|
| -/*
|
| - * ignoreGamma tells us that the caller just wants metrics that are unaffected
|
| - * by gamma correction, so we set the rec to ignore preblend: i.e. gamma = 1,
|
| - * contrast = 0, luminanceColor = transparent black.
|
| - */
|
| -void SkPaint::descriptorProc(const SkDeviceProperties* deviceProperties,
|
| - const SkMatrix* deviceMatrix,
|
| - void (*proc)(SkTypeface*, const SkDescriptor*, void*),
|
| - void* context, bool ignoreGamma) const {
|
| - SkScalerContext::Rec rec;
|
| +static void write_out_descriptor(SkDescriptor* desc, const SkScalerContext::Rec& rec,
|
| + const SkPathEffect* pe, SkWriteBuffer* peBuffer,
|
| + const SkMaskFilter* mf, SkWriteBuffer* mfBuffer,
|
| + const SkRasterizer* ra, SkWriteBuffer* raBuffer,
|
| + size_t descSize) {
|
| + desc->init();
|
| + desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
|
|
|
| - SkScalerContext::MakeRec(*this, deviceProperties, deviceMatrix, &rec);
|
| - if (ignoreGamma) {
|
| - rec.ignorePreBlend();
|
| + if (pe) {
|
| + add_flattenable(desc, kPathEffect_SkDescriptorTag, peBuffer);
|
| + }
|
| + if (mf) {
|
| + add_flattenable(desc, kMaskFilter_SkDescriptorTag, mfBuffer);
|
| + }
|
| + if (ra) {
|
| + add_flattenable(desc, kRasterizer_SkDescriptorTag, raBuffer);
|
| }
|
|
|
| - size_t descSize = sizeof(rec);
|
| - int entryCount = 1;
|
| - SkPathEffect* pe = this->getPathEffect();
|
| - SkMaskFilter* mf = this->getMaskFilter();
|
| - SkRasterizer* ra = this->getRasterizer();
|
| + desc->computeChecksum();
|
| +}
|
| +
|
| +static size_t fill_out_rec(const SkPaint& paint, SkScalerContext::Rec* rec,
|
| + const SkDeviceProperties* deviceProperties,
|
| + const SkMatrix* deviceMatrix, bool ignoreGamma,
|
| + const SkPathEffect* pe, SkWriteBuffer* peBuffer,
|
| + const SkMaskFilter* mf, SkWriteBuffer* mfBuffer,
|
| + const SkRasterizer* ra, SkWriteBuffer* raBuffer) {
|
| + SkScalerContext::MakeRec(paint, deviceProperties, deviceMatrix, rec);
|
| + if (ignoreGamma) {
|
| + rec->ignorePreBlend();
|
| + }
|
|
|
| - SkWriteBuffer peBuffer, mfBuffer, raBuffer;
|
| + int entryCount = 1;
|
| + size_t descSize = sizeof(*rec);
|
|
|
| if (pe) {
|
| - peBuffer.writeFlattenable(pe);
|
| - descSize += peBuffer.bytesWritten();
|
| + peBuffer->writeFlattenable(pe);
|
| + descSize += peBuffer->bytesWritten();
|
| entryCount += 1;
|
| - rec.fMaskFormat = SkMask::kA8_Format; // force antialiasing when we do the scan conversion
|
| + rec->fMaskFormat = SkMask::kA8_Format; // force antialiasing when we do the scan conversion
|
| // seems like we could support kLCD as well at this point...
|
| }
|
| if (mf) {
|
| - mfBuffer.writeFlattenable(mf);
|
| - descSize += mfBuffer.bytesWritten();
|
| + mfBuffer->writeFlattenable(mf);
|
| + descSize += mfBuffer->bytesWritten();
|
| entryCount += 1;
|
| - rec.fMaskFormat = SkMask::kA8_Format; // force antialiasing with maskfilters
|
| + rec->fMaskFormat = SkMask::kA8_Format; // force antialiasing with maskfilters
|
| /* Pre-blend is not currently applied to filtered text.
|
| The primary filter is blur, for which contrast makes no sense,
|
| and for which the destination guess error is more visible.
|
| Also, all existing users of blur have calibrated for linear. */
|
| - rec.ignorePreBlend();
|
| + rec->ignorePreBlend();
|
| }
|
| if (ra) {
|
| - raBuffer.writeFlattenable(ra);
|
| - descSize += raBuffer.bytesWritten();
|
| + raBuffer->writeFlattenable(ra);
|
| + descSize += raBuffer->bytesWritten();
|
| entryCount += 1;
|
| - rec.fMaskFormat = SkMask::kA8_Format; // force antialiasing when we do the scan conversion
|
| + rec->fMaskFormat = SkMask::kA8_Format; // force antialiasing when we do the scan conversion
|
| }
|
|
|
| ///////////////////////////////////////////////////////////////////////////
|
| // Now that we're done tweaking the rec, call the PostMakeRec cleanup
|
| - SkScalerContext::PostMakeRec(*this, &rec);
|
| + SkScalerContext::PostMakeRec(paint, rec);
|
|
|
| descSize += SkDescriptor::ComputeOverhead(entryCount);
|
| + return descSize;
|
| +}
|
|
|
| - SkAutoDescriptor ad(descSize);
|
| - SkDescriptor* desc = ad.getDesc();
|
| -
|
| - desc->init();
|
| - desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
|
| +#ifdef TEST_DESC
|
| +static void test_desc(const SkScalerContext::Rec& rec,
|
| + const SkPathEffect* pe, SkWriteBuffer* peBuffer,
|
| + const SkMaskFilter* mf, SkWriteBuffer* mfBuffer,
|
| + const SkRasterizer* ra, SkWriteBuffer* raBuffer,
|
| + const SkDescriptor* desc, size_t descSize) {
|
| + // Check that we completely write the bytes in desc (our key), and that
|
| + // there are no uninitialized bytes. If there were, then we would get
|
| + // false-misses (or worse, false-hits) in our fontcache.
|
| + //
|
| + // We do this buy filling 2 others, one with 0s and the other with 1s
|
| + // and create those, and then check that all 3 are identical.
|
| + SkAutoDescriptor ad1(descSize);
|
| + SkAutoDescriptor ad2(descSize);
|
| + SkDescriptor* desc1 = ad1.getDesc();
|
| + SkDescriptor* desc2 = ad2.getDesc();
|
| +
|
| + memset(desc1, 0x00, descSize);
|
| + memset(desc2, 0xFF, descSize);
|
| +
|
| + desc1->init();
|
| + desc2->init();
|
| + desc1->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
|
| + desc2->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
|
|
|
| if (pe) {
|
| - add_flattenable(desc, kPathEffect_SkDescriptorTag, &peBuffer);
|
| + add_flattenable(desc1, kPathEffect_SkDescriptorTag, peBuffer);
|
| + add_flattenable(desc2, kPathEffect_SkDescriptorTag, peBuffer);
|
| }
|
| if (mf) {
|
| - add_flattenable(desc, kMaskFilter_SkDescriptorTag, &mfBuffer);
|
| + add_flattenable(desc1, kMaskFilter_SkDescriptorTag, mfBuffer);
|
| + add_flattenable(desc2, kMaskFilter_SkDescriptorTag, mfBuffer);
|
| }
|
| if (ra) {
|
| - add_flattenable(desc, kRasterizer_SkDescriptorTag, &raBuffer);
|
| + add_flattenable(desc1, kRasterizer_SkDescriptorTag, raBuffer);
|
| + add_flattenable(desc2, kRasterizer_SkDescriptorTag, raBuffer);
|
| }
|
|
|
| + SkASSERT(descSize == desc1->getLength());
|
| + SkASSERT(descSize == desc2->getLength());
|
| + desc1->computeChecksum();
|
| + desc2->computeChecksum();
|
| + SkASSERT(!memcmp(desc, desc1, descSize));
|
| + SkASSERT(!memcmp(desc, desc2, descSize));
|
| +}
|
| +#endif
|
| +
|
| +/* see the note on ignoreGamma on descriptorProc */
|
| +const SkData* SkPaint::getDescriptor(const SkDeviceProperties* deviceProperties,
|
| + const SkMatrix* deviceMatrix, bool ignoreGamma) const {
|
| + SkScalerContext::Rec rec;
|
| +
|
| + SkPathEffect* pe = this->getPathEffect();
|
| + SkMaskFilter* mf = this->getMaskFilter();
|
| + SkRasterizer* ra = this->getRasterizer();
|
| +
|
| + SkWriteBuffer peBuffer, mfBuffer, raBuffer;
|
| + size_t descSize = fill_out_rec(*this, &rec, deviceProperties, deviceMatrix, ignoreGamma,
|
| + pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer);
|
| +
|
| + SkASSERT(SkAlign4(descSize) == descSize);
|
| + SkData* data = SkData::NewUninitialized(descSize);
|
| + SkDescriptor* desc = reinterpret_cast<SkDescriptor*>(data->writable_data());
|
| +
|
| + write_out_descriptor(desc, rec, pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer, descSize);
|
| +
|
| SkASSERT(descSize == desc->getLength());
|
| - desc->computeChecksum();
|
|
|
| #ifdef TEST_DESC
|
| - {
|
| - // Check that we completely write the bytes in desc (our key), and that
|
| - // there are no uninitialized bytes. If there were, then we would get
|
| - // false-misses (or worse, false-hits) in our fontcache.
|
| - //
|
| - // We do this buy filling 2 others, one with 0s and the other with 1s
|
| - // and create those, and then check that all 3 are identical.
|
| - SkAutoDescriptor ad1(descSize);
|
| - SkAutoDescriptor ad2(descSize);
|
| - SkDescriptor* desc1 = ad1.getDesc();
|
| - SkDescriptor* desc2 = ad2.getDesc();
|
| -
|
| - memset(desc1, 0x00, descSize);
|
| - memset(desc2, 0xFF, descSize);
|
| -
|
| - desc1->init();
|
| - desc2->init();
|
| - desc1->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
|
| - desc2->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
|
| -
|
| - if (pe) {
|
| - add_flattenable(desc1, kPathEffect_SkDescriptorTag, &peBuffer);
|
| - add_flattenable(desc2, kPathEffect_SkDescriptorTag, &peBuffer);
|
| - }
|
| - if (mf) {
|
| - add_flattenable(desc1, kMaskFilter_SkDescriptorTag, &mfBuffer);
|
| - add_flattenable(desc2, kMaskFilter_SkDescriptorTag, &mfBuffer);
|
| - }
|
| - if (ra) {
|
| - add_flattenable(desc1, kRasterizer_SkDescriptorTag, &raBuffer);
|
| - add_flattenable(desc2, kRasterizer_SkDescriptorTag, &raBuffer);
|
| - }
|
| + test_desc(rec, pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer, desc, descSize);
|
| +#endif
|
|
|
| - SkASSERT(descSize == desc1->getLength());
|
| - SkASSERT(descSize == desc2->getLength());
|
| - desc1->computeChecksum();
|
| - desc2->computeChecksum();
|
| - SkASSERT(!memcmp(desc, desc1, descSize));
|
| - SkASSERT(!memcmp(desc, desc2, descSize));
|
| - }
|
| + return data;
|
| +}
|
| +
|
| +/*
|
| + * ignoreGamma tells us that the caller just wants metrics that are unaffected
|
| + * by gamma correction, so we set the rec to ignore preblend: i.e. gamma = 1,
|
| + * contrast = 0, luminanceColor = transparent black.
|
| + */
|
| +void SkPaint::descriptorProc(const SkDeviceProperties* deviceProperties,
|
| + const SkMatrix* deviceMatrix,
|
| + void (*proc)(SkTypeface*, const SkDescriptor*, void*),
|
| + void* context, bool ignoreGamma) const {
|
| + SkScalerContext::Rec rec;
|
| +
|
| + SkPathEffect* pe = this->getPathEffect();
|
| + SkMaskFilter* mf = this->getMaskFilter();
|
| + SkRasterizer* ra = this->getRasterizer();
|
| +
|
| + SkWriteBuffer peBuffer, mfBuffer, raBuffer;
|
| + size_t descSize = fill_out_rec(*this, &rec, deviceProperties, deviceMatrix, ignoreGamma,
|
| + pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer);
|
| +
|
| + SkAutoDescriptor ad(descSize);
|
| + SkDescriptor* desc = ad.getDesc();
|
| +
|
| + write_out_descriptor(desc, rec, pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer, descSize);
|
| +
|
| + SkASSERT(descSize == desc->getLength());
|
| +
|
| +#ifdef TEST_DESC
|
| + test_desc(rec, pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer, desc, descSize);
|
| #endif
|
|
|
| proc(fTypeface, desc, context);
|
|
|