Index: src/core/SkPaint.cpp |
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp |
index b93236f0d10393530b0028114826a45d27b34af8..6ddbe027a1a7b8f89273909e0d11a5166df39c4b 100644 |
--- a/src/core/SkPaint.cpp |
+++ b/src/core/SkPaint.cpp |
@@ -1589,121 +1589,178 @@ 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::getScalerContextDescriptor(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); |