Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
| 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 "SkGpuDevice.h" | 8 #include "SkGpuDevice.h" |
| 9 | 9 |
| 10 #include "effects/GrTextureDomainEffect.h" | 10 #include "effects/GrTextureDomainEffect.h" |
| (...skipping 1666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1677 procs->fFontScaler); | 1677 procs->fFontScaler); |
| 1678 } | 1678 } |
| 1679 | 1679 |
| 1680 SkDrawProcs* SkGpuDevice::initDrawForText(GrTextContext* context) { | 1680 SkDrawProcs* SkGpuDevice::initDrawForText(GrTextContext* context) { |
| 1681 | 1681 |
| 1682 // deferred allocation | 1682 // deferred allocation |
| 1683 if (NULL == fDrawProcs) { | 1683 if (NULL == fDrawProcs) { |
| 1684 fDrawProcs = SkNEW(GrSkDrawProcs); | 1684 fDrawProcs = SkNEW(GrSkDrawProcs); |
| 1685 fDrawProcs->fD1GProc = SkGPU_Draw1Glyph; | 1685 fDrawProcs->fD1GProc = SkGPU_Draw1Glyph; |
| 1686 fDrawProcs->fContext = fContext; | 1686 fDrawProcs->fContext = fContext; |
| 1687 #if SK_DISTANCEFIELD_FONTS | |
| 1688 fDrawProcs->fFlags = 0; | |
| 1689 #endif | |
| 1690 } | 1687 } |
| 1691 | 1688 |
| 1692 // init our (and GL's) state | 1689 // init our (and GL's) state |
| 1693 fDrawProcs->fTextContext = context; | 1690 fDrawProcs->fTextContext = context; |
| 1694 fDrawProcs->fFontScaler = NULL; | 1691 fDrawProcs->fFontScaler = NULL; |
| 1695 return fDrawProcs; | 1692 return fDrawProcs; |
| 1696 } | 1693 } |
| 1697 | 1694 |
| 1698 void SkGpuDevice::drawText(const SkDraw& draw, const void* text, | 1695 void SkGpuDevice::drawText(const SkDraw& draw, const void* text, |
| 1699 size_t byteLength, SkScalar x, SkScalar y, | 1696 size_t byteLength, SkScalar x, SkScalar y, |
| 1700 const SkPaint& paint) { | 1697 const SkPaint& paint) { |
| 1701 CHECK_SHOULD_DRAW(draw, false); | 1698 CHECK_SHOULD_DRAW(draw, false); |
| 1702 | 1699 |
| 1703 if (fContext->getMatrix().hasPerspective()) { | 1700 if (draw.shouldDrawTextAsPaths(paint, fContext->getMatrix())) { |
| 1704 // this guy will just call our drawPath() | 1701 draw.drawText_asPaths((const char*)text, byteLength, x, y, paint); |
| 1705 draw.drawText((const char*)text, byteLength, x, y, paint); | 1702 #if SK_DISTANCEFIELD_FONTS |
| 1703 } else if (!paint.getRasterizer()) { | |
| 1704 drawDFText((const char *)text, byteLength, x, y, paint); | |
| 1705 #endif | |
| 1706 } else { | 1706 } else { |
| 1707 SkDraw myDraw(draw); | 1707 SkDraw myDraw(draw); |
| 1708 | 1708 |
| 1709 GrPaint grPaint; | 1709 GrPaint grPaint; |
| 1710 if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) { | 1710 if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) { |
| 1711 return; | 1711 return; |
| 1712 } | 1712 } |
| 1713 #if SK_DISTANCEFIELD_FONTS | 1713 |
| 1714 if (paint.getRasterizer()) { | 1714 GrBitmapTextContext context(fContext, grPaint, paint.getColor()); |
| 1715 #endif | 1715 myDraw.fProcs = this->initDrawForText(&context); |
| 1716 GrBitmapTextContext context(fContext, grPaint, paint.getColor()); | 1716 this->INHERITED::drawText(myDraw, text, byteLength, x, y, paint); |
| 1717 myDraw.fProcs = this->initDrawForText(&context); | |
| 1718 this->INHERITED::drawText(myDraw, text, byteLength, x, y, paint); | |
| 1719 #if SK_DISTANCEFIELD_FONTS | |
| 1720 } else { | |
| 1721 GrDistanceFieldTextContext context(fContext, grPaint, paint.getColor (), | |
| 1722 paint.getTextSize()/SkDrawProcs:: kBaseDFFontSize); | |
| 1723 myDraw.fProcs = this->initDrawForText(&context); | |
| 1724 fDrawProcs->fFlags |= SkDrawProcs::kSkipBakedGlyphTransform_Flag; | |
| 1725 fDrawProcs->fFlags |= SkDrawProcs::kUseScaledGlyphs_Flag; | |
| 1726 this->INHERITED::drawText(myDraw, text, byteLength, x, y, paint); | |
| 1727 fDrawProcs->fFlags = 0; | |
| 1728 } | |
| 1729 #endif | |
| 1730 } | 1717 } |
| 1731 } | 1718 } |
| 1732 | 1719 |
| 1720 static const int kBaseDFFontSize = 32; | |
| 1721 | |
| 1722 void SkGpuDevice::drawDFText(const char text[], size_t byteLength, | |
| 1723 SkScalar x, SkScalar y, | |
| 1724 const SkPaint& paint) { | |
| 1725 GrPaint grPaint; | |
| 1726 if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) { | |
| 1727 return; | |
| 1728 } | |
| 1729 | |
| 1730 SkASSERT(byteLength == 0 || text != NULL); | |
| 1731 | |
| 1732 SkDEBUGCODE(this->validate();) | |
| 1733 | |
| 1734 // nothing to draw | |
| 1735 if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/) { | |
| 1736 return; | |
| 1737 } | |
| 1738 | |
| 1739 SkScalar sizeRatio = paint.getTextSize()/kBaseDFFontSize; | |
| 1740 GrDistanceFieldTextContext context(fContext, grPaint, paint.getColor(), size Ratio); | |
| 1741 | |
| 1742 SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc(); | |
| 1743 | |
| 1744 SkPaint paintCopy = paint; | |
| 1745 paintCopy.setTextSize(SkIntToScalar(kBaseDFFontSize)); | |
| 1746 paintCopy.setLCDRenderText(false); | |
| 1747 paintCopy.setAutohinted(false); | |
| 1748 paintCopy.setSubpixelText(false); | |
| 1749 SkAutoGlyphCache autoCache(paintCopy, &this->fLeakyProperties, NULL); | |
| 1750 SkGlyphCache* cache = autoCache.getCache(); | |
| 1751 | |
| 1752 // need to measure first | |
| 1753 // TODO - generate positions and pre-load cache as well? | |
| 1754 const char* stop = text + byteLength; | |
| 1755 if (paint.getTextAlign() != SkPaint::kLeft_Align) { | |
| 1756 SkFixed stopX = 0; | |
| 1757 SkFixed stopY = 0; | |
| 1758 | |
| 1759 const char* textPtr = text; | |
| 1760 while (textPtr < stop) { | |
| 1761 // don't need x, y here, since all subpixel variants will have the | |
| 1762 // same advance | |
| 1763 const SkGlyph& glyph = glyphCacheProc(cache, &textPtr, 0, 0); | |
| 1764 | |
| 1765 stopX += glyph.fAdvanceX; | |
| 1766 stopY += glyph.fAdvanceY; | |
| 1767 } | |
| 1768 SkASSERT(textPtr == stop); | |
| 1769 | |
| 1770 SkScalar alignX = SkFixedToScalar(stopX)*sizeRatio; | |
| 1771 SkScalar alignY = SkFixedToScalar(stopY)*sizeRatio; | |
| 1772 | |
| 1773 if (paint.getTextAlign() == SkPaint::kCenter_Align) { | |
| 1774 alignX = SkScalarHalf(alignX); | |
| 1775 alignY = SkScalarHalf(alignY); | |
| 1776 } | |
| 1777 | |
| 1778 x -= alignX; | |
| 1779 y -= alignY; | |
| 1780 } | |
| 1781 | |
| 1782 SkFixed fx = SkScalarToFixed(x) + SK_FixedHalf; | |
| 1783 SkFixed fy = SkScalarToFixed(y) + SK_FixedHalf; | |
| 1784 SkFixed fixedScale = SkScalarToFixed(sizeRatio); | |
| 1785 GrFontScaler* fontScaler = get_gr_font_scaler(cache); | |
| 1786 while (text < stop) { | |
| 1787 const SkGlyph& glyph = glyphCacheProc(cache, &text, fx, fy); | |
| 1788 | |
| 1789 if (glyph.fWidth) { | |
| 1790 context.drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(), | |
| 1791 glyph.getSubXFixed(), | |
| 1792 glyph.getSubYFixed()), | |
| 1793 SkFixedFloorToFixed(fx), | |
| 1794 SkFixedFloorToFixed(fy), | |
| 1795 fontScaler); | |
| 1796 } | |
| 1797 | |
| 1798 fx += SkFixedMul_portable(glyph.fAdvanceX, fixedScale); | |
| 1799 fy += SkFixedMul_portable(glyph.fAdvanceY, fixedScale); | |
| 1800 } | |
| 1801 } | |
| 1802 | |
| 1733 void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text, | 1803 void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text, |
| 1734 size_t byteLength, const SkScalar pos[], | 1804 size_t byteLength, const SkScalar pos[], |
| 1735 SkScalar constY, int scalarsPerPos, | 1805 SkScalar constY, int scalarsPerPos, |
| 1736 const SkPaint& paint) { | 1806 const SkPaint& paint) { |
| 1737 CHECK_SHOULD_DRAW(draw, false); | 1807 CHECK_SHOULD_DRAW(draw, false); |
| 1738 | 1808 |
| 1739 if (fContext->getMatrix().hasPerspective()) { | 1809 if (draw.shouldDrawTextAsPaths(paint, fContext->getMatrix())) { |
| 1740 // this guy will just call our drawPath() | 1810 // this guy will just call our drawPath() |
| 1741 draw.drawPosText((const char*)text, byteLength, pos, constY, | 1811 draw.drawPosText_asPaths((const char*)text, byteLength, pos, constY, |
| 1742 scalarsPerPos, paint); | 1812 scalarsPerPos, paint); |
| 1813 #if SK_DISTANCEFIELD_FONTS | |
| 1814 } else if (!paint.getRasterizer()) { | |
| 1815 drawPosDFText((const char *)text, byteLength, pos, constY, scalarsPerPos , paint); | |
|
bsalomon
2013/11/25 20:50:22
this->
| |
| 1816 #endif | |
| 1743 } else { | 1817 } else { |
| 1744 SkDraw myDraw(draw); | 1818 SkDraw myDraw(draw); |
| 1745 | 1819 |
| 1746 GrPaint grPaint; | 1820 GrPaint grPaint; |
| 1747 if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) { | 1821 if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) { |
| 1748 return; | 1822 return; |
| 1749 } | 1823 } |
| 1750 #if SK_DISTANCEFIELD_FONTS | 1824 GrBitmapTextContext context(fContext, grPaint, paint.getColor()); |
| 1751 if (paint.getRasterizer()) { | 1825 myDraw.fProcs = this->initDrawForText(&context); |
| 1752 #endif | 1826 this->INHERITED::drawPosText(myDraw, text, byteLength, pos, constY, |
| 1753 GrBitmapTextContext context(fContext, grPaint, paint.getColor()); | 1827 scalarsPerPos, paint); |
| 1754 myDraw.fProcs = this->initDrawForText(&context); | |
| 1755 this->INHERITED::drawPosText(myDraw, text, byteLength, pos, constY, | |
| 1756 scalarsPerPos, paint); | |
| 1757 #if SK_DISTANCEFIELD_FONTS | |
| 1758 } else { | |
| 1759 GrDistanceFieldTextContext context(fContext, grPaint, paint.getColor (), | |
| 1760 paint.getTextSize()/SkDrawProcs:: kBaseDFFontSize); | |
| 1761 myDraw.fProcs = this->initDrawForText(&context); | |
| 1762 fDrawProcs->fFlags |= SkDrawProcs::kSkipBakedGlyphTransform_Flag; | |
| 1763 fDrawProcs->fFlags |= SkDrawProcs::kUseScaledGlyphs_Flag; | |
| 1764 this->INHERITED::drawPosText(myDraw, text, byteLength, pos, constY, | |
| 1765 scalarsPerPos, paint); | |
| 1766 fDrawProcs->fFlags = 0; | |
| 1767 } | |
| 1768 #endif | |
| 1769 } | 1828 } |
| 1770 } | 1829 } |
| 1771 | 1830 |
| 1831 void SkGpuDevice::drawPosDFText(const char text[], size_t byteLength, | |
| 1832 const SkScalar pos[], SkScalar constY, int scala rsPerPosition, | |
| 1833 const SkPaint& paint) { | |
| 1834 GrPaint grPaint; | |
| 1835 if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) { | |
| 1836 return; | |
| 1837 } | |
| 1838 | |
| 1839 SkASSERT(byteLength == 0 || text != NULL); | |
| 1840 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); | |
| 1841 | |
| 1842 SkDEBUGCODE(this->validate();) | |
| 1843 | |
| 1844 // nothing to draw | |
| 1845 if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/) { | |
| 1846 return; | |
| 1847 } | |
| 1848 | |
| 1849 SkScalar sizeRatio = paint.getTextSize()/kBaseDFFontSize; | |
| 1850 GrDistanceFieldTextContext context(fContext, grPaint, paint.getColor(), size Ratio); | |
| 1851 | |
| 1852 SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc(); | |
| 1853 | |
| 1854 SkPaint paintCopy = paint; | |
| 1855 paintCopy.setTextSize(SkIntToScalar(kBaseDFFontSize)); | |
| 1856 paintCopy.setLCDRenderText(false); | |
| 1857 paintCopy.setAutohinted(false); | |
| 1858 paintCopy.setSubpixelText(false); | |
| 1859 SkAutoGlyphCache autoCache(paintCopy, &this->fLeakyProperties, NULL); | |
| 1860 SkGlyphCache* cache = autoCache.getCache(); | |
| 1861 | |
| 1862 const char* stop = text + byteLength; | |
| 1863 GrFontScaler* fontScaler = get_gr_font_scaler(cache); | |
| 1864 | |
| 1865 if (SkPaint::kLeft_Align == paint.getTextAlign()) { | |
| 1866 while (text < stop) { | |
| 1867 // the last 2 parameters are ignored | |
| 1868 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); | |
| 1869 | |
| 1870 if (glyph.fWidth) { | |
| 1871 SkScalar x = pos[0]; | |
| 1872 SkScalar y = scalarsPerPosition == 1 ? constY : pos[1]; | |
| 1873 | |
| 1874 context.drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(), | |
| 1875 glyph.getSubXFixed(), | |
| 1876 glyph.getSubYFixed()), | |
| 1877 SkScalarToFixed(x) + SK_FixedHalf, //d1g .fHalfSampleX, | |
| 1878 SkScalarToFixed(y) + SK_FixedHalf, //d1g .fHalfSampleY, | |
| 1879 fontScaler); | |
| 1880 } | |
| 1881 pos += scalarsPerPosition; | |
| 1882 } | |
| 1883 } else { | |
|
robertphillips
2013/11/25 20:39:44
Is all this duplicate code just for the shift?
| |
| 1884 int alignShift = SkPaint::kCenter_Align == paint.getTextAlign() ? 1 : 0; | |
| 1885 while (text < stop) { | |
| 1886 // the last 2 parameters are ignored | |
| 1887 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); | |
| 1888 | |
| 1889 if (glyph.fWidth) { | |
| 1890 SkScalar x = pos[0]; | |
| 1891 SkScalar y = scalarsPerPosition == 1 ? constY : pos[1]; | |
| 1892 | |
| 1893 context.drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(), | |
| 1894 glyph.getSubXFixed(), | |
| 1895 glyph.getSubYFixed()), | |
| 1896 SkScalarToFixed(x) - (glyph.fAdvanceX >> alignShift) | |
| 1897 + SK_FixedHalf, //d1g .fHalfSampleX, | |
| 1898 SkScalarToFixed(y) - (glyph.fAdvanceY >> alignShift) | |
| 1899 + SK_FixedHalf, //d1g .fHalfSampleY, | |
| 1900 fontScaler); | |
| 1901 } | |
| 1902 pos += scalarsPerPosition; | |
| 1903 } | |
| 1904 } | |
| 1905 } | |
| 1906 | |
| 1772 void SkGpuDevice::drawTextOnPath(const SkDraw& draw, const void* text, | 1907 void SkGpuDevice::drawTextOnPath(const SkDraw& draw, const void* text, |
| 1773 size_t len, const SkPath& path, | 1908 size_t len, const SkPath& path, |
| 1774 const SkMatrix* m, const SkPaint& paint) { | 1909 const SkMatrix* m, const SkPaint& paint) { |
| 1775 CHECK_SHOULD_DRAW(draw, false); | 1910 CHECK_SHOULD_DRAW(draw, false); |
| 1776 | 1911 |
| 1777 SkASSERT(draw.fDevice == this); | 1912 SkASSERT(draw.fDevice == this); |
| 1778 draw.drawTextOnPath((const char*)text, len, path, m, paint); | 1913 draw.drawTextOnPath((const char*)text, len, path, m, paint); |
| 1779 } | 1914 } |
| 1780 | 1915 |
| 1781 /////////////////////////////////////////////////////////////////////////////// | 1916 /////////////////////////////////////////////////////////////////////////////// |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1847 GrTexture* texture, | 1982 GrTexture* texture, |
| 1848 bool needClear) | 1983 bool needClear) |
| 1849 : SkBitmapDevice(make_bitmap(context, texture->asRenderTarget())) { | 1984 : SkBitmapDevice(make_bitmap(context, texture->asRenderTarget())) { |
| 1850 | 1985 |
| 1851 SkASSERT(texture && texture->asRenderTarget()); | 1986 SkASSERT(texture && texture->asRenderTarget()); |
| 1852 // This constructor is called from onCreateCompatibleDevice. It has locked t he RT in the texture | 1987 // This constructor is called from onCreateCompatibleDevice. It has locked t he RT in the texture |
| 1853 // cache. We pass true for the third argument so that it will get unlocked. | 1988 // cache. We pass true for the third argument so that it will get unlocked. |
| 1854 this->initFromRenderTarget(context, texture->asRenderTarget(), true); | 1989 this->initFromRenderTarget(context, texture->asRenderTarget(), true); |
| 1855 fNeedClear = needClear; | 1990 fNeedClear = needClear; |
| 1856 } | 1991 } |
| OLD | NEW |