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

Side by Side Diff: src/core/SkDraw.cpp

Issue 196133014: Implement text rendering with NVPR (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: rebase and fix postext Created 6 years, 6 months 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
OLDNEW
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 "SkDraw.h" 8 #include "SkDraw.h"
9 #include "SkBlitter.h" 9 #include "SkBlitter.h"
10 #include "SkCanvas.h" 10 #include "SkCanvas.h"
11 #include "SkColorPriv.h" 11 #include "SkColorPriv.h"
12 #include "SkDevice.h" 12 #include "SkDevice.h"
13 #include "SkDeviceLooper.h" 13 #include "SkDeviceLooper.h"
14 #include "SkFixed.h" 14 #include "SkFixed.h"
15 #include "SkMaskFilter.h" 15 #include "SkMaskFilter.h"
16 #include "SkPaint.h" 16 #include "SkPaint.h"
17 #include "SkPathEffect.h" 17 #include "SkPathEffect.h"
18 #include "SkRasterClip.h" 18 #include "SkRasterClip.h"
19 #include "SkRasterizer.h" 19 #include "SkRasterizer.h"
20 #include "SkRRect.h" 20 #include "SkRRect.h"
21 #include "SkScan.h" 21 #include "SkScan.h"
22 #include "SkShader.h" 22 #include "SkShader.h"
23 #include "SkSmallAllocator.h" 23 #include "SkSmallAllocator.h"
24 #include "SkString.h" 24 #include "SkString.h"
25 #include "SkStroke.h" 25 #include "SkStroke.h"
26 #include "SkTextMapState.h"
26 #include "SkTLazy.h" 27 #include "SkTLazy.h"
27 #include "SkUtils.h" 28 #include "SkUtils.h"
28 #include "SkVertState.h" 29 #include "SkVertState.h"
29 30
30 #include "SkAutoKern.h" 31 #include "SkAutoKern.h"
31 #include "SkBitmapProcShader.h" 32 #include "SkBitmapProcShader.h"
32 #include "SkDrawProcs.h" 33 #include "SkDrawProcs.h"
33 #include "SkMatrixUtils.h" 34 #include "SkMatrixUtils.h"
34 35
35 36
(...skipping 1595 matching lines...) Expand 10 before | Expand all | Expand 10 after
1631 1632
1632 if (glyph.fWidth) { 1633 if (glyph.fWidth) {
1633 proc(d1g, fx, fy, glyph); 1634 proc(d1g, fx, fy, glyph);
1634 } 1635 }
1635 1636
1636 fx += glyph.fAdvanceX; 1637 fx += glyph.fAdvanceX;
1637 fy += glyph.fAdvanceY; 1638 fy += glyph.fAdvanceY;
1638 } 1639 }
1639 } 1640 }
1640 1641
1641 // last parameter is interpreted as SkFixed [x, y]
1642 // return the fixed position, which may be rounded or not by the caller
1643 // e.g. subpixel doesn't round
1644 typedef void (*AlignProc)(const SkPoint&, const SkGlyph&, SkIPoint*);
1645
1646 static void leftAlignProc(const SkPoint& loc, const SkGlyph& glyph, SkIPoint* ds t) {
1647 dst->set(SkScalarToFixed(loc.fX), SkScalarToFixed(loc.fY));
1648 }
1649
1650 static void centerAlignProc(const SkPoint& loc, const SkGlyph& glyph, SkIPoint* dst) {
1651 dst->set(SkScalarToFixed(loc.fX) - (glyph.fAdvanceX >> 1),
1652 SkScalarToFixed(loc.fY) - (glyph.fAdvanceY >> 1));
1653 }
1654
1655 static void rightAlignProc(const SkPoint& loc, const SkGlyph& glyph, SkIPoint* d st) {
1656 dst->set(SkScalarToFixed(loc.fX) - glyph.fAdvanceX,
1657 SkScalarToFixed(loc.fY) - glyph.fAdvanceY);
1658 }
1659
1660 static AlignProc pick_align_proc(SkPaint::Align align) {
1661 static const AlignProc gProcs[] = {
1662 leftAlignProc, centerAlignProc, rightAlignProc
1663 };
1664
1665 SkASSERT((unsigned)align < SK_ARRAY_COUNT(gProcs));
1666
1667 return gProcs[align];
1668 }
1669
1670 typedef void (*AlignProc_scalar)(const SkPoint&, const SkGlyph&, SkPoint*);
1671
1672 static void leftAlignProc_scalar(const SkPoint& loc, const SkGlyph& glyph, SkPoi nt* dst) {
1673 dst->set(loc.fX, loc.fY);
1674 }
1675
1676 static void centerAlignProc_scalar(const SkPoint& loc, const SkGlyph& glyph, SkP oint* dst) {
1677 dst->set(loc.fX - SkFixedToScalar(glyph.fAdvanceX >> 1),
1678 loc.fY - SkFixedToScalar(glyph.fAdvanceY >> 1));
1679 }
1680
1681 static void rightAlignProc_scalar(const SkPoint& loc, const SkGlyph& glyph, SkPo int* dst) {
1682 dst->set(loc.fX - SkFixedToScalar(glyph.fAdvanceX),
1683 loc.fY - SkFixedToScalar(glyph.fAdvanceY));
1684 }
1685
1686 static AlignProc_scalar pick_align_proc_scalar(SkPaint::Align align) {
1687 static const AlignProc_scalar gProcs[] = {
1688 leftAlignProc_scalar, centerAlignProc_scalar, rightAlignProc_scalar
1689 };
1690
1691 SkASSERT((unsigned)align < SK_ARRAY_COUNT(gProcs));
1692
1693 return gProcs[align];
1694 }
1695
1696 class TextMapState {
1697 public:
1698 mutable SkPoint fLoc;
1699
1700 TextMapState(const SkMatrix& matrix, SkScalar y)
1701 : fMatrix(matrix), fProc(matrix.getMapXYProc()), fY(y) {}
1702
1703 typedef void (*Proc)(const TextMapState&, const SkScalar pos[]);
1704
1705 Proc pickProc(int scalarsPerPosition);
1706
1707 private:
1708 const SkMatrix& fMatrix;
1709 SkMatrix::MapXYProc fProc;
1710 SkScalar fY; // ignored by MapXYProc
1711 // these are only used by Only... procs
1712 SkScalar fScaleX, fTransX, fTransformedY;
1713
1714 static void MapXProc(const TextMapState& state, const SkScalar pos[]) {
1715 state.fProc(state.fMatrix, *pos, state.fY, &state.fLoc);
1716 }
1717
1718 static void MapXYProc(const TextMapState& state, const SkScalar pos[]) {
1719 state.fProc(state.fMatrix, pos[0], pos[1], &state.fLoc);
1720 }
1721
1722 static void MapOnlyScaleXProc(const TextMapState& state,
1723 const SkScalar pos[]) {
1724 state.fLoc.set(SkScalarMul(state.fScaleX, *pos) + state.fTransX,
1725 state.fTransformedY);
1726 }
1727
1728 static void MapOnlyTransXProc(const TextMapState& state,
1729 const SkScalar pos[]) {
1730 state.fLoc.set(*pos + state.fTransX, state.fTransformedY);
1731 }
1732 };
1733
1734 TextMapState::Proc TextMapState::pickProc(int scalarsPerPosition) {
1735 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
1736
1737 if (1 == scalarsPerPosition) {
1738 unsigned mtype = fMatrix.getType();
1739 if (mtype & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask)) {
1740 return MapXProc;
1741 } else {
1742 fScaleX = fMatrix.getScaleX();
1743 fTransX = fMatrix.getTranslateX();
1744 fTransformedY = SkScalarMul(fY, fMatrix.getScaleY()) +
1745 fMatrix.getTranslateY();
1746 return (mtype & SkMatrix::kScale_Mask) ?
1747 MapOnlyScaleXProc : MapOnlyTransXProc;
1748 }
1749 } else {
1750 return MapXYProc;
1751 }
1752 }
1753
1754 ////////////////////////////////////////////////////////////////////////////// 1642 //////////////////////////////////////////////////////////////////////////////
1755 1643
1756 void SkDraw::drawPosText_asPaths(const char text[], size_t byteLength, 1644 void SkDraw::drawPosText_asPaths(const char text[], size_t byteLength,
1757 const SkScalar pos[], SkScalar constY, 1645 const SkScalar pos[], SkScalar constY,
1758 int scalarsPerPosition, 1646 int scalarsPerPosition,
1759 const SkPaint& origPaint) const { 1647 const SkPaint& origPaint) const {
1760 // setup our std paint, in hopes of getting hits in the cache 1648 // setup our std paint, in hopes of getting hits in the cache
1761 SkPaint paint(origPaint); 1649 SkPaint paint(origPaint);
1762 SkScalar matrixScale = paint.setupForAsPaths(); 1650 SkScalar matrixScale = paint.setupForAsPaths();
1763 1651
1764 SkMatrix matrix; 1652 SkMatrix matrix;
1765 matrix.setScale(matrixScale, matrixScale); 1653 matrix.setScale(matrixScale, matrixScale);
1766 1654
1767 // Temporarily jam in kFill, so we only ever ask for the raw outline from th e cache. 1655 // Temporarily jam in kFill, so we only ever ask for the raw outline from th e cache.
1768 paint.setStyle(SkPaint::kFill_Style); 1656 paint.setStyle(SkPaint::kFill_Style);
1769 paint.setPathEffect(NULL); 1657 paint.setPathEffect(NULL);
1770 1658
1771 SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc(); 1659 SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc();
1772 SkAutoGlyphCache autoCache(paint, NULL, NULL); 1660 SkAutoGlyphCache autoCache(paint, NULL, NULL);
1773 SkGlyphCache* cache = autoCache.getCache(); 1661 SkGlyphCache* cache = autoCache.getCache();
1774 1662
1775 const char* stop = text + byteLength; 1663 const char* stop = text + byteLength;
1776 AlignProc_scalar alignProc = pick_align_proc_scalar(paint.getTextAlign()); 1664 SkTextAlignProcScalar alignProc(paint.getTextAlign());
1777 TextMapState tms(SkMatrix::I(), constY); 1665 SkTextMapState tms(SkMatrix::I(), constY);
1778 TextMapState::Proc tmsProc = tms.pickProc(scalarsPerPosition); 1666 SkTextMapState::Proc tmsProc = tms.pickProc(scalarsPerPosition);
1779 1667
1780 // Now restore the original settings, so we "draw" with whatever style/strok ing. 1668 // Now restore the original settings, so we "draw" with whatever style/strok ing.
1781 paint.setStyle(origPaint.getStyle()); 1669 paint.setStyle(origPaint.getStyle());
1782 paint.setPathEffect(origPaint.getPathEffect()); 1670 paint.setPathEffect(origPaint.getPathEffect());
1783 1671
1784 while (text < stop) { 1672 while (text < stop) {
1785 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); 1673 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
1786 if (glyph.fWidth) { 1674 if (glyph.fWidth) {
1787 const SkPath* path = cache->findPath(glyph); 1675 const SkPath* path = cache->findPath(glyph);
1788 if (path) { 1676 if (path) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1832 if (needsRasterTextBlit(*this)) { 1720 if (needsRasterTextBlit(*this)) {
1833 blitterChooser.choose(*fBitmap, *fMatrix, paint); 1721 blitterChooser.choose(*fBitmap, *fMatrix, paint);
1834 blitter = blitterChooser.get(); 1722 blitter = blitterChooser.get();
1835 if (fRC->isAA()) { 1723 if (fRC->isAA()) {
1836 wrapper.init(*fRC, blitter); 1724 wrapper.init(*fRC, blitter);
1837 blitter = wrapper.getBlitter(); 1725 blitter = wrapper.getBlitter();
1838 } 1726 }
1839 } 1727 }
1840 1728
1841 const char* stop = text + byteLength; 1729 const char* stop = text + byteLength;
1842 AlignProc alignProc = pick_align_proc(paint.getTextAlign()); 1730 SkTextAlignProc alignProc(paint.getTextAlign());
1843 SkDraw1Glyph d1g; 1731 SkDraw1Glyph d1g;
1844 SkDraw1Glyph::Proc proc = d1g.init(this, blitter, cache, paint); 1732 SkDraw1Glyph::Proc proc = d1g.init(this, blitter, cache, paint);
1845 TextMapState tms(*fMatrix, constY); 1733 SkTextMapState tms(*fMatrix, constY);
1846 TextMapState::Proc tmsProc = tms.pickProc(scalarsPerPosition); 1734 SkTextMapState::Proc tmsProc = tms.pickProc(scalarsPerPosition);
1847 1735
1848 if (cache->isSubpixel()) { 1736 if (cache->isSubpixel()) {
1849 // maybe we should skip the rounding if linearText is set 1737 // maybe we should skip the rounding if linearText is set
1850 SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(*fMatrix); 1738 SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(*fMatrix);
1851 1739
1852 SkFixed fxMask = ~0; 1740 SkFixed fxMask = ~0;
1853 SkFixed fyMask = ~0; 1741 SkFixed fyMask = ~0;
1854 if (kX_SkAxisAlignment == baseline) { 1742 if (kX_SkAxisAlignment == baseline) {
1855 fyMask = 0; 1743 fyMask = 0;
1856 #ifndef SK_IGNORE_SUBPIXEL_AXIS_ALIGN_FIX 1744 #ifndef SK_IGNORE_SUBPIXEL_AXIS_ALIGN_FIX
(...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after
2477 mask->fImage = SkMask::AllocImage(size); 2365 mask->fImage = SkMask::AllocImage(size);
2478 memset(mask->fImage, 0, mask->computeImageSize()); 2366 memset(mask->fImage, 0, mask->computeImageSize());
2479 } 2367 }
2480 2368
2481 if (SkMask::kJustComputeBounds_CreateMode != mode) { 2369 if (SkMask::kJustComputeBounds_CreateMode != mode) {
2482 draw_into_mask(*mask, devPath, style); 2370 draw_into_mask(*mask, devPath, style);
2483 } 2371 }
2484 2372
2485 return true; 2373 return true;
2486 } 2374 }
OLDNEW
« no previous file with comments | « include/gpu/GrContext.h ('k') | src/core/SkDrawProcs.h » ('j') | src/core/SkDrawProcs.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698