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 |