| 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 |