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 #define __STDC_LIMIT_MACROS | 7 #define __STDC_LIMIT_MACROS |
8 | 8 |
9 #include "SkDraw.h" | 9 #include "SkDraw.h" |
10 #include "SkBlitter.h" | 10 #include "SkBlitter.h" |
(...skipping 16 matching lines...) Expand all Loading... |
27 #include "SkString.h" | 27 #include "SkString.h" |
28 #include "SkStroke.h" | 28 #include "SkStroke.h" |
29 #include "SkStrokeRec.h" | 29 #include "SkStrokeRec.h" |
30 #include "SkTemplates.h" | 30 #include "SkTemplates.h" |
31 #include "SkTextMapStateProc.h" | 31 #include "SkTextMapStateProc.h" |
32 #include "SkTLazy.h" | 32 #include "SkTLazy.h" |
33 #include "SkUtility.h" | 33 #include "SkUtility.h" |
34 #include "SkUtils.h" | 34 #include "SkUtils.h" |
35 #include "SkVertState.h" | 35 #include "SkVertState.h" |
36 | 36 |
37 #include "SkAutoKern.h" | |
38 #include "SkBitmapProcShader.h" | 37 #include "SkBitmapProcShader.h" |
39 #include "SkDrawProcs.h" | 38 #include "SkDrawProcs.h" |
40 #include "SkMatrixUtils.h" | 39 #include "SkMatrixUtils.h" |
41 | 40 |
42 //#define TRACE_BITMAP_DRAWS | 41 //#define TRACE_BITMAP_DRAWS |
43 | 42 |
44 | 43 |
45 /** Helper for allocating small blitters on the stack. | 44 /** Helper for allocating small blitters on the stack. |
46 */ | 45 */ |
47 class SkAutoBlitterChoose : SkNoncopyable { | 46 class SkAutoBlitterChoose : SkNoncopyable { |
48 public: | 47 public: |
49 SkAutoBlitterChoose() { | 48 SkAutoBlitterChoose() { |
50 fBlitter = nullptr; | 49 fBlitter = nullptr; |
51 } | 50 } |
52 SkAutoBlitterChoose(const SkPixmap& dst, const SkMatrix& matrix, | 51 SkAutoBlitterChoose(const SkPixmap& dst, const SkMatrix& matrix, |
53 const SkPaint& paint, bool drawCoverage = false) { | 52 const SkPaint& paint, bool drawCoverage = false) { |
54 fBlitter = SkBlitter::Choose(dst, matrix, paint, &fAllocator, drawCovera
ge); | 53 fBlitter = SkBlitter::Choose(dst, matrix, paint, &fAllocator, drawCovera
ge); |
55 } | 54 } |
56 | 55 |
57 SkBlitter* operator->() { return fBlitter; } | 56 SkBlitter* operator->() { return fBlitter; } |
58 SkBlitter* get() const { return fBlitter; } | 57 SkBlitter* get() const { return fBlitter; } |
59 | 58 |
60 void choose(const SkPixmap& dst, const SkMatrix& matrix, | 59 void choose(const SkPixmap& dst, const SkMatrix& matrix, |
61 const SkPaint& paint, bool drawCoverage = false) { | 60 const SkPaint& paint, bool drawCoverage = false) { |
62 SkASSERT(!fBlitter); | 61 SkASSERT(!fBlitter); |
63 fBlitter = SkBlitter::Choose(dst, matrix, paint, &fAllocator, drawCovera
ge); | 62 fBlitter = SkBlitter::Choose(dst, matrix, paint, &fAllocator, drawCovera
ge); |
64 } | 63 } |
65 | 64 |
66 private: | 65 private: |
(...skipping 1300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1367 draw.drawRect(r, shaderPaint); | 1366 draw.drawRect(r, shaderPaint); |
1368 } | 1367 } |
1369 | 1368 |
1370 /////////////////////////////////////////////////////////////////////////////// | 1369 /////////////////////////////////////////////////////////////////////////////// |
1371 | 1370 |
1372 #include "SkScalerContext.h" | 1371 #include "SkScalerContext.h" |
1373 #include "SkGlyphCache.h" | 1372 #include "SkGlyphCache.h" |
1374 #include "SkTextToPathIter.h" | 1373 #include "SkTextToPathIter.h" |
1375 #include "SkUtils.h" | 1374 #include "SkUtils.h" |
1376 | 1375 |
1377 static void measure_text(SkGlyphCache* cache, SkDrawCacheProc glyphCacheProc, | |
1378 const char text[], size_t byteLength, SkVector* stopVector) { | |
1379 SkFixed x = 0, y = 0; | |
1380 const char* stop = text + byteLength; | |
1381 | |
1382 SkAutoKern autokern; | |
1383 | |
1384 while (text < stop) { | |
1385 // don't need x, y here, since all subpixel variants will have the | |
1386 // same advance | |
1387 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); | |
1388 | |
1389 x += autokern.adjust(glyph) + glyph.fAdvanceX; | |
1390 y += glyph.fAdvanceY; | |
1391 } | |
1392 stopVector->set(SkFixedToScalar(x), SkFixedToScalar(y)); | |
1393 | |
1394 SkASSERT(text == stop); | |
1395 } | |
1396 | |
1397 bool SkDraw::ShouldDrawTextAsPaths(const SkPaint& paint, const SkMatrix& ctm) { | 1376 bool SkDraw::ShouldDrawTextAsPaths(const SkPaint& paint, const SkMatrix& ctm) { |
1398 // hairline glyphs are fast enough so we don't need to cache them | 1377 // hairline glyphs are fast enough so we don't need to cache them |
1399 if (SkPaint::kStroke_Style == paint.getStyle() && 0 == paint.getStrokeWidth(
)) { | 1378 if (SkPaint::kStroke_Style == paint.getStyle() && 0 == paint.getStrokeWidth(
)) { |
1400 return true; | 1379 return true; |
1401 } | 1380 } |
1402 | 1381 |
1403 // we don't cache perspective | 1382 // we don't cache perspective |
1404 if (ctm.hasPerspective()) { | 1383 if (ctm.hasPerspective()) { |
1405 return true; | 1384 return true; |
1406 } | 1385 } |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1594 return; | 1573 return; |
1595 } | 1574 } |
1596 | 1575 |
1597 // SkScalarRec doesn't currently have a way of representing hairline stroke
and | 1576 // SkScalarRec doesn't currently have a way of representing hairline stroke
and |
1598 // will fill if its frame-width is 0. | 1577 // will fill if its frame-width is 0. |
1599 if (ShouldDrawTextAsPaths(paint, *fMatrix)) { | 1578 if (ShouldDrawTextAsPaths(paint, *fMatrix)) { |
1600 this->drawText_asPaths(text, byteLength, x, y, paint); | 1579 this->drawText_asPaths(text, byteLength, x, y, paint); |
1601 return; | 1580 return; |
1602 } | 1581 } |
1603 | 1582 |
1604 SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc(); | 1583 SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc(); |
1605 | |
1606 SkAutoGlyphCache autoCache(paint, &fDevice->surfaceProps(), fMatrix); | 1584 SkAutoGlyphCache autoCache(paint, &fDevice->surfaceProps(), fMatrix); |
1607 SkGlyphCache* cache = autoCache.getCache(); | 1585 SkGlyphCache* cache = autoCache.getCache(); |
1608 | 1586 |
1609 // transform our starting point | |
1610 { | |
1611 SkPoint loc; | |
1612 fMatrix->mapXY(x, y, &loc); | |
1613 x = loc.fX; | |
1614 y = loc.fY; | |
1615 } | |
1616 | |
1617 // need to measure first | |
1618 if (paint.getTextAlign() != SkPaint::kLeft_Align) { | |
1619 SkVector stop; | |
1620 | |
1621 measure_text(cache, glyphCacheProc, text, byteLength, &stop); | |
1622 | |
1623 SkScalar stopX = stop.fX; | |
1624 SkScalar stopY = stop.fY; | |
1625 | |
1626 if (paint.getTextAlign() == SkPaint::kCenter_Align) { | |
1627 stopX = SkScalarHalf(stopX); | |
1628 stopY = SkScalarHalf(stopY); | |
1629 } | |
1630 x -= stopX; | |
1631 y -= stopY; | |
1632 } | |
1633 | |
1634 const char* stop = text + byteLength; | |
1635 | |
1636 SkAAClipBlitter aaBlitter; | 1587 SkAAClipBlitter aaBlitter; |
1637 SkAutoBlitterChoose blitterChooser; | 1588 SkAutoBlitterChoose blitterChooser; |
1638 SkBlitter* blitter = nullptr; | 1589 SkBlitter* blitter = nullptr; |
1639 if (needsRasterTextBlit(*this)) { | 1590 if (needsRasterTextBlit(*this)) { |
1640 blitterChooser.choose(fDst, *fMatrix, paint); | 1591 blitterChooser.choose(fDst, *fMatrix, paint); |
1641 blitter = blitterChooser.get(); | 1592 blitter = blitterChooser.get(); |
1642 if (fRC->isAA()) { | 1593 if (fRC->isAA()) { |
1643 aaBlitter.init(blitter, &fRC->aaRgn()); | 1594 aaBlitter.init(blitter, &fRC->aaRgn()); |
1644 blitter = &aaBlitter; | 1595 blitter = &aaBlitter; |
1645 } | 1596 } |
1646 } | 1597 } |
1647 | 1598 |
1648 SkAutoKern autokern; | |
1649 SkDraw1Glyph d1g; | 1599 SkDraw1Glyph d1g; |
1650 SkDraw1Glyph::Proc proc = d1g.init(this, blitter, cache, paint); | 1600 SkDraw1Glyph::Proc proc = d1g.init(this, blitter, cache, paint); |
1651 | 1601 |
1652 SkFixed fxMask = ~0; | 1602 SkFindAndPlaceGlyph::ProcessText( |
1653 SkFixed fyMask = ~0; | 1603 text, byteLength, {x, y}, *fMatrix, paint.getTextAlign(), glyphCacheProc
, cache, |
1654 if (cache->isSubpixel()) { | 1604 [&](const SkGlyph& glyph, SkPoint position, SkPoint rounding) { |
1655 SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(*fMatrix); | 1605 position += rounding; |
1656 if (kX_SkAxisAlignment == baseline) { | 1606 proc(d1g, SkScalarTo48Dot16(position.fX), SkScalarTo48Dot16(position
.fY), glyph); |
1657 fyMask = 0; | |
1658 d1g.fHalfSampleY = SK_ScalarHalf; | |
1659 } else if (kY_SkAxisAlignment == baseline) { | |
1660 fxMask = 0; | |
1661 d1g.fHalfSampleX = SK_ScalarHalf; | |
1662 } | 1607 } |
1663 } | 1608 ); |
1664 | |
1665 Sk48Dot16 fx = SkScalarTo48Dot16(x + d1g.fHalfSampleX); | |
1666 Sk48Dot16 fy = SkScalarTo48Dot16(y + d1g.fHalfSampleY); | |
1667 | |
1668 while (text < stop) { | |
1669 const SkGlyph& glyph = glyphCacheProc(cache, &text, fx & fxMask, fy & fy
Mask); | |
1670 | |
1671 fx += autokern.adjust(glyph); | |
1672 | |
1673 if (glyph.fWidth) { | |
1674 proc(d1g, fx, fy, glyph); | |
1675 } | |
1676 | |
1677 fx += glyph.fAdvanceX; | |
1678 fy += glyph.fAdvanceY; | |
1679 } | |
1680 } | 1609 } |
1681 | 1610 |
1682 ////////////////////////////////////////////////////////////////////////////// | 1611 ////////////////////////////////////////////////////////////////////////////// |
1683 | 1612 |
1684 void SkDraw::drawPosText_asPaths(const char text[], size_t byteLength, | 1613 void SkDraw::drawPosText_asPaths(const char text[], size_t byteLength, |
1685 const SkScalar pos[], int scalarsPerPosition, | 1614 const SkScalar pos[], int scalarsPerPosition, |
1686 const SkPoint& offset, const SkPaint& origPaint
) const { | 1615 const SkPoint& offset, const SkPaint& origPaint
) const { |
1687 // setup our std paint, in hopes of getting hits in the cache | 1616 // setup our std paint, in hopes of getting hits in the cache |
1688 SkPaint paint(origPaint); | 1617 SkPaint paint(origPaint); |
1689 SkScalar matrixScale = paint.setupForAsPaths(); | 1618 SkScalar matrixScale = paint.setupForAsPaths(); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1766 SkDraw1Glyph d1g; | 1695 SkDraw1Glyph d1g; |
1767 SkDraw1Glyph::Proc proc = d1g.init(this, blitter, cache, paint); | 1696 SkDraw1Glyph::Proc proc = d1g.init(this, blitter, cache, paint); |
1768 SkPaint::Align textAlignment = paint.getTextAlign(); | 1697 SkPaint::Align textAlignment = paint.getTextAlign(); |
1769 SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc(); | 1698 SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc(); |
1770 | 1699 |
1771 SkFindAndPlaceGlyph::ProcessPosText( | 1700 SkFindAndPlaceGlyph::ProcessPosText( |
1772 text, byteLength, offset, *fMatrix, pos, scalarsPerPosition, | 1701 text, byteLength, offset, *fMatrix, pos, scalarsPerPosition, |
1773 textAlignment, glyphCacheProc, cache, | 1702 textAlignment, glyphCacheProc, cache, |
1774 [&](const SkGlyph& glyph, SkPoint position, SkPoint rounding) { | 1703 [&](const SkGlyph& glyph, SkPoint position, SkPoint rounding) { |
1775 position += rounding; | 1704 position += rounding; |
1776 proc(d1g, SkScalarToFixed(position.fX), SkScalarToFixed(position.fY)
, glyph); | 1705 proc(d1g, SkScalarTo48Dot16(position.fX), SkScalarTo48Dot16(position
.fY), glyph); |
1777 } | 1706 } |
1778 ); | 1707 ); |
1779 } | 1708 } |
1780 | 1709 |
1781 #if defined _WIN32 && _MSC_VER >= 1300 | 1710 #if defined _WIN32 && _MSC_VER >= 1300 |
1782 #pragma warning ( pop ) | 1711 #pragma warning ( pop ) |
1783 #endif | 1712 #endif |
1784 | 1713 |
1785 /////////////////////////////////////////////////////////////////////////////// | 1714 /////////////////////////////////////////////////////////////////////////////// |
1786 | 1715 |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2171 mask->fImage = SkMask::AllocImage(size); | 2100 mask->fImage = SkMask::AllocImage(size); |
2172 memset(mask->fImage, 0, mask->computeImageSize()); | 2101 memset(mask->fImage, 0, mask->computeImageSize()); |
2173 } | 2102 } |
2174 | 2103 |
2175 if (SkMask::kJustComputeBounds_CreateMode != mode) { | 2104 if (SkMask::kJustComputeBounds_CreateMode != mode) { |
2176 draw_into_mask(*mask, devPath, style); | 2105 draw_into_mask(*mask, devPath, style); |
2177 } | 2106 } |
2178 | 2107 |
2179 return true; | 2108 return true; |
2180 } | 2109 } |
OLD | NEW |