aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar joshualitt <joshualitt@chromium.org>2015-03-13 08:38:43 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-03-13 08:38:43 -0700
commitfd45079314b739979492601fc7a242aff24c58a3 (patch)
tree456124ecafc6d73de7964fede1c0827eed61e891 /src
parent6e8f9033bb8d4f27a0dae6bc10bfb629f8e3ba0b (diff)
Call to retrieve SkDescriptor for SkScalarContext from SkPaint.
Diffstat (limited to 'src')
-rw-r--r--src/core/SkPaint.cpp213
1 files changed, 135 insertions, 78 deletions
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
index b93236f0d1..6ddbe027a1 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);