| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkPaint.h" | 8 #include "SkPaint.h" |
| 9 #include "SkAnnotation.h" | 9 #include "SkAnnotation.h" |
| 10 #include "SkAutoKern.h" | 10 #include "SkAutoKern.h" |
| 11 #include "SkChecksum.h" | 11 #include "SkChecksum.h" |
| 12 #include "SkColorFilter.h" | 12 #include "SkColorFilter.h" |
| 13 #include "SkData.h" | 13 #include "SkData.h" |
| 14 #include "SkDeviceProperties.h" | |
| 15 #include "SkDraw.h" | 14 #include "SkDraw.h" |
| 16 #include "SkFontDescriptor.h" | 15 #include "SkFontDescriptor.h" |
| 17 #include "SkGlyphCache.h" | 16 #include "SkGlyphCache.h" |
| 18 #include "SkImageFilter.h" | 17 #include "SkImageFilter.h" |
| 19 #include "SkMaskFilter.h" | 18 #include "SkMaskFilter.h" |
| 20 #include "SkMaskGamma.h" | 19 #include "SkMaskGamma.h" |
| 21 #include "SkReadBuffer.h" | 20 #include "SkReadBuffer.h" |
| 22 #include "SkWriteBuffer.h" | 21 #include "SkWriteBuffer.h" |
| 23 #include "SkPaintDefaults.h" | 22 #include "SkPaintDefaults.h" |
| 24 #include "SkPathEffect.h" | 23 #include "SkPathEffect.h" |
| 25 #include "SkRasterizer.h" | 24 #include "SkRasterizer.h" |
| 26 #include "SkScalar.h" | 25 #include "SkScalar.h" |
| 27 #include "SkScalerContext.h" | 26 #include "SkScalerContext.h" |
| 28 #include "SkShader.h" | 27 #include "SkShader.h" |
| 29 #include "SkStringUtils.h" | 28 #include "SkStringUtils.h" |
| 30 #include "SkStroke.h" | 29 #include "SkStroke.h" |
| 31 #include "SkTextFormatParams.h" | 30 #include "SkTextFormatParams.h" |
| 32 #include "SkTextToPathIter.h" | 31 #include "SkTextToPathIter.h" |
| 33 #include "SkTLazy.h" | 32 #include "SkTLazy.h" |
| 34 #include "SkTypeface.h" | 33 #include "SkTypeface.h" |
| 34 #include "SkSurfacePriv.h" |
| 35 #include "SkXfermode.h" | 35 #include "SkXfermode.h" |
| 36 | 36 |
| 37 // define this to get a printf for out-of-range parameter in setters | 37 // define this to get a printf for out-of-range parameter in setters |
| 38 // e.g. setTextSize(-1) | 38 // e.g. setTextSize(-1) |
| 39 //#define SK_REPORT_API_RANGE_CHECK | 39 //#define SK_REPORT_API_RANGE_CHECK |
| 40 | 40 |
| 41 SkPaint::SkPaint() { | 41 SkPaint::SkPaint() { |
| 42 fTypeface = NULL; | 42 fTypeface = NULL; |
| 43 fPathEffect = NULL; | 43 fPathEffect = NULL; |
| 44 fShader = NULL; | 44 fShader = NULL; |
| (...skipping 1277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1322 * Return the scalar with only limited fractional precision. Used to consolidat
e matrices | 1322 * Return the scalar with only limited fractional precision. Used to consolidat
e matrices |
| 1323 * that vary only slightly when we create our key into the font cache, since th
e font scaler | 1323 * that vary only slightly when we create our key into the font cache, since th
e font scaler |
| 1324 * typically returns the same looking resuts for tiny changes in the matrix. | 1324 * typically returns the same looking resuts for tiny changes in the matrix. |
| 1325 */ | 1325 */ |
| 1326 static SkScalar sk_relax(SkScalar x) { | 1326 static SkScalar sk_relax(SkScalar x) { |
| 1327 int n = sk_float_round2int(x * 1024); | 1327 int n = sk_float_round2int(x * 1024); |
| 1328 return n / 1024.0f; | 1328 return n / 1024.0f; |
| 1329 } | 1329 } |
| 1330 | 1330 |
| 1331 void SkScalerContext::MakeRec(const SkPaint& paint, | 1331 void SkScalerContext::MakeRec(const SkPaint& paint, |
| 1332 const SkDeviceProperties* deviceProperties, | 1332 const SkSurfaceProps* surfaceProps, |
| 1333 const SkMatrix* deviceMatrix, | 1333 const SkMatrix* deviceMatrix, |
| 1334 Rec* rec) { | 1334 Rec* rec) { |
| 1335 SkASSERT(deviceMatrix == NULL || !deviceMatrix->hasPerspective()); | 1335 SkASSERT(deviceMatrix == NULL || !deviceMatrix->hasPerspective()); |
| 1336 | 1336 |
| 1337 SkTypeface* typeface = paint.getTypeface(); | 1337 SkTypeface* typeface = paint.getTypeface(); |
| 1338 if (NULL == typeface) { | 1338 if (NULL == typeface) { |
| 1339 typeface = SkTypeface::GetDefaultTypeface(); | 1339 typeface = SkTypeface::GetDefaultTypeface(); |
| 1340 } | 1340 } |
| 1341 rec->fFontID = typeface->uniqueID(); | 1341 rec->fFontID = typeface->uniqueID(); |
| 1342 rec->fTextSize = paint.getTextSize(); | 1342 rec->fTextSize = paint.getTextSize(); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1408 rec->fStrokeJoin = 0; | 1408 rec->fStrokeJoin = 0; |
| 1409 } | 1409 } |
| 1410 | 1410 |
| 1411 rec->fMaskFormat = SkToU8(computeMaskFormat(paint)); | 1411 rec->fMaskFormat = SkToU8(computeMaskFormat(paint)); |
| 1412 | 1412 |
| 1413 if (SkMask::kLCD16_Format == rec->fMaskFormat) { | 1413 if (SkMask::kLCD16_Format == rec->fMaskFormat) { |
| 1414 if (too_big_for_lcd(*rec, checkPost2x2)) { | 1414 if (too_big_for_lcd(*rec, checkPost2x2)) { |
| 1415 rec->fMaskFormat = SkMask::kA8_Format; | 1415 rec->fMaskFormat = SkMask::kA8_Format; |
| 1416 flags |= SkScalerContext::kGenA8FromLCD_Flag; | 1416 flags |= SkScalerContext::kGenA8FromLCD_Flag; |
| 1417 } else { | 1417 } else { |
| 1418 SkPixelGeometry geometry = deviceProperties | 1418 SkPixelGeometry geometry = surfaceProps |
| 1419 ? deviceProperties->pixelGeometry() | 1419 ? surfaceProps->pixelGeometry() |
| 1420 : SkSurfacePropsDefaultPixelGeometry(); | 1420 : SkSurfacePropsDefaultPixelGeometry(); |
| 1421 switch (geometry) { | 1421 switch (geometry) { |
| 1422 case kUnknown_SkPixelGeometry: | 1422 case kUnknown_SkPixelGeometry: |
| 1423 // eeek, can't support LCD | 1423 // eeek, can't support LCD |
| 1424 rec->fMaskFormat = SkMask::kA8_Format; | 1424 rec->fMaskFormat = SkMask::kA8_Format; |
| 1425 flags |= SkScalerContext::kGenA8FromLCD_Flag; | 1425 flags |= SkScalerContext::kGenA8FromLCD_Flag; |
| 1426 break; | 1426 break; |
| 1427 case kRGB_H_SkPixelGeometry: | 1427 case kRGB_H_SkPixelGeometry: |
| 1428 // our default, do nothing. | 1428 // our default, do nothing. |
| 1429 break; | 1429 break; |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1596 add_flattenable(desc, kMaskFilter_SkDescriptorTag, mfBuffer); | 1596 add_flattenable(desc, kMaskFilter_SkDescriptorTag, mfBuffer); |
| 1597 } | 1597 } |
| 1598 if (ra) { | 1598 if (ra) { |
| 1599 add_flattenable(desc, kRasterizer_SkDescriptorTag, raBuffer); | 1599 add_flattenable(desc, kRasterizer_SkDescriptorTag, raBuffer); |
| 1600 } | 1600 } |
| 1601 | 1601 |
| 1602 desc->computeChecksum(); | 1602 desc->computeChecksum(); |
| 1603 } | 1603 } |
| 1604 | 1604 |
| 1605 static size_t fill_out_rec(const SkPaint& paint, SkScalerContext::Rec* rec, | 1605 static size_t fill_out_rec(const SkPaint& paint, SkScalerContext::Rec* rec, |
| 1606 const SkDeviceProperties* deviceProperties, | 1606 const SkSurfaceProps* surfaceProps, |
| 1607 const SkMatrix* deviceMatrix, bool ignoreGamma, | 1607 const SkMatrix* deviceMatrix, bool ignoreGamma, |
| 1608 const SkPathEffect* pe, SkWriteBuffer* peBuffer, | 1608 const SkPathEffect* pe, SkWriteBuffer* peBuffer, |
| 1609 const SkMaskFilter* mf, SkWriteBuffer* mfBuffer, | 1609 const SkMaskFilter* mf, SkWriteBuffer* mfBuffer, |
| 1610 const SkRasterizer* ra, SkWriteBuffer* raBuffer) { | 1610 const SkRasterizer* ra, SkWriteBuffer* raBuffer) { |
| 1611 SkScalerContext::MakeRec(paint, deviceProperties, deviceMatrix, rec); | 1611 SkScalerContext::MakeRec(paint, surfaceProps, deviceMatrix, rec); |
| 1612 if (ignoreGamma) { | 1612 if (ignoreGamma) { |
| 1613 rec->ignorePreBlend(); | 1613 rec->ignorePreBlend(); |
| 1614 } | 1614 } |
| 1615 | 1615 |
| 1616 int entryCount = 1; | 1616 int entryCount = 1; |
| 1617 size_t descSize = sizeof(*rec); | 1617 size_t descSize = sizeof(*rec); |
| 1618 | 1618 |
| 1619 if (pe) { | 1619 if (pe) { |
| 1620 peBuffer->writeFlattenable(pe); | 1620 peBuffer->writeFlattenable(pe); |
| 1621 descSize += peBuffer->bytesWritten(); | 1621 descSize += peBuffer->bytesWritten(); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1691 SkASSERT(descSize == desc2->getLength()); | 1691 SkASSERT(descSize == desc2->getLength()); |
| 1692 desc1->computeChecksum(); | 1692 desc1->computeChecksum(); |
| 1693 desc2->computeChecksum(); | 1693 desc2->computeChecksum(); |
| 1694 SkASSERT(!memcmp(desc, desc1, descSize)); | 1694 SkASSERT(!memcmp(desc, desc1, descSize)); |
| 1695 SkASSERT(!memcmp(desc, desc2, descSize)); | 1695 SkASSERT(!memcmp(desc, desc2, descSize)); |
| 1696 } | 1696 } |
| 1697 #endif | 1697 #endif |
| 1698 | 1698 |
| 1699 /* see the note on ignoreGamma on descriptorProc */ | 1699 /* see the note on ignoreGamma on descriptorProc */ |
| 1700 void SkPaint::getScalerContextDescriptor(SkAutoDescriptor* ad, | 1700 void SkPaint::getScalerContextDescriptor(SkAutoDescriptor* ad, |
| 1701 const SkDeviceProperties* devicePropert
ies, | 1701 const SkSurfaceProps& surfaceProps, |
| 1702 const SkMatrix* deviceMatrix, bool igno
reGamma) const { | 1702 const SkMatrix* deviceMatrix, bool igno
reGamma) const { |
| 1703 SkScalerContext::Rec rec; | 1703 SkScalerContext::Rec rec; |
| 1704 | 1704 |
| 1705 SkPathEffect* pe = this->getPathEffect(); | 1705 SkPathEffect* pe = this->getPathEffect(); |
| 1706 SkMaskFilter* mf = this->getMaskFilter(); | 1706 SkMaskFilter* mf = this->getMaskFilter(); |
| 1707 SkRasterizer* ra = this->getRasterizer(); | 1707 SkRasterizer* ra = this->getRasterizer(); |
| 1708 | 1708 |
| 1709 SkWriteBuffer peBuffer, mfBuffer, raBuffer; | 1709 SkWriteBuffer peBuffer, mfBuffer, raBuffer; |
| 1710 size_t descSize = fill_out_rec(*this, &rec, deviceProperties, deviceMatrix,
ignoreGamma, | 1710 size_t descSize = fill_out_rec(*this, &rec, &surfaceProps, deviceMatrix, ign
oreGamma, |
| 1711 pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer); | 1711 pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer); |
| 1712 | 1712 |
| 1713 ad->reset(descSize); | 1713 ad->reset(descSize); |
| 1714 SkDescriptor* desc = ad->getDesc(); | 1714 SkDescriptor* desc = ad->getDesc(); |
| 1715 | 1715 |
| 1716 write_out_descriptor(desc, rec, pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer,
descSize); | 1716 write_out_descriptor(desc, rec, pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer,
descSize); |
| 1717 | 1717 |
| 1718 SkASSERT(descSize == desc->getLength()); | 1718 SkASSERT(descSize == desc->getLength()); |
| 1719 | 1719 |
| 1720 #ifdef TEST_DESC | 1720 #ifdef TEST_DESC |
| 1721 test_desc(rec, pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer, desc, descSize); | 1721 test_desc(rec, pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer, desc, descSize); |
| 1722 #endif | 1722 #endif |
| 1723 } | 1723 } |
| 1724 | 1724 |
| 1725 /* | 1725 /* |
| 1726 * ignoreGamma tells us that the caller just wants metrics that are unaffected | 1726 * ignoreGamma tells us that the caller just wants metrics that are unaffected |
| 1727 * by gamma correction, so we set the rec to ignore preblend: i.e. gamma = 1, | 1727 * by gamma correction, so we set the rec to ignore preblend: i.e. gamma = 1, |
| 1728 * contrast = 0, luminanceColor = transparent black. | 1728 * contrast = 0, luminanceColor = transparent black. |
| 1729 */ | 1729 */ |
| 1730 void SkPaint::descriptorProc(const SkDeviceProperties* deviceProperties, | 1730 void SkPaint::descriptorProc(const SkSurfaceProps* surfaceProps, |
| 1731 const SkMatrix* deviceMatrix, | 1731 const SkMatrix* deviceMatrix, |
| 1732 void (*proc)(SkTypeface*, const SkDescriptor*, void
*), | 1732 void (*proc)(SkTypeface*, const SkDescriptor*, void
*), |
| 1733 void* context, bool ignoreGamma) const { | 1733 void* context, bool ignoreGamma) const { |
| 1734 SkScalerContext::Rec rec; | 1734 SkScalerContext::Rec rec; |
| 1735 | 1735 |
| 1736 SkPathEffect* pe = this->getPathEffect(); | 1736 SkPathEffect* pe = this->getPathEffect(); |
| 1737 SkMaskFilter* mf = this->getMaskFilter(); | 1737 SkMaskFilter* mf = this->getMaskFilter(); |
| 1738 SkRasterizer* ra = this->getRasterizer(); | 1738 SkRasterizer* ra = this->getRasterizer(); |
| 1739 | 1739 |
| 1740 SkWriteBuffer peBuffer, mfBuffer, raBuffer; | 1740 SkWriteBuffer peBuffer, mfBuffer, raBuffer; |
| 1741 size_t descSize = fill_out_rec(*this, &rec, deviceProperties, deviceMatrix,
ignoreGamma, | 1741 size_t descSize = fill_out_rec(*this, &rec, surfaceProps, deviceMatrix, igno
reGamma, |
| 1742 pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer); | 1742 pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer); |
| 1743 | 1743 |
| 1744 SkAutoDescriptor ad(descSize); | 1744 SkAutoDescriptor ad(descSize); |
| 1745 SkDescriptor* desc = ad.getDesc(); | 1745 SkDescriptor* desc = ad.getDesc(); |
| 1746 | 1746 |
| 1747 write_out_descriptor(desc, rec, pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer,
descSize); | 1747 write_out_descriptor(desc, rec, pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer,
descSize); |
| 1748 | 1748 |
| 1749 SkASSERT(descSize == desc->getLength()); | 1749 SkASSERT(descSize == desc->getLength()); |
| 1750 | 1750 |
| 1751 #ifdef TEST_DESC | 1751 #ifdef TEST_DESC |
| 1752 test_desc(rec, pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer, desc, descSize); | 1752 test_desc(rec, pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer, desc, descSize); |
| 1753 #endif | 1753 #endif |
| 1754 | 1754 |
| 1755 proc(fTypeface, desc, context); | 1755 proc(fTypeface, desc, context); |
| 1756 } | 1756 } |
| 1757 | 1757 |
| 1758 SkGlyphCache* SkPaint::detachCache(const SkDeviceProperties* deviceProperties, | 1758 SkGlyphCache* SkPaint::detachCache(const SkSurfaceProps* surfaceProps, |
| 1759 const SkMatrix* deviceMatrix, | 1759 const SkMatrix* deviceMatrix, |
| 1760 bool ignoreGamma) const { | 1760 bool ignoreGamma) const { |
| 1761 SkGlyphCache* cache; | 1761 SkGlyphCache* cache; |
| 1762 this->descriptorProc(deviceProperties, deviceMatrix, DetachDescProc, &cache,
ignoreGamma); | 1762 this->descriptorProc(surfaceProps, deviceMatrix, DetachDescProc, &cache, ign
oreGamma); |
| 1763 return cache; | 1763 return cache; |
| 1764 } | 1764 } |
| 1765 | 1765 |
| 1766 /** | 1766 /** |
| 1767 * Expands fDeviceGamma, fPaintGamma, fContrast, and fLumBits into a mask pre-bl
end. | 1767 * Expands fDeviceGamma, fPaintGamma, fContrast, and fLumBits into a mask pre-bl
end. |
| 1768 */ | 1768 */ |
| 1769 //static | 1769 //static |
| 1770 SkMaskGamma::PreBlend SkScalerContext::GetMaskPreBlend(const SkScalerContext::Re
c& rec) { | 1770 SkMaskGamma::PreBlend SkScalerContext::GetMaskPreBlend(const SkScalerContext::Re
c& rec) { |
| 1771 SkAutoMutexAcquire ama(gMaskGammaCacheMutex); | 1771 SkAutoMutexAcquire ama(gMaskGammaCacheMutex); |
| 1772 const SkMaskGamma& maskGamma = cachedMaskGamma(rec.getContrast(), | 1772 const SkMaskGamma& maskGamma = cachedMaskGamma(rec.getContrast(), |
| (...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2282 } | 2282 } |
| 2283 #endif | 2283 #endif |
| 2284 | 2284 |
| 2285 /////////////////////////////////////////////////////////////////////////////// | 2285 /////////////////////////////////////////////////////////////////////////////// |
| 2286 | 2286 |
| 2287 static bool has_thick_frame(const SkPaint& paint) { | 2287 static bool has_thick_frame(const SkPaint& paint) { |
| 2288 return paint.getStrokeWidth() > 0 && | 2288 return paint.getStrokeWidth() > 0 && |
| 2289 paint.getStyle() != SkPaint::kFill_Style; | 2289 paint.getStyle() != SkPaint::kFill_Style; |
| 2290 } | 2290 } |
| 2291 | 2291 |
| 2292 SkTextToPathIter::SkTextToPathIter( const char text[], size_t length, | 2292 SkTextToPathIter::SkTextToPathIter(const char text[], size_t length, |
| 2293 const SkPaint& paint, | 2293 const SkPaint& paint, |
| 2294 bool applyStrokeAndPathEffects) | 2294 bool applyStrokeAndPathEffects) |
| 2295 : fPaint(paint) { | 2295 : fPaint(paint) { |
| 2296 fGlyphCacheProc = paint.getMeasureCacheProc(true); | 2296 fGlyphCacheProc = paint.getMeasureCacheProc(true); |
| 2297 | 2297 |
| 2298 fPaint.setLinearText(true); | 2298 fPaint.setLinearText(true); |
| 2299 fPaint.setMaskFilter(NULL); // don't want this affecting our path-cache lo
okup | 2299 fPaint.setMaskFilter(NULL); // don't want this affecting our path-cache lo
okup |
| 2300 | 2300 |
| 2301 if (fPaint.getPathEffect() == NULL && !has_thick_frame(fPaint)) { | 2301 if (fPaint.getPathEffect() == NULL && !has_thick_frame(fPaint)) { |
| 2302 applyStrokeAndPathEffects = false; | 2302 applyStrokeAndPathEffects = false; |
| 2303 } | 2303 } |
| 2304 | 2304 |
| 2305 // can't use our canonical size if we need to apply patheffects | 2305 // can't use our canonical size if we need to apply patheffects |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2420 } | 2420 } |
| 2421 | 2421 |
| 2422 uint32_t SkPaint::getHash() const { | 2422 uint32_t SkPaint::getHash() const { |
| 2423 // We're going to hash 10 pointers and 7 32-bit values, finishing up with fB
itfields, | 2423 // We're going to hash 10 pointers and 7 32-bit values, finishing up with fB
itfields, |
| 2424 // so fBitfields should be 10 pointers and 6 32-bit values from the start. | 2424 // so fBitfields should be 10 pointers and 6 32-bit values from the start. |
| 2425 SK_COMPILE_ASSERT(offsetof(SkPaint, fBitfields) == 10 * sizeof(void*) + 6 *
sizeof(uint32_t), | 2425 SK_COMPILE_ASSERT(offsetof(SkPaint, fBitfields) == 10 * sizeof(void*) + 6 *
sizeof(uint32_t), |
| 2426 SkPaint_notPackedTightly); | 2426 SkPaint_notPackedTightly); |
| 2427 return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(this), | 2427 return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(this), |
| 2428 offsetof(SkPaint, fBitfields) + sizeof(fBitfields
)); | 2428 offsetof(SkPaint, fBitfields) + sizeof(fBitfields
)); |
| 2429 } | 2429 } |
| OLD | NEW |