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 |