• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2013 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  */
7 
8 #ifndef SkBitmapProcState_MatrixTemplates_DEFINED
9 #define SkBitmapProcState_MatrixTemplates_DEFINED
10 
11 #include "SkMath.h"
12 #include "SkMathPriv.h"
13 
14 template <typename TileProc, bool tryDecal>
NoFilterProc_Scale(const SkBitmapProcState & s,uint32_t xy[],int count,int x,int y)15 void NoFilterProc_Scale(const SkBitmapProcState& s, uint32_t xy[],
16                         int count, int x, int y) {
17     SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
18                              SkMatrix::kScale_Mask)) == 0);
19 
20     // we store y, x, x, x, x, x
21 
22     const unsigned maxX = s.fBitmap->width() - 1;
23     SkFractionalInt fx;
24     {
25         SkPoint pt;
26         s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf,
27                                   SkIntToScalar(y) + SK_ScalarHalf, &pt);
28         fx = SkScalarToFractionalInt(pt.fY);
29         const unsigned maxY = s.fBitmap->height() - 1;
30         *xy++ = TileProc::Y(s, SkFractionalIntToFixed(fx), maxY);
31         fx = SkScalarToFractionalInt(pt.fX);
32     }
33 
34     if (0 == maxX) {
35         // all of the following X values must be 0
36         memset(xy, 0, count * sizeof(uint16_t));
37         return;
38     }
39 
40     const SkFractionalInt dx = s.fInvSxFractionalInt;
41 
42     if (tryDecal && can_truncate_to_fixed_for_decal(fx, dx, count, maxX)) {
43         decal_nofilter_scale(xy, SkFractionalIntToFixed(fx),
44                              SkFractionalIntToFixed(dx), count);
45     } else {
46         int i;
47         for (i = (count >> 2); i > 0; --i) {
48             unsigned a, b;
49             a = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx;
50             b = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx;
51 #ifdef SK_CPU_BENDIAN
52             *xy++ = (a << 16) | b;
53 #else
54             *xy++ = (b << 16) | a;
55 #endif
56             a = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx;
57             b = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx;
58 #ifdef SK_CPU_BENDIAN
59             *xy++ = (a << 16) | b;
60 #else
61             *xy++ = (b << 16) | a;
62 #endif
63         }
64         uint16_t* xx = (uint16_t*)xy;
65         for (i = (count & 3); i > 0; --i) {
66             *xx++ = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx;
67         }
68     }
69 }
70 
71 // note: we could special-case on a matrix which is skewed in X but not Y.
72 // this would require a more general setup thatn SCALE does, but could use
73 // SCALE's inner loop that only looks at dx
74 
75 template <typename TileProc>
NoFilterProc_Affine(const SkBitmapProcState & s,uint32_t xy[],int count,int x,int y)76 void NoFilterProc_Affine(const SkBitmapProcState& s, uint32_t xy[],
77                          int count, int x, int y) {
78     SkASSERT(s.fInvType & SkMatrix::kAffine_Mask);
79     SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
80                              SkMatrix::kScale_Mask |
81                              SkMatrix::kAffine_Mask)) == 0);
82 
83     SkPoint srcPt;
84     s.fInvProc(s.fInvMatrix,
85                SkIntToScalar(x) + SK_ScalarHalf,
86                SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
87 
88     SkFractionalInt fx = SkScalarToFractionalInt(srcPt.fX);
89     SkFractionalInt fy = SkScalarToFractionalInt(srcPt.fY);
90     SkFractionalInt dx = s.fInvSxFractionalInt;
91     SkFractionalInt dy = s.fInvKyFractionalInt;
92     int maxX = s.fBitmap->width() - 1;
93     int maxY = s.fBitmap->height() - 1;
94 
95     for (int i = count; i > 0; --i) {
96         *xy++ = (TileProc::Y(s, SkFractionalIntToFixed(fy), maxY) << 16) |
97                  TileProc::X(s, SkFractionalIntToFixed(fx), maxX);
98         fx += dx; fy += dy;
99     }
100 }
101 
102 template <typename TileProc>
NoFilterProc_Persp(const SkBitmapProcState & s,uint32_t * SK_RESTRICT xy,int count,int x,int y)103 void NoFilterProc_Persp(const SkBitmapProcState& s, uint32_t* SK_RESTRICT xy,
104                         int count, int x, int y) {
105     SkASSERT(s.fInvType & SkMatrix::kPerspective_Mask);
106 
107     int maxX = s.fBitmap->width() - 1;
108     int maxY = s.fBitmap->height() - 1;
109 
110     SkPerspIter   iter(s.fInvMatrix,
111                        SkIntToScalar(x) + SK_ScalarHalf,
112                        SkIntToScalar(y) + SK_ScalarHalf, count);
113 
114     while ((count = iter.next()) != 0) {
115         const SkFixed* SK_RESTRICT srcXY = iter.getXY();
116         while (--count >= 0) {
117             *xy++ = (TileProc::Y(s, srcXY[1], maxY) << 16) |
118                      TileProc::X(s, srcXY[0], maxX);
119             srcXY += 2;
120         }
121     }
122 }
123 
124 #endif
125