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 14template <typename TileProc, bool tryDecal> 15void 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 77template <typename TileProc> 78void 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 101template <typename TileProc> 102void NoFilterProc_Persp(const SkBitmapProcState& s, uint32_t* SK_RESTRICT xy, 103 int count, int x, int y) { 104 SkASSERT(s.fInvType & SkMatrix::kPerspective_Mask); 105 106 int maxX = s.fPixmap.width() - 1; 107 int maxY = s.fPixmap.height() - 1; 108 109 SkPerspIter iter(s.fInvMatrix, 110 SkIntToScalar(x) + SK_ScalarHalf, 111 SkIntToScalar(y) + SK_ScalarHalf, count); 112 113 while ((count = iter.next()) != 0) { 114 const SkFixed* SK_RESTRICT srcXY = iter.getXY(); 115 while (--count >= 0) { 116 *xy++ = (TileProc::Y(s, srcXY[1], maxY) << 16) | 117 TileProc::X(s, srcXY[0], maxX); 118 srcXY += 2; 119 } 120 } 121} 122 123#endif 124