Line data Source code
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>
15 0 : void NoFilterProc_Scale(const SkBitmapProcState& s, uint32_t xy[],
16 : int count, int x, int y) {
17 0 : SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
18 : SkMatrix::kScale_Mask)) == 0);
19 :
20 : // we store y, x, x, x, x, x
21 :
22 0 : const unsigned maxX = s.fPixmap.width() - 1;
23 : SkFractionalInt fx;
24 : {
25 0 : const SkBitmapProcStateAutoMapper mapper(s, x, y);
26 0 : const unsigned maxY = s.fPixmap.height() - 1;
27 0 : *xy++ = TileProc::Y(s, mapper.fixedY(), maxY);
28 0 : fx = mapper.fractionalIntX();
29 : }
30 :
31 0 : if (0 == maxX) {
32 : // all of the following X values must be 0
33 0 : memset(xy, 0, count * sizeof(uint16_t));
34 0 : return;
35 : }
36 :
37 0 : const SkFractionalInt dx = s.fInvSxFractionalInt;
38 :
39 : if (tryDecal) {
40 0 : const SkFixed fixedFx = SkFractionalIntToFixed(fx);
41 0 : const SkFixed fixedDx = SkFractionalIntToFixed(dx);
42 :
43 0 : if (can_truncate_to_fixed_for_decal(fixedFx, fixedDx, count, maxX)) {
44 0 : decal_nofilter_scale(xy, fixedFx, fixedDx, count);
45 0 : return;
46 : }
47 : }
48 :
49 : int i;
50 0 : for (i = (count >> 2); i > 0; --i) {
51 : unsigned a, b;
52 0 : a = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx;
53 0 : b = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx;
54 : #ifdef SK_CPU_BENDIAN
55 : *xy++ = (a << 16) | b;
56 : #else
57 0 : *xy++ = (b << 16) | a;
58 : #endif
59 0 : a = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx;
60 0 : b = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx;
61 : #ifdef SK_CPU_BENDIAN
62 : *xy++ = (a << 16) | b;
63 : #else
64 0 : *xy++ = (b << 16) | a;
65 : #endif
66 : }
67 0 : uint16_t* xx = (uint16_t*)xy;
68 0 : for (i = (count & 3); i > 0; --i) {
69 0 : *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>
78 0 : void NoFilterProc_Affine(const SkBitmapProcState& s, uint32_t xy[],
79 : int count, int x, int y) {
80 0 : SkASSERT(s.fInvType & SkMatrix::kAffine_Mask);
81 0 : SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
82 : SkMatrix::kScale_Mask |
83 : SkMatrix::kAffine_Mask)) == 0);
84 :
85 0 : const SkBitmapProcStateAutoMapper mapper(s, x, y);
86 :
87 0 : SkFractionalInt fx = mapper.fractionalIntX();
88 0 : SkFractionalInt fy = mapper.fractionalIntY();
89 0 : SkFractionalInt dx = s.fInvSxFractionalInt;
90 0 : SkFractionalInt dy = s.fInvKyFractionalInt;
91 0 : int maxX = s.fPixmap.width() - 1;
92 0 : int maxY = s.fPixmap.height() - 1;
93 :
94 0 : for (int i = count; i > 0; --i) {
95 0 : *xy++ = (TileProc::Y(s, SkFractionalIntToFixed(fy), maxY) << 16) |
96 0 : TileProc::X(s, SkFractionalIntToFixed(fx), maxX);
97 0 : fx += dx; fy += dy;
98 : }
99 0 : }
100 :
101 : template <typename TileProc>
102 0 : void NoFilterProc_Persp(const SkBitmapProcState& s, uint32_t* SK_RESTRICT xy,
103 : int count, int x, int y) {
104 0 : SkASSERT(s.fInvType & SkMatrix::kPerspective_Mask);
105 :
106 0 : int maxX = s.fPixmap.width() - 1;
107 0 : int maxY = s.fPixmap.height() - 1;
108 :
109 : SkPerspIter iter(s.fInvMatrix,
110 : SkIntToScalar(x) + SK_ScalarHalf,
111 0 : SkIntToScalar(y) + SK_ScalarHalf, count);
112 :
113 0 : while ((count = iter.next()) != 0) {
114 0 : const SkFixed* SK_RESTRICT srcXY = iter.getXY();
115 0 : while (--count >= 0) {
116 0 : *xy++ = (TileProc::Y(s, srcXY[1], maxY) << 16) |
117 0 : TileProc::X(s, srcXY[0], maxX);
118 0 : srcXY += 2;
119 : }
120 : }
121 0 : }
122 :
123 : #endif
|