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" |
(...skipping 1579 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1590 break; | 1590 break; |
1591 } | 1591 } |
1592 } | 1592 } |
1593 | 1593 |
1594 #define MIN_SIZE_FOR_EFFECT_BUFFER 1024 | 1594 #define MIN_SIZE_FOR_EFFECT_BUFFER 1024 |
1595 | 1595 |
1596 #ifdef SK_DEBUG | 1596 #ifdef SK_DEBUG |
1597 #define TEST_DESC | 1597 #define TEST_DESC |
1598 #endif | 1598 #endif |
1599 | 1599 |
| 1600 static void write_out_descriptor(SkDescriptor* desc, const SkScalerContext::Rec&
rec, |
| 1601 const SkPathEffect* pe, SkWriteBuffer* peBuffer
, |
| 1602 const SkMaskFilter* mf, SkWriteBuffer* mfBuffer
, |
| 1603 const SkRasterizer* ra, SkWriteBuffer* raBuffer
, |
| 1604 size_t descSize) { |
| 1605 desc->init(); |
| 1606 desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); |
| 1607 |
| 1608 if (pe) { |
| 1609 add_flattenable(desc, kPathEffect_SkDescriptorTag, peBuffer); |
| 1610 } |
| 1611 if (mf) { |
| 1612 add_flattenable(desc, kMaskFilter_SkDescriptorTag, mfBuffer); |
| 1613 } |
| 1614 if (ra) { |
| 1615 add_flattenable(desc, kRasterizer_SkDescriptorTag, raBuffer); |
| 1616 } |
| 1617 |
| 1618 desc->computeChecksum(); |
| 1619 } |
| 1620 |
| 1621 static size_t fill_out_rec(const SkPaint& paint, SkScalerContext::Rec* rec, |
| 1622 const SkDeviceProperties* deviceProperties, |
| 1623 const SkMatrix* deviceMatrix, bool ignoreGamma, |
| 1624 const SkPathEffect* pe, SkWriteBuffer* peBuffer, |
| 1625 const SkMaskFilter* mf, SkWriteBuffer* mfBuffer, |
| 1626 const SkRasterizer* ra, SkWriteBuffer* raBuffer) { |
| 1627 SkScalerContext::MakeRec(paint, deviceProperties, deviceMatrix, rec); |
| 1628 if (ignoreGamma) { |
| 1629 rec->ignorePreBlend(); |
| 1630 } |
| 1631 |
| 1632 int entryCount = 1; |
| 1633 size_t descSize = sizeof(*rec); |
| 1634 |
| 1635 if (pe) { |
| 1636 peBuffer->writeFlattenable(pe); |
| 1637 descSize += peBuffer->bytesWritten(); |
| 1638 entryCount += 1; |
| 1639 rec->fMaskFormat = SkMask::kA8_Format; // force antialiasing when we do
the scan conversion |
| 1640 // seems like we could support kLCD as well at this point... |
| 1641 } |
| 1642 if (mf) { |
| 1643 mfBuffer->writeFlattenable(mf); |
| 1644 descSize += mfBuffer->bytesWritten(); |
| 1645 entryCount += 1; |
| 1646 rec->fMaskFormat = SkMask::kA8_Format; // force antialiasing with mask
filters |
| 1647 /* Pre-blend is not currently applied to filtered text. |
| 1648 The primary filter is blur, for which contrast makes no sense, |
| 1649 and for which the destination guess error is more visible. |
| 1650 Also, all existing users of blur have calibrated for linear. */ |
| 1651 rec->ignorePreBlend(); |
| 1652 } |
| 1653 if (ra) { |
| 1654 raBuffer->writeFlattenable(ra); |
| 1655 descSize += raBuffer->bytesWritten(); |
| 1656 entryCount += 1; |
| 1657 rec->fMaskFormat = SkMask::kA8_Format; // force antialiasing when we do
the scan conversion |
| 1658 } |
| 1659 |
| 1660 /////////////////////////////////////////////////////////////////////////// |
| 1661 // Now that we're done tweaking the rec, call the PostMakeRec cleanup |
| 1662 SkScalerContext::PostMakeRec(paint, rec); |
| 1663 |
| 1664 descSize += SkDescriptor::ComputeOverhead(entryCount); |
| 1665 return descSize; |
| 1666 } |
| 1667 |
| 1668 #ifdef TEST_DESC |
| 1669 static void test_desc(const SkScalerContext::Rec& rec, |
| 1670 const SkPathEffect* pe, SkWriteBuffer* peBuffer, |
| 1671 const SkMaskFilter* mf, SkWriteBuffer* mfBuffer, |
| 1672 const SkRasterizer* ra, SkWriteBuffer* raBuffer, |
| 1673 const SkDescriptor* desc, size_t descSize) { |
| 1674 // Check that we completely write the bytes in desc (our key), and that |
| 1675 // there are no uninitialized bytes. If there were, then we would get |
| 1676 // false-misses (or worse, false-hits) in our fontcache. |
| 1677 // |
| 1678 // We do this buy filling 2 others, one with 0s and the other with 1s |
| 1679 // and create those, and then check that all 3 are identical. |
| 1680 SkAutoDescriptor ad1(descSize); |
| 1681 SkAutoDescriptor ad2(descSize); |
| 1682 SkDescriptor* desc1 = ad1.getDesc(); |
| 1683 SkDescriptor* desc2 = ad2.getDesc(); |
| 1684 |
| 1685 memset(desc1, 0x00, descSize); |
| 1686 memset(desc2, 0xFF, descSize); |
| 1687 |
| 1688 desc1->init(); |
| 1689 desc2->init(); |
| 1690 desc1->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); |
| 1691 desc2->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); |
| 1692 |
| 1693 if (pe) { |
| 1694 add_flattenable(desc1, kPathEffect_SkDescriptorTag, peBuffer); |
| 1695 add_flattenable(desc2, kPathEffect_SkDescriptorTag, peBuffer); |
| 1696 } |
| 1697 if (mf) { |
| 1698 add_flattenable(desc1, kMaskFilter_SkDescriptorTag, mfBuffer); |
| 1699 add_flattenable(desc2, kMaskFilter_SkDescriptorTag, mfBuffer); |
| 1700 } |
| 1701 if (ra) { |
| 1702 add_flattenable(desc1, kRasterizer_SkDescriptorTag, raBuffer); |
| 1703 add_flattenable(desc2, kRasterizer_SkDescriptorTag, raBuffer); |
| 1704 } |
| 1705 |
| 1706 SkASSERT(descSize == desc1->getLength()); |
| 1707 SkASSERT(descSize == desc2->getLength()); |
| 1708 desc1->computeChecksum(); |
| 1709 desc2->computeChecksum(); |
| 1710 SkASSERT(!memcmp(desc, desc1, descSize)); |
| 1711 SkASSERT(!memcmp(desc, desc2, descSize)); |
| 1712 } |
| 1713 #endif |
| 1714 |
| 1715 /* see the note on ignoreGamma on descriptorProc */ |
| 1716 const SkData* SkPaint::getDescriptor(const SkDeviceProperties* deviceProperties, |
| 1717 const SkMatrix* deviceMatrix, bool ignoreGa
mma) const { |
| 1718 SkScalerContext::Rec rec; |
| 1719 |
| 1720 SkPathEffect* pe = this->getPathEffect(); |
| 1721 SkMaskFilter* mf = this->getMaskFilter(); |
| 1722 SkRasterizer* ra = this->getRasterizer(); |
| 1723 |
| 1724 SkWriteBuffer peBuffer, mfBuffer, raBuffer; |
| 1725 size_t descSize = fill_out_rec(*this, &rec, deviceProperties, deviceMatrix,
ignoreGamma, |
| 1726 pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer); |
| 1727 |
| 1728 SkASSERT(SkAlign4(descSize) == descSize); |
| 1729 SkData* data = SkData::NewUninitialized(descSize); |
| 1730 SkDescriptor* desc = reinterpret_cast<SkDescriptor*>(data->writable_da
ta()); |
| 1731 |
| 1732 write_out_descriptor(desc, rec, pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer,
descSize); |
| 1733 |
| 1734 SkASSERT(descSize == desc->getLength()); |
| 1735 |
| 1736 #ifdef TEST_DESC |
| 1737 test_desc(rec, pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer, desc, descSize); |
| 1738 #endif |
| 1739 |
| 1740 return data; |
| 1741 } |
| 1742 |
1600 /* | 1743 /* |
1601 * ignoreGamma tells us that the caller just wants metrics that are unaffected | 1744 * ignoreGamma tells us that the caller just wants metrics that are unaffected |
1602 * by gamma correction, so we set the rec to ignore preblend: i.e. gamma = 1, | 1745 * by gamma correction, so we set the rec to ignore preblend: i.e. gamma = 1, |
1603 * contrast = 0, luminanceColor = transparent black. | 1746 * contrast = 0, luminanceColor = transparent black. |
1604 */ | 1747 */ |
1605 void SkPaint::descriptorProc(const SkDeviceProperties* deviceProperties, | 1748 void SkPaint::descriptorProc(const SkDeviceProperties* deviceProperties, |
1606 const SkMatrix* deviceMatrix, | 1749 const SkMatrix* deviceMatrix, |
1607 void (*proc)(SkTypeface*, const SkDescriptor*, void
*), | 1750 void (*proc)(SkTypeface*, const SkDescriptor*, void
*), |
1608 void* context, bool ignoreGamma) const { | 1751 void* context, bool ignoreGamma) const { |
1609 SkScalerContext::Rec rec; | 1752 SkScalerContext::Rec rec; |
1610 | 1753 |
1611 SkScalerContext::MakeRec(*this, deviceProperties, deviceMatrix, &rec); | |
1612 if (ignoreGamma) { | |
1613 rec.ignorePreBlend(); | |
1614 } | |
1615 | |
1616 size_t descSize = sizeof(rec); | |
1617 int entryCount = 1; | |
1618 SkPathEffect* pe = this->getPathEffect(); | 1754 SkPathEffect* pe = this->getPathEffect(); |
1619 SkMaskFilter* mf = this->getMaskFilter(); | 1755 SkMaskFilter* mf = this->getMaskFilter(); |
1620 SkRasterizer* ra = this->getRasterizer(); | 1756 SkRasterizer* ra = this->getRasterizer(); |
1621 | 1757 |
1622 SkWriteBuffer peBuffer, mfBuffer, raBuffer; | 1758 SkWriteBuffer peBuffer, mfBuffer, raBuffer; |
1623 | 1759 size_t descSize = fill_out_rec(*this, &rec, deviceProperties, deviceMatrix,
ignoreGamma, |
1624 if (pe) { | 1760 pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer); |
1625 peBuffer.writeFlattenable(pe); | |
1626 descSize += peBuffer.bytesWritten(); | |
1627 entryCount += 1; | |
1628 rec.fMaskFormat = SkMask::kA8_Format; // force antialiasing when we do
the scan conversion | |
1629 // seems like we could support kLCD as well at this point... | |
1630 } | |
1631 if (mf) { | |
1632 mfBuffer.writeFlattenable(mf); | |
1633 descSize += mfBuffer.bytesWritten(); | |
1634 entryCount += 1; | |
1635 rec.fMaskFormat = SkMask::kA8_Format; // force antialiasing with maskf
ilters | |
1636 /* Pre-blend is not currently applied to filtered text. | |
1637 The primary filter is blur, for which contrast makes no sense, | |
1638 and for which the destination guess error is more visible. | |
1639 Also, all existing users of blur have calibrated for linear. */ | |
1640 rec.ignorePreBlend(); | |
1641 } | |
1642 if (ra) { | |
1643 raBuffer.writeFlattenable(ra); | |
1644 descSize += raBuffer.bytesWritten(); | |
1645 entryCount += 1; | |
1646 rec.fMaskFormat = SkMask::kA8_Format; // force antialiasing when we do
the scan conversion | |
1647 } | |
1648 | |
1649 /////////////////////////////////////////////////////////////////////////// | |
1650 // Now that we're done tweaking the rec, call the PostMakeRec cleanup | |
1651 SkScalerContext::PostMakeRec(*this, &rec); | |
1652 | |
1653 descSize += SkDescriptor::ComputeOverhead(entryCount); | |
1654 | 1761 |
1655 SkAutoDescriptor ad(descSize); | 1762 SkAutoDescriptor ad(descSize); |
1656 SkDescriptor* desc = ad.getDesc(); | 1763 SkDescriptor* desc = ad.getDesc(); |
1657 | 1764 |
1658 desc->init(); | 1765 write_out_descriptor(desc, rec, pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer,
descSize); |
1659 desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); | |
1660 | |
1661 if (pe) { | |
1662 add_flattenable(desc, kPathEffect_SkDescriptorTag, &peBuffer); | |
1663 } | |
1664 if (mf) { | |
1665 add_flattenable(desc, kMaskFilter_SkDescriptorTag, &mfBuffer); | |
1666 } | |
1667 if (ra) { | |
1668 add_flattenable(desc, kRasterizer_SkDescriptorTag, &raBuffer); | |
1669 } | |
1670 | 1766 |
1671 SkASSERT(descSize == desc->getLength()); | 1767 SkASSERT(descSize == desc->getLength()); |
1672 desc->computeChecksum(); | |
1673 | 1768 |
1674 #ifdef TEST_DESC | 1769 #ifdef TEST_DESC |
1675 { | 1770 test_desc(rec, pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer, desc, descSize); |
1676 // Check that we completely write the bytes in desc (our key), and that | |
1677 // there are no uninitialized bytes. If there were, then we would get | |
1678 // false-misses (or worse, false-hits) in our fontcache. | |
1679 // | |
1680 // We do this buy filling 2 others, one with 0s and the other with 1s | |
1681 // and create those, and then check that all 3 are identical. | |
1682 SkAutoDescriptor ad1(descSize); | |
1683 SkAutoDescriptor ad2(descSize); | |
1684 SkDescriptor* desc1 = ad1.getDesc(); | |
1685 SkDescriptor* desc2 = ad2.getDesc(); | |
1686 | |
1687 memset(desc1, 0x00, descSize); | |
1688 memset(desc2, 0xFF, descSize); | |
1689 | |
1690 desc1->init(); | |
1691 desc2->init(); | |
1692 desc1->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); | |
1693 desc2->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); | |
1694 | |
1695 if (pe) { | |
1696 add_flattenable(desc1, kPathEffect_SkDescriptorTag, &peBuffer); | |
1697 add_flattenable(desc2, kPathEffect_SkDescriptorTag, &peBuffer); | |
1698 } | |
1699 if (mf) { | |
1700 add_flattenable(desc1, kMaskFilter_SkDescriptorTag, &mfBuffer); | |
1701 add_flattenable(desc2, kMaskFilter_SkDescriptorTag, &mfBuffer); | |
1702 } | |
1703 if (ra) { | |
1704 add_flattenable(desc1, kRasterizer_SkDescriptorTag, &raBuffer); | |
1705 add_flattenable(desc2, kRasterizer_SkDescriptorTag, &raBuffer); | |
1706 } | |
1707 | |
1708 SkASSERT(descSize == desc1->getLength()); | |
1709 SkASSERT(descSize == desc2->getLength()); | |
1710 desc1->computeChecksum(); | |
1711 desc2->computeChecksum(); | |
1712 SkASSERT(!memcmp(desc, desc1, descSize)); | |
1713 SkASSERT(!memcmp(desc, desc2, descSize)); | |
1714 } | |
1715 #endif | 1771 #endif |
1716 | 1772 |
1717 proc(fTypeface, desc, context); | 1773 proc(fTypeface, desc, context); |
1718 } | 1774 } |
1719 | 1775 |
1720 SkGlyphCache* SkPaint::detachCache(const SkDeviceProperties* deviceProperties, | 1776 SkGlyphCache* SkPaint::detachCache(const SkDeviceProperties* deviceProperties, |
1721 const SkMatrix* deviceMatrix, | 1777 const SkMatrix* deviceMatrix, |
1722 bool ignoreGamma) const { | 1778 bool ignoreGamma) const { |
1723 SkGlyphCache* cache; | 1779 SkGlyphCache* cache; |
1724 this->descriptorProc(deviceProperties, deviceMatrix, DetachDescProc, &cache,
ignoreGamma); | 1780 this->descriptorProc(deviceProperties, deviceMatrix, DetachDescProc, &cache,
ignoreGamma); |
(...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2384 } | 2440 } |
2385 | 2441 |
2386 uint32_t SkPaint::getHash() const { | 2442 uint32_t SkPaint::getHash() const { |
2387 // We're going to hash 10 pointers and 7 32-bit values, finishing up with fB
itfields, | 2443 // We're going to hash 10 pointers and 7 32-bit values, finishing up with fB
itfields, |
2388 // so fBitfields should be 10 pointers and 6 32-bit values from the start. | 2444 // so fBitfields should be 10 pointers and 6 32-bit values from the start. |
2389 SK_COMPILE_ASSERT(offsetof(SkPaint, fBitfields) == 10 * sizeof(void*) + 6 *
sizeof(uint32_t), | 2445 SK_COMPILE_ASSERT(offsetof(SkPaint, fBitfields) == 10 * sizeof(void*) + 6 *
sizeof(uint32_t), |
2390 SkPaint_notPackedTightly); | 2446 SkPaint_notPackedTightly); |
2391 return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(this), | 2447 return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(this), |
2392 offsetof(SkPaint, fBitfields) + sizeof(fBitfields
)); | 2448 offsetof(SkPaint, fBitfields) + sizeof(fBitfields
)); |
2393 } | 2449 } |
OLD | NEW |