Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(127)

Side by Side Diff: src/core/SkLatticeIter.cpp

Issue 2382893002: Add a src rect to drawImageLattice() API (Closed)
Patch Set: Simplify impl Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkLatticeIter.h ('k') | src/core/SkLiteDL.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkLatticeIter.h" 8 #include "SkLatticeIter.h"
9 #include "SkRect.h" 9 #include "SkRect.h"
10 10
11 /** 11 /**
12 * Divs must be in increasing order with no duplicates. 12 * Divs must be in increasing order with no duplicates.
13 */ 13 */
14 static bool valid_divs(const int* divs, int count, int len) { 14 static bool valid_divs(const int* divs, int count, int start, int end) {
15 int prev = -1; 15 int prev = start - 1;
16 for (int i = 0; i < count; i++) { 16 for (int i = 0; i < count; i++) {
17 if (prev >= divs[i] || divs[i] >= len) { 17 if (prev >= divs[i] || divs[i] >= end) {
18 return false; 18 return false;
19 } 19 }
20 } 20 }
21 21
22 return true; 22 return true;
23 } 23 }
24 24
25 bool SkLatticeIter::Valid(int width, int height, const SkCanvas::Lattice& lattic e) { 25 bool SkLatticeIter::Valid(int width, int height, const SkCanvas::Lattice& lattic e) {
26 bool zeroXDivs = lattice.fXCount <= 0 || (1 == lattice.fXCount && 0 == latti ce.fXDivs[0]); 26 SkIRect totalBounds = SkIRect::MakeWH(width, height);
27 bool zeroYDivs = lattice.fYCount <= 0 || (1 == lattice.fYCount && 0 == latti ce.fYDivs[0]); 27 SkASSERT(lattice.fBounds);
28 const SkIRect latticeBounds = *lattice.fBounds;
29 if (!totalBounds.contains(latticeBounds)) {
30 return false;
31 }
32
33 bool zeroXDivs = lattice.fXCount <= 0 || (1 == lattice.fXCount &&
34 latticeBounds.fLeft == lattice.fXD ivs[0]);
35 bool zeroYDivs = lattice.fYCount <= 0 || (1 == lattice.fYCount &&
36 latticeBounds.fTop == lattice.fYDi vs[0]);
28 if (zeroXDivs && zeroYDivs) { 37 if (zeroXDivs && zeroYDivs) {
29 return false; 38 return false;
30 } 39 }
31 40
32 return valid_divs(lattice.fXDivs, lattice.fXCount, width) && 41 return valid_divs(lattice.fXDivs, lattice.fXCount, latticeBounds.fLeft, latt iceBounds.fRight)
33 valid_divs(lattice.fYDivs, lattice.fYCount, height); 42 && valid_divs(lattice.fYDivs, lattice.fYCount, latticeBounds.fTop, latti ceBounds.fBottom);
34 } 43 }
35 44
36 /** 45 /**
37 * Count the number of pixels that are in "scalable" patches. 46 * Count the number of pixels that are in "scalable" patches.
38 */ 47 */
39 static int count_scalable_pixels(const int32_t* divs, int numDivs, bool firstIsS calable, 48 static int count_scalable_pixels(const int32_t* divs, int numDivs, bool firstIsS calable,
40 int length) { 49 int start, int end) {
41 if (0 == numDivs) { 50 if (0 == numDivs) {
42 return firstIsScalable ? length : 0; 51 return firstIsScalable ? end - start : 0;
43 } 52 }
44 53
45 int i; 54 int i;
46 int count; 55 int count;
47 if (firstIsScalable) { 56 if (firstIsScalable) {
48 count = divs[0]; 57 count = divs[0] - start;
49 i = 1; 58 i = 1;
50 } else { 59 } else {
51 count = 0; 60 count = 0;
52 i = 0; 61 i = 0;
53 } 62 }
54 63
55 for (; i < numDivs; i += 2) { 64 for (; i < numDivs; i += 2) {
56 // Alternatively, we could use |top| and |bottom| as variable names, ins tead of 65 // Alternatively, we could use |top| and |bottom| as variable names, ins tead of
57 // |left| and |right|. 66 // |left| and |right|.
58 int left = divs[i]; 67 int left = divs[i];
59 int right = (i + 1 < numDivs) ? divs[i + 1] : length; 68 int right = (i + 1 < numDivs) ? divs[i + 1] : end;
60 count += right - left; 69 count += right - left;
61 } 70 }
62 71
63 return count; 72 return count;
64 } 73 }
65 74
66 /** 75 /**
67 * Set points for the src and dst rects on subsequent draw calls. 76 * Set points for the src and dst rects on subsequent draw calls.
68 */ 77 */
69 static void set_points(float* dst, float* src, const int* divs, int divCount, in t srcFixed, 78 static void set_points(float* dst, float* src, const int* divs, int divCount, in t srcFixed,
70 int srcScalable, float dstStart, float dstStop, bool isSc alable) { 79 int srcScalable, float srcStart, float srcEnd, float dstS tart, float dstEnd,
80 bool isScalable) {
71 81
72 float dstLen = dstStop - dstStart; 82 float dstLen = dstEnd - dstStart;
73 int srcLen = srcFixed + srcScalable;
74 float scale; 83 float scale;
75 if (srcFixed <= dstLen) { 84 if (srcFixed <= dstLen) {
76 // This is the "normal" case, where we scale the "scalable" patches and leave 85 // This is the "normal" case, where we scale the "scalable" patches and leave
77 // the other patches fixed. 86 // the other patches fixed.
78 scale = (dstLen - ((float) srcFixed)) / ((float) srcScalable); 87 scale = (dstLen - ((float) srcFixed)) / ((float) srcScalable);
79 } else { 88 } else {
80 // In this case, we eliminate the "scalable" patches and scale the "fixe d" patches. 89 // In this case, we eliminate the "scalable" patches and scale the "fixe d" patches.
81 scale = dstLen / ((float) srcFixed); 90 scale = dstLen / ((float) srcFixed);
82 } 91 }
83 92
84 src[0] = 0.0f; 93 src[0] = srcStart;
85 dst[0] = dstStart; 94 dst[0] = dstStart;
86 for (int i = 0; i < divCount; i++) { 95 for (int i = 0; i < divCount; i++) {
87 src[i + 1] = (float) (divs[i]); 96 src[i + 1] = (float) (divs[i]);
88 float srcDelta = src[i + 1] - src[i]; 97 float srcDelta = src[i + 1] - src[i];
89 float dstDelta; 98 float dstDelta;
90 if (srcFixed <= dstLen) { 99 if (srcFixed <= dstLen) {
91 dstDelta = isScalable ? scale * srcDelta : srcDelta; 100 dstDelta = isScalable ? scale * srcDelta : srcDelta;
92 } else { 101 } else {
93 dstDelta = isScalable ? 0.0f : scale * srcDelta; 102 dstDelta = isScalable ? 0.0f : scale * srcDelta;
94 } 103 }
95 dst[i + 1] = dst[i] + dstDelta; 104 dst[i + 1] = dst[i] + dstDelta;
96 105
97 // Alternate between "scalable" and "fixed" patches. 106 // Alternate between "scalable" and "fixed" patches.
98 isScalable = !isScalable; 107 isScalable = !isScalable;
99 } 108 }
100 109
101 src[divCount + 1] = (float) srcLen; 110 src[divCount + 1] = srcEnd;
102 dst[divCount + 1] = dstStop; 111 dst[divCount + 1] = dstEnd;
103 } 112 }
104 113
105 SkLatticeIter::SkLatticeIter(int srcWidth, int srcHeight, const SkCanvas::Lattic e& lattice, 114 SkLatticeIter::SkLatticeIter(const SkCanvas::Lattice& lattice, const SkRect& dst ) {
106 const SkRect& dst)
107 {
108 const int* xDivs = lattice.fXDivs; 115 const int* xDivs = lattice.fXDivs;
109 const int origXCount = lattice.fXCount; 116 const int origXCount = lattice.fXCount;
110 const int* yDivs = lattice.fYDivs; 117 const int* yDivs = lattice.fYDivs;
111 const int origYCount = lattice.fYCount; 118 const int origYCount = lattice.fYCount;
119 SkASSERT(lattice.fBounds);
120 const SkIRect src = *lattice.fBounds;
112 121
113 // In the x-dimension, the first rectangle always starts at x = 0 and is "sc alable". 122 // In the x-dimension, the first rectangle always starts at x = 0 and is "sc alable".
114 // If xDiv[0] is 0, it indicates that the first rectangle is degenerate, so the 123 // If xDiv[0] is 0, it indicates that the first rectangle is degenerate, so the
115 // first real rectangle "scalable" in the x-direction. 124 // first real rectangle "scalable" in the x-direction.
116 // 125 //
117 // The same interpretation applies to the y-dimension. 126 // The same interpretation applies to the y-dimension.
118 // 127 //
119 // As we move left to right across the image, alternating patches will be "f ixed" or 128 // As we move left to right across the image, alternating patches will be "f ixed" or
120 // "scalable" in the x-direction. Similarly, as move top to bottom, alterna ting 129 // "scalable" in the x-direction. Similarly, as move top to bottom, alterna ting
121 // patches will be "fixed" or "scalable" in the y-direction. 130 // patches will be "fixed" or "scalable" in the y-direction.
122 int xCount = origXCount; 131 int xCount = origXCount;
123 int yCount = origYCount; 132 int yCount = origYCount;
124 bool xIsScalable = (xCount > 0 && 0 == xDivs[0]); 133 bool xIsScalable = (xCount > 0 && src.fLeft == xDivs[0]);
125 if (xIsScalable) { 134 if (xIsScalable) {
126 // Once we've decided that the first patch is "scalable", we don't need the 135 // Once we've decided that the first patch is "scalable", we don't need the
127 // xDiv. It is always implied that we start at zero. 136 // xDiv. It is always implied that we start at the edge of the bounds.
128 xDivs++; 137 xDivs++;
129 xCount--; 138 xCount--;
130 } 139 }
131 bool yIsScalable = (yCount > 0 && 0 == yDivs[0]); 140 bool yIsScalable = (yCount > 0 && src.fTop == yDivs[0]);
132 if (yIsScalable) { 141 if (yIsScalable) {
133 // Once we've decided that the first patch is "scalable", we don't need the 142 // Once we've decided that the first patch is "scalable", we don't need the
134 // yDiv. It is always implied that we start at zero. 143 // yDiv. It is always implied that we start at the edge of the bounds.
135 yDivs++; 144 yDivs++;
136 yCount--; 145 yCount--;
137 } 146 }
138 147
139 // Count "scalable" and "fixed" pixels in each dimension. 148 // Count "scalable" and "fixed" pixels in each dimension.
140 int xCountScalable = count_scalable_pixels(xDivs, xCount, xIsScalable, srcWi dth); 149 int xCountScalable = count_scalable_pixels(xDivs, xCount, xIsScalable, src.f Left, src.fRight);
141 int xCountFixed = srcWidth - xCountScalable; 150 int xCountFixed = src.width() - xCountScalable;
142 int yCountScalable = count_scalable_pixels(yDivs, yCount, yIsScalable, srcHe ight); 151 int yCountScalable = count_scalable_pixels(yDivs, yCount, yIsScalable, src.f Top, src.fBottom);
143 int yCountFixed = srcHeight - yCountScalable; 152 int yCountFixed = src.height() - yCountScalable;
144 153
145 fSrcX.reset(xCount + 2); 154 fSrcX.reset(xCount + 2);
146 fDstX.reset(xCount + 2); 155 fDstX.reset(xCount + 2);
147 set_points(fDstX.begin(), fSrcX.begin(), xDivs, xCount, xCountFixed, xCountS calable, 156 set_points(fDstX.begin(), fSrcX.begin(), xDivs, xCount, xCountFixed, xCountS calable,
148 dst.fLeft, dst.fRight, xIsScalable); 157 src.fLeft, src.fRight, dst.fLeft, dst.fRight, xIsScalable);
149 158
150 fSrcY.reset(yCount + 2); 159 fSrcY.reset(yCount + 2);
151 fDstY.reset(yCount + 2); 160 fDstY.reset(yCount + 2);
152 set_points(fDstY.begin(), fSrcY.begin(), yDivs, yCount, yCountFixed, yCountS calable, 161 set_points(fDstY.begin(), fSrcY.begin(), yDivs, yCount, yCountFixed, yCountS calable,
153 dst.fTop, dst.fBottom, yIsScalable); 162 src.fTop, src.fBottom, dst.fTop, dst.fBottom, yIsScalable);
154 163
155 fCurrX = fCurrY = 0; 164 fCurrX = fCurrY = 0;
156 fNumRectsInLattice = (xCount + 1) * (yCount + 1); 165 fNumRectsInLattice = (xCount + 1) * (yCount + 1);
157 fNumRectsToDraw = fNumRectsInLattice; 166 fNumRectsToDraw = fNumRectsInLattice;
158 167
159 if (lattice.fFlags) { 168 if (lattice.fFlags) {
160 fFlags.push_back_n(fNumRectsInLattice); 169 fFlags.push_back_n(fNumRectsInLattice);
161 170
162 const SkCanvas::Lattice::Flags* flags = lattice.fFlags; 171 const SkCanvas::Lattice::Flags* flags = lattice.fFlags;
163 172
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 for (int i = 0; i < fDstX.count(); i++) { 279 for (int i = 0; i < fDstX.count(); i++) {
271 fDstX[i] = fDstX[i] * sx + tx; 280 fDstX[i] = fDstX[i] * sx + tx;
272 } 281 }
273 282
274 SkScalar ty = matrix.getTranslateY(); 283 SkScalar ty = matrix.getTranslateY();
275 SkScalar sy = matrix.getScaleY(); 284 SkScalar sy = matrix.getScaleY();
276 for (int i = 0; i < fDstY.count(); i++) { 285 for (int i = 0; i < fDstY.count(); i++) {
277 fDstY[i] = fDstY[i] * sy + ty; 286 fDstY[i] = fDstY[i] * sy + ty;
278 } 287 }
279 } 288 }
OLDNEW
« no previous file with comments | « src/core/SkLatticeIter.h ('k') | src/core/SkLiteDL.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698