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

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

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

Powered by Google App Engine
This is Rietveld 408576698