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