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 "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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |