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