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.fPixmap.width() - 1;
23 SkFractionalInt fx;
24 {
25 const SkBitmapProcStateAutoMapper mapper(s, x, y);
26 const unsigned maxY = s.fPixmap.height() - 1;
27 *xy++ = TileProc::Y(s, mapper.fixedY(), maxY);
28 fx = mapper.fractionalIntX();
29 }
30
31 if (0 == maxX) {
32 // all of the following X values must be 0
33 memset(xy, 0, count * sizeof(uint16_t));
34 return;
35 }
36
37 const SkFractionalInt dx = s.fInvSxFractionalInt;
38
39 if (tryDecal) {
40 const SkFixed fixedFx = SkFractionalIntToFixed(fx);
41 const SkFixed fixedDx = SkFractionalIntToFixed(dx);
42
43 if (can_truncate_to_fixed_for_decal(fixedFx, fixedDx, count, maxX)) {
44 decal_nofilter_scale(xy, fixedFx, fixedDx, count);
45 return;
46 }
47 }
48
49 int i;
50 for (i = (count >> 2); i > 0; --i) {
51 unsigned a, b;
52 a = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx;
53 b = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx;
54 #ifdef SK_CPU_BENDIAN
55 *xy++ = (a << 16) | b;
56 #else
57 *xy++ = (b << 16) | a;
58 #endif
59 a = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx;
60 b = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx;
61 #ifdef SK_CPU_BENDIAN
62 *xy++ = (a << 16) | b;
63 #else
64 *xy++ = (b << 16) | a;
65 #endif
66 }
67 uint16_t* xx = (uint16_t*)xy;
68 for (i = (count & 3); i > 0; --i) {
69 *xx++ = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx;
70 }
71 }
72
73 // note: we could special-case on a matrix which is skewed in X but not Y.
74 // this would require a more general setup thatn SCALE does, but could use
75 // SCALE's inner loop that only looks at dx
76
77 template <typename TileProc>
NoFilterProc_Affine(const SkBitmapProcState & s,uint32_t xy[],int count,int x,int y)78 void NoFilterProc_Affine(const SkBitmapProcState& s, uint32_t xy[],
79 int count, int x, int y) {
80 SkASSERT(s.fInvType & SkMatrix::kAffine_Mask);
81 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
82 SkMatrix::kScale_Mask |
83 SkMatrix::kAffine_Mask)) == 0);
84
85 const SkBitmapProcStateAutoMapper mapper(s, x, y);
86
87 SkFractionalInt fx = mapper.fractionalIntX();
88 SkFractionalInt fy = mapper.fractionalIntY();
89 SkFractionalInt dx = s.fInvSxFractionalInt;
90 SkFractionalInt dy = s.fInvKyFractionalInt;
91 int maxX = s.fPixmap.width() - 1;
92 int maxY = s.fPixmap.height() - 1;
93
94 for (int i = count; i > 0; --i) {
95 *xy++ = (TileProc::Y(s, SkFractionalIntToFixed(fy), maxY) << 16) |
96 TileProc::X(s, SkFractionalIntToFixed(fx), maxX);
97 fx += dx; fy += dy;
98 }
99 }
100
101 #endif
102