epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2011 Google Inc. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. |
| 6 | */ |
reed | 868074b | 2014-06-03 10:53:59 -0700 | [diff] [blame] | 7 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 8 | #ifndef SkDrawProcs_DEFINED |
| 9 | #define SkDrawProcs_DEFINED |
| 10 | |
reed@google.com | 5bdfb33 | 2013-05-02 18:55:44 +0000 | [diff] [blame] | 11 | #include "SkBlitter.h" |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 12 | #include "SkDraw.h" |
kkinnunen | cb9a2c8 | 2014-06-12 23:06:28 -0700 | [diff] [blame^] | 13 | #include "SkGlyph.h" |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 14 | |
reed@google.com | 045e62d | 2011-10-24 12:19:46 +0000 | [diff] [blame] | 15 | class SkAAClip; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 16 | class SkBlitter; |
| 17 | |
| 18 | struct SkDraw1Glyph { |
bungeman@google.com | 2211b62 | 2012-01-13 15:02:58 +0000 | [diff] [blame] | 19 | const SkDraw* fDraw; |
bungeman@google.com | 2211b62 | 2012-01-13 15:02:58 +0000 | [diff] [blame] | 20 | const SkRegion* fClip; |
| 21 | const SkAAClip* fAAClip; |
| 22 | SkBlitter* fBlitter; |
| 23 | SkGlyphCache* fCache; |
reed@google.com | 5bdfb33 | 2013-05-02 18:55:44 +0000 | [diff] [blame] | 24 | const SkPaint* fPaint; |
bungeman@google.com | 2211b62 | 2012-01-13 15:02:58 +0000 | [diff] [blame] | 25 | SkIRect fClipBounds; |
bungeman@google.com | 9447103 | 2013-02-25 15:55:13 +0000 | [diff] [blame] | 26 | /** Half the sampling frequency of the rasterized glyph in x. */ |
| 27 | SkFixed fHalfSampleX; |
| 28 | /** Half the sampling frequency of the rasterized glyph in y. */ |
| 29 | SkFixed fHalfSampleY; |
bungeman@google.com | 2211b62 | 2012-01-13 15:02:58 +0000 | [diff] [blame] | 30 | |
bungeman@google.com | 9447103 | 2013-02-25 15:55:13 +0000 | [diff] [blame] | 31 | /** Draws one glyph. |
| 32 | * |
| 33 | * The x and y are pre-biased, so implementations may just truncate them. |
| 34 | * i.e. half the sampling frequency has been added. |
| 35 | * e.g. 1/2 or 1/(2^(SkGlyph::kSubBits+1)) has already been added. |
| 36 | * This added bias can be found in fHalfSampleX,Y. |
| 37 | */ |
bungeman@google.com | 2211b62 | 2012-01-13 15:02:58 +0000 | [diff] [blame] | 38 | typedef void (*Proc)(const SkDraw1Glyph&, SkFixed x, SkFixed y, const SkGlyph&); |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 39 | |
reed@google.com | 5bdfb33 | 2013-05-02 18:55:44 +0000 | [diff] [blame] | 40 | Proc init(const SkDraw* draw, SkBlitter* blitter, SkGlyphCache* cache, |
| 41 | const SkPaint&); |
| 42 | |
| 43 | // call this instead of fBlitter->blitMask() since this wrapper will handle |
| 44 | // the case when the mask is ARGB32_Format |
| 45 | // |
| 46 | void blitMask(const SkMask& mask, const SkIRect& clip) const { |
| 47 | if (SkMask::kARGB32_Format == mask.fFormat) { |
| 48 | this->blitMaskAsSprite(mask); |
| 49 | } else { |
| 50 | fBlitter->blitMask(mask, clip); |
| 51 | } |
| 52 | } |
| 53 | |
| 54 | // mask must be kARGB32_Format |
| 55 | void blitMaskAsSprite(const SkMask& mask) const; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 56 | }; |
| 57 | |
| 58 | struct SkDrawProcs { |
| 59 | SkDraw1Glyph::Proc fD1GProc; |
| 60 | }; |
| 61 | |
commit-bot@chromium.org | e0a868c | 2013-11-22 07:02:11 +0000 | [diff] [blame] | 62 | bool SkDrawTreatAAStrokeAsHairline(SkScalar strokeWidth, const SkMatrix&, |
| 63 | SkScalar* coverage); |
| 64 | |
reed@google.com | ecadf99 | 2011-09-19 19:18:18 +0000 | [diff] [blame] | 65 | /** |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 66 | * If the current paint is set to stroke and the stroke-width when applied to |
bsalomon@google.com | dd1be60 | 2012-01-18 20:34:00 +0000 | [diff] [blame] | 67 | * the matrix is <= 1.0, then this returns true, and sets coverage (simulating |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 68 | * a stroke by drawing a hairline with partial coverage). If any of these |
bsalomon@google.com | dd1be60 | 2012-01-18 20:34:00 +0000 | [diff] [blame] | 69 | * conditions are false, then this returns false and coverage is ignored. |
reed@google.com | ecadf99 | 2011-09-19 19:18:18 +0000 | [diff] [blame] | 70 | */ |
commit-bot@chromium.org | e0a868c | 2013-11-22 07:02:11 +0000 | [diff] [blame] | 71 | inline bool SkDrawTreatAsHairline(const SkPaint& paint, const SkMatrix& matrix, |
| 72 | SkScalar* coverage) { |
| 73 | if (SkPaint::kStroke_Style != paint.getStyle()) { |
| 74 | return false; |
| 75 | } |
| 76 | |
| 77 | SkScalar strokeWidth = paint.getStrokeWidth(); |
| 78 | if (0 == strokeWidth) { |
| 79 | *coverage = SK_Scalar1; |
| 80 | return true; |
| 81 | } |
| 82 | |
| 83 | if (!paint.isAntiAlias()) { |
| 84 | return false; |
| 85 | } |
| 86 | |
| 87 | return SkDrawTreatAAStrokeAsHairline(strokeWidth, matrix, coverage); |
| 88 | } |
reed@google.com | ecadf99 | 2011-09-19 19:18:18 +0000 | [diff] [blame] | 89 | |
kkinnunen | cb9a2c8 | 2014-06-12 23:06:28 -0700 | [diff] [blame^] | 90 | class SkTextAlignProc { |
| 91 | public: |
| 92 | SkTextAlignProc(SkPaint::Align align) |
| 93 | : fAlign(align) { |
| 94 | } |
| 95 | |
| 96 | // Returns the position of the glyph in fixed point, which may be rounded or not |
| 97 | // by the caller e.g. subpixel doesn't round. |
| 98 | // @param point interpreted as SkFixed [x, y]. |
| 99 | void operator()(const SkPoint& loc, const SkGlyph& glyph, SkIPoint* dst) { |
| 100 | if (SkPaint::kLeft_Align == fAlign) { |
| 101 | dst->set(SkScalarToFixed(loc.fX), SkScalarToFixed(loc.fY)); |
| 102 | } else if (SkPaint::kCenter_Align == fAlign) { |
| 103 | dst->set(SkScalarToFixed(loc.fX) - (glyph.fAdvanceX >> 1), |
| 104 | SkScalarToFixed(loc.fY) - (glyph.fAdvanceY >> 1)); |
| 105 | } else { |
| 106 | SkASSERT(SkPaint::kRight_Align == fAlign); |
| 107 | dst->set(SkScalarToFixed(loc.fX) - glyph.fAdvanceX, |
| 108 | SkScalarToFixed(loc.fY) - glyph.fAdvanceY); |
| 109 | } |
| 110 | } |
| 111 | private: |
| 112 | const SkPaint::Align fAlign; |
| 113 | }; |
| 114 | |
| 115 | class SkTextAlignProcScalar { |
| 116 | public: |
| 117 | SkTextAlignProcScalar(SkPaint::Align align) |
| 118 | : fAlign(align) { |
| 119 | } |
| 120 | |
| 121 | // Returns the glyph position, which may be rounded or not by the caller |
| 122 | // e.g. subpixel doesn't round. |
| 123 | void operator()(const SkPoint& loc, const SkGlyph& glyph, SkPoint* dst) { |
| 124 | if (SkPaint::kLeft_Align == fAlign) { |
| 125 | dst->set(loc.fX, loc.fY); |
| 126 | } else if (SkPaint::kCenter_Align == fAlign) { |
| 127 | dst->set(loc.fX - SkFixedToScalar(glyph.fAdvanceX >> 1), |
| 128 | loc.fY - SkFixedToScalar(glyph.fAdvanceY >> 1)); |
| 129 | } else { |
| 130 | SkASSERT(SkPaint::kRight_Align == fAlign); |
| 131 | dst->set(loc.fX - SkFixedToScalar(glyph.fAdvanceX), |
| 132 | loc.fY - SkFixedToScalar(glyph.fAdvanceY)); |
| 133 | } |
| 134 | } |
| 135 | private: |
| 136 | const SkPaint::Align fAlign; |
| 137 | }; |
| 138 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 139 | #endif |