| 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 "SkAutoKern.h" | 9 #include "SkAutoKern.h" |
| 10 #include "SkChecksum.h" | 10 #include "SkChecksum.h" |
| (...skipping 1754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1765 | 1765 |
| 1766 | 1766 |
| 1767 /////////////////////////////////////////////////////////////////////////////// | 1767 /////////////////////////////////////////////////////////////////////////////// |
| 1768 | 1768 |
| 1769 #include "SkStream.h" | 1769 #include "SkStream.h" |
| 1770 | 1770 |
| 1771 static uintptr_t asint(const void* p) { | 1771 static uintptr_t asint(const void* p) { |
| 1772 return reinterpret_cast<uintptr_t>(p); | 1772 return reinterpret_cast<uintptr_t>(p); |
| 1773 } | 1773 } |
| 1774 | 1774 |
| 1775 union Scalar32 { | |
| 1776 SkScalar fScalar; | |
| 1777 uint32_t f32; | |
| 1778 }; | |
| 1779 | |
| 1780 static uint32_t* write_scalar(uint32_t* ptr, SkScalar value) { | |
| 1781 SkASSERT(sizeof(SkScalar) == sizeof(uint32_t)); | |
| 1782 Scalar32 tmp; | |
| 1783 tmp.fScalar = value; | |
| 1784 *ptr = tmp.f32; | |
| 1785 return ptr + 1; | |
| 1786 } | |
| 1787 | |
| 1788 static SkScalar read_scalar(const uint32_t*& ptr) { | |
| 1789 SkASSERT(sizeof(SkScalar) == sizeof(uint32_t)); | |
| 1790 Scalar32 tmp; | |
| 1791 tmp.f32 = *ptr++; | |
| 1792 return tmp.fScalar; | |
| 1793 } | |
| 1794 | |
| 1795 static uint32_t pack_4(unsigned a, unsigned b, unsigned c, unsigned d) { | 1775 static uint32_t pack_4(unsigned a, unsigned b, unsigned c, unsigned d) { |
| 1796 SkASSERT(a == (uint8_t)a); | 1776 SkASSERT(a == (uint8_t)a); |
| 1797 SkASSERT(b == (uint8_t)b); | 1777 SkASSERT(b == (uint8_t)b); |
| 1798 SkASSERT(c == (uint8_t)c); | 1778 SkASSERT(c == (uint8_t)c); |
| 1799 SkASSERT(d == (uint8_t)d); | 1779 SkASSERT(d == (uint8_t)d); |
| 1800 return (a << 24) | (b << 16) | (c << 8) | d; | 1780 return (a << 24) | (b << 16) | (c << 8) | d; |
| 1801 } | 1781 } |
| 1802 | 1782 |
| 1803 #ifdef SK_DEBUG | 1783 #ifdef SK_DEBUG |
| 1804 static void ASSERT_FITS_IN(uint32_t value, int bitCount) { | 1784 static void ASSERT_FITS_IN(uint32_t value, int bitCount) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1844 } | 1824 } |
| 1845 | 1825 |
| 1846 static FlatFlags unpack_paint_flags(SkPaint* paint, uint32_t packed) { | 1826 static FlatFlags unpack_paint_flags(SkPaint* paint, uint32_t packed) { |
| 1847 paint->setFlags(packed >> 16); | 1827 paint->setFlags(packed >> 16); |
| 1848 paint->setHinting((SkPaint::Hinting)((packed >> 14) & BPF_Mask(kHint_BPF))); | 1828 paint->setHinting((SkPaint::Hinting)((packed >> 14) & BPF_Mask(kHint_BPF))); |
| 1849 paint->setTextAlign((SkPaint::Align)((packed >> 12) & BPF_Mask(kAlign_BPF)))
; | 1829 paint->setTextAlign((SkPaint::Align)((packed >> 12) & BPF_Mask(kAlign_BPF)))
; |
| 1850 paint->setFilterQuality((SkFilterQuality)((packed >> 10) & BPF_Mask(kFilter_
BPF))); | 1830 paint->setFilterQuality((SkFilterQuality)((packed >> 10) & BPF_Mask(kFilter_
BPF))); |
| 1851 return (FlatFlags)(packed & kFlatFlagMask); | 1831 return (FlatFlags)(packed & kFlatFlagMask); |
| 1852 } | 1832 } |
| 1853 | 1833 |
| 1854 // The size of a flat paint's POD fields | |
| 1855 static const uint32_t kPODPaintSize = 5 * sizeof(SkScalar) + | |
| 1856 1 * sizeof(SkColor) + | |
| 1857 1 * sizeof(uint16_t) + | |
| 1858 6 * sizeof(uint8_t); | |
| 1859 | |
| 1860 /* To save space/time, we analyze the paint, and write a truncated version of | 1834 /* To save space/time, we analyze the paint, and write a truncated version of |
| 1861 it if there are not tricky elements like shaders, etc. | 1835 it if there are not tricky elements like shaders, etc. |
| 1862 */ | 1836 */ |
| 1863 void SkPaint::flatten(SkWriteBuffer& buffer) const { | 1837 void SkPaint::flatten(SkWriteBuffer& buffer) const { |
| 1864 uint8_t flatFlags = 0; | 1838 uint8_t flatFlags = 0; |
| 1865 if (this->getTypeface()) { | 1839 if (this->getTypeface()) { |
| 1866 flatFlags |= kHasTypeface_FlatFlag; | 1840 flatFlags |= kHasTypeface_FlatFlag; |
| 1867 } | 1841 } |
| 1868 if (asint(this->getPathEffect()) | | 1842 if (asint(this->getPathEffect()) | |
| 1869 asint(this->getShader()) | | 1843 asint(this->getShader()) | |
| 1870 asint(this->getXfermode()) | | 1844 asint(this->getXfermode()) | |
| 1871 asint(this->getMaskFilter()) | | 1845 asint(this->getMaskFilter()) | |
| 1872 asint(this->getColorFilter()) | | 1846 asint(this->getColorFilter()) | |
| 1873 asint(this->getRasterizer()) | | 1847 asint(this->getRasterizer()) | |
| 1874 asint(this->getLooper()) | | 1848 asint(this->getLooper()) | |
| 1875 asint(this->getImageFilter())) { | 1849 asint(this->getImageFilter())) { |
| 1876 flatFlags |= kHasEffects_FlatFlag; | 1850 flatFlags |= kHasEffects_FlatFlag; |
| 1877 } | 1851 } |
| 1878 | 1852 |
| 1879 SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize); | 1853 buffer.writeScalar(this->getTextSize()); |
| 1880 uint32_t* ptr = buffer.reserve(kPODPaintSize); | 1854 buffer.writeScalar(this->getTextScaleX()); |
| 1855 buffer.writeScalar(this->getTextSkewX()); |
| 1856 buffer.writeScalar(this->getStrokeWidth()); |
| 1857 buffer.writeScalar(this->getStrokeMiter()); |
| 1858 buffer.writeColor(this->getColor()); |
| 1881 | 1859 |
| 1882 ptr = write_scalar(ptr, this->getTextSize()); | 1860 buffer.writeUInt(pack_paint_flags(this->getFlags(), this->getHinting(), this
->getTextAlign(), |
| 1883 ptr = write_scalar(ptr, this->getTextScaleX()); | 1861 this->getFilterQuality(), flatFlags)); |
| 1884 ptr = write_scalar(ptr, this->getTextSkewX()); | 1862 buffer.writeUInt(pack_4(this->getStrokeCap(), this->getStrokeJoin(), |
| 1885 ptr = write_scalar(ptr, this->getStrokeWidth()); | 1863 this->getStyle(), this->getTextEncoding())); |
| 1886 ptr = write_scalar(ptr, this->getStrokeMiter()); | |
| 1887 *ptr++ = this->getColor(); | |
| 1888 | |
| 1889 *ptr++ = pack_paint_flags(this->getFlags(), this->getHinting(), this->getTex
tAlign(), | |
| 1890 this->getFilterQuality(), flatFlags); | |
| 1891 *ptr++ = pack_4(this->getStrokeCap(), this->getStrokeJoin(), | |
| 1892 this->getStyle(), this->getTextEncoding()); | |
| 1893 | 1864 |
| 1894 // now we're done with ptr and the (pre)reserved space. If we need to write | 1865 // now we're done with ptr and the (pre)reserved space. If we need to write |
| 1895 // additional fields, use the buffer directly | 1866 // additional fields, use the buffer directly |
| 1896 if (flatFlags & kHasTypeface_FlatFlag) { | 1867 if (flatFlags & kHasTypeface_FlatFlag) { |
| 1897 buffer.writeTypeface(this->getTypeface()); | 1868 buffer.writeTypeface(this->getTypeface()); |
| 1898 } | 1869 } |
| 1899 if (flatFlags & kHasEffects_FlatFlag) { | 1870 if (flatFlags & kHasEffects_FlatFlag) { |
| 1900 buffer.writeFlattenable(this->getPathEffect()); | 1871 buffer.writeFlattenable(this->getPathEffect()); |
| 1901 buffer.writeFlattenable(this->getShader()); | 1872 buffer.writeFlattenable(this->getShader()); |
| 1902 buffer.writeFlattenable(this->getXfermode()); | 1873 buffer.writeFlattenable(this->getXfermode()); |
| 1903 buffer.writeFlattenable(this->getMaskFilter()); | 1874 buffer.writeFlattenable(this->getMaskFilter()); |
| 1904 buffer.writeFlattenable(this->getColorFilter()); | 1875 buffer.writeFlattenable(this->getColorFilter()); |
| 1905 buffer.writeFlattenable(this->getRasterizer()); | 1876 buffer.writeFlattenable(this->getRasterizer()); |
| 1906 buffer.writeFlattenable(this->getLooper()); | 1877 buffer.writeFlattenable(this->getLooper()); |
| 1907 buffer.writeFlattenable(this->getImageFilter()); | 1878 buffer.writeFlattenable(this->getImageFilter()); |
| 1908 } | 1879 } |
| 1909 } | 1880 } |
| 1910 | 1881 |
| 1911 void SkPaint::unflatten(SkReadBuffer& buffer) { | 1882 void SkPaint::unflatten(SkReadBuffer& buffer) { |
| 1912 SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize); | 1883 this->setTextSize(buffer.readScalar()); |
| 1913 if (!buffer.validateAvailable(kPODPaintSize)) { | 1884 this->setTextScaleX(buffer.readScalar()); |
| 1914 return; | 1885 this->setTextSkewX(buffer.readScalar()); |
| 1915 } | 1886 this->setStrokeWidth(buffer.readScalar()); |
| 1916 const void* podData = buffer.skip(kPODPaintSize); | 1887 this->setStrokeMiter(buffer.readScalar()); |
| 1917 const uint32_t* pod = reinterpret_cast<const uint32_t*>(podData); | 1888 this->setColor(buffer.readColor()); |
| 1918 | 1889 |
| 1919 // the order we read must match the order we wrote in flatten() | 1890 unsigned flatFlags = unpack_paint_flags(this, buffer.readUInt()); |
| 1920 this->setTextSize(read_scalar(pod)); | |
| 1921 this->setTextScaleX(read_scalar(pod)); | |
| 1922 this->setTextSkewX(read_scalar(pod)); | |
| 1923 this->setStrokeWidth(read_scalar(pod)); | |
| 1924 this->setStrokeMiter(read_scalar(pod)); | |
| 1925 this->setColor(*pod++); | |
| 1926 | 1891 |
| 1927 unsigned flatFlags = unpack_paint_flags(this, *pod++); | 1892 uint32_t tmp = buffer.readUInt(); |
| 1928 | |
| 1929 uint32_t tmp = *pod++; | |
| 1930 this->setStrokeCap(static_cast<Cap>((tmp >> 24) & 0xFF)); | 1893 this->setStrokeCap(static_cast<Cap>((tmp >> 24) & 0xFF)); |
| 1931 this->setStrokeJoin(static_cast<Join>((tmp >> 16) & 0xFF)); | 1894 this->setStrokeJoin(static_cast<Join>((tmp >> 16) & 0xFF)); |
| 1932 this->setStyle(static_cast<Style>((tmp >> 8) & 0xFF)); | 1895 this->setStyle(static_cast<Style>((tmp >> 8) & 0xFF)); |
| 1933 this->setTextEncoding(static_cast<TextEncoding>((tmp >> 0) & 0xFF)); | 1896 this->setTextEncoding(static_cast<TextEncoding>((tmp >> 0) & 0xFF)); |
| 1934 | 1897 |
| 1935 if (flatFlags & kHasTypeface_FlatFlag) { | 1898 if (flatFlags & kHasTypeface_FlatFlag) { |
| 1936 this->setTypeface(buffer.readTypeface()); | 1899 this->setTypeface(buffer.readTypeface()); |
| 1937 } else { | 1900 } else { |
| 1938 this->setTypeface(nullptr); | 1901 this->setTypeface(nullptr); |
| 1939 } | 1902 } |
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2371 } | 2334 } |
| 2372 | 2335 |
| 2373 uint32_t SkPaint::getHash() const { | 2336 uint32_t SkPaint::getHash() const { |
| 2374 // We're going to hash 10 pointers and 7 32-bit values, finishing up with fB
itfields, | 2337 // We're going to hash 10 pointers and 7 32-bit values, finishing up with fB
itfields, |
| 2375 // so fBitfields should be 10 pointers and 6 32-bit values from the start. | 2338 // so fBitfields should be 10 pointers and 6 32-bit values from the start. |
| 2376 static_assert(offsetof(SkPaint, fBitfields) == 9 * sizeof(void*) + 6 * sizeo
f(uint32_t), | 2339 static_assert(offsetof(SkPaint, fBitfields) == 9 * sizeof(void*) + 6 * sizeo
f(uint32_t), |
| 2377 "SkPaint_notPackedTightly"); | 2340 "SkPaint_notPackedTightly"); |
| 2378 return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(this), | 2341 return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(this), |
| 2379 offsetof(SkPaint, fBitfields) + sizeof(fBitfields
)); | 2342 offsetof(SkPaint, fBitfields) + sizeof(fBitfields
)); |
| 2380 } | 2343 } |
| OLD | NEW |