Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Side by Side Diff: src/gpu/SkGpuDevice.cpp

Issue 85653004: Move distance field font code into SkGpuDevice (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« src/core/SkDraw.cpp ('K') | « src/device/xps/SkXPSDevice.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 }
OLDNEW
« src/core/SkDraw.cpp ('K') | « src/device/xps/SkXPSDevice.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698