SkDraw.cpp 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308
  1. /*
  2. * Copyright 2006 The Android Open Source Project
  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. #include "src/core/SkDraw.h"
  8. #include "include/core/SkCanvas.h"
  9. #include "include/core/SkMatrix.h"
  10. #include "include/core/SkPaint.h"
  11. #include "include/core/SkPathEffect.h"
  12. #include "include/core/SkRRect.h"
  13. #include "include/core/SkShader.h"
  14. #include "include/core/SkString.h"
  15. #include "include/core/SkStrokeRec.h"
  16. #include "include/private/SkColorData.h"
  17. #include "include/private/SkMacros.h"
  18. #include "include/private/SkTemplates.h"
  19. #include "include/private/SkTo.h"
  20. #include "src/core/SkArenaAlloc.h"
  21. #include "src/core/SkAutoBlitterChoose.h"
  22. #include "src/core/SkBlendModePriv.h"
  23. #include "src/core/SkBlitter.h"
  24. #include "src/core/SkDevice.h"
  25. #include "src/core/SkDrawProcs.h"
  26. #include "src/core/SkMaskFilterBase.h"
  27. #include "src/core/SkMatrixUtils.h"
  28. #include "src/core/SkPathPriv.h"
  29. #include "src/core/SkRasterClip.h"
  30. #include "src/core/SkRectPriv.h"
  31. #include "src/core/SkScan.h"
  32. #include "src/core/SkStroke.h"
  33. #include "src/core/SkTLazy.h"
  34. #include "src/core/SkUtils.h"
  35. #include <utility>
  36. static SkPaint make_paint_with_image(
  37. const SkPaint& origPaint, const SkBitmap& bitmap, SkMatrix* matrix = nullptr) {
  38. SkPaint paint(origPaint);
  39. paint.setShader(SkMakeBitmapShaderForPaint(origPaint, bitmap, SkTileMode::kClamp,
  40. SkTileMode::kClamp, matrix,
  41. kNever_SkCopyPixelsMode));
  42. return paint;
  43. }
  44. ///////////////////////////////////////////////////////////////////////////////
  45. SkDraw::SkDraw() {}
  46. bool SkDraw::computeConservativeLocalClipBounds(SkRect* localBounds) const {
  47. if (fRC->isEmpty()) {
  48. return false;
  49. }
  50. SkMatrix inverse;
  51. if (!fMatrix->invert(&inverse)) {
  52. return false;
  53. }
  54. SkIRect devBounds = fRC->getBounds();
  55. // outset to have slop for antialasing and hairlines
  56. devBounds.outset(1, 1);
  57. inverse.mapRect(localBounds, SkRect::Make(devBounds));
  58. return true;
  59. }
  60. ///////////////////////////////////////////////////////////////////////////////
  61. void SkDraw::drawPaint(const SkPaint& paint) const {
  62. SkDEBUGCODE(this->validate();)
  63. if (fRC->isEmpty()) {
  64. return;
  65. }
  66. SkIRect devRect;
  67. devRect.set(0, 0, fDst.width(), fDst.height());
  68. SkAutoBlitterChoose blitter(*this, nullptr, paint);
  69. SkScan::FillIRect(devRect, *fRC, blitter.get());
  70. }
  71. ///////////////////////////////////////////////////////////////////////////////
  72. struct PtProcRec {
  73. SkCanvas::PointMode fMode;
  74. const SkPaint* fPaint;
  75. const SkRegion* fClip;
  76. const SkRasterClip* fRC;
  77. // computed values
  78. SkRect fClipBounds;
  79. SkScalar fRadius;
  80. typedef void (*Proc)(const PtProcRec&, const SkPoint devPts[], int count,
  81. SkBlitter*);
  82. bool init(SkCanvas::PointMode, const SkPaint&, const SkMatrix* matrix,
  83. const SkRasterClip*);
  84. Proc chooseProc(SkBlitter** blitter);
  85. private:
  86. SkAAClipBlitterWrapper fWrapper;
  87. };
  88. static void bw_pt_rect_hair_proc(const PtProcRec& rec, const SkPoint devPts[],
  89. int count, SkBlitter* blitter) {
  90. SkASSERT(rec.fClip->isRect());
  91. const SkIRect& r = rec.fClip->getBounds();
  92. for (int i = 0; i < count; i++) {
  93. int x = SkScalarFloorToInt(devPts[i].fX);
  94. int y = SkScalarFloorToInt(devPts[i].fY);
  95. if (r.contains(x, y)) {
  96. blitter->blitH(x, y, 1);
  97. }
  98. }
  99. }
  100. static void bw_pt_rect_16_hair_proc(const PtProcRec& rec,
  101. const SkPoint devPts[], int count,
  102. SkBlitter* blitter) {
  103. SkASSERT(rec.fRC->isRect());
  104. const SkIRect& r = rec.fRC->getBounds();
  105. uint32_t value;
  106. const SkPixmap* dst = blitter->justAnOpaqueColor(&value);
  107. SkASSERT(dst);
  108. uint16_t* addr = dst->writable_addr16(0, 0);
  109. size_t rb = dst->rowBytes();
  110. for (int i = 0; i < count; i++) {
  111. int x = SkScalarFloorToInt(devPts[i].fX);
  112. int y = SkScalarFloorToInt(devPts[i].fY);
  113. if (r.contains(x, y)) {
  114. ((uint16_t*)((char*)addr + y * rb))[x] = SkToU16(value);
  115. }
  116. }
  117. }
  118. static void bw_pt_rect_32_hair_proc(const PtProcRec& rec,
  119. const SkPoint devPts[], int count,
  120. SkBlitter* blitter) {
  121. SkASSERT(rec.fRC->isRect());
  122. const SkIRect& r = rec.fRC->getBounds();
  123. uint32_t value;
  124. const SkPixmap* dst = blitter->justAnOpaqueColor(&value);
  125. SkASSERT(dst);
  126. SkPMColor* addr = dst->writable_addr32(0, 0);
  127. size_t rb = dst->rowBytes();
  128. for (int i = 0; i < count; i++) {
  129. int x = SkScalarFloorToInt(devPts[i].fX);
  130. int y = SkScalarFloorToInt(devPts[i].fY);
  131. if (r.contains(x, y)) {
  132. ((SkPMColor*)((char*)addr + y * rb))[x] = value;
  133. }
  134. }
  135. }
  136. static void bw_pt_hair_proc(const PtProcRec& rec, const SkPoint devPts[],
  137. int count, SkBlitter* blitter) {
  138. for (int i = 0; i < count; i++) {
  139. int x = SkScalarFloorToInt(devPts[i].fX);
  140. int y = SkScalarFloorToInt(devPts[i].fY);
  141. if (rec.fClip->contains(x, y)) {
  142. blitter->blitH(x, y, 1);
  143. }
  144. }
  145. }
  146. static void bw_line_hair_proc(const PtProcRec& rec, const SkPoint devPts[],
  147. int count, SkBlitter* blitter) {
  148. for (int i = 0; i < count; i += 2) {
  149. SkScan::HairLine(&devPts[i], 2, *rec.fRC, blitter);
  150. }
  151. }
  152. static void bw_poly_hair_proc(const PtProcRec& rec, const SkPoint devPts[],
  153. int count, SkBlitter* blitter) {
  154. SkScan::HairLine(devPts, count, *rec.fRC, blitter);
  155. }
  156. // aa versions
  157. static void aa_line_hair_proc(const PtProcRec& rec, const SkPoint devPts[],
  158. int count, SkBlitter* blitter) {
  159. for (int i = 0; i < count; i += 2) {
  160. SkScan::AntiHairLine(&devPts[i], 2, *rec.fRC, blitter);
  161. }
  162. }
  163. static void aa_poly_hair_proc(const PtProcRec& rec, const SkPoint devPts[],
  164. int count, SkBlitter* blitter) {
  165. SkScan::AntiHairLine(devPts, count, *rec.fRC, blitter);
  166. }
  167. // square procs (strokeWidth > 0 but matrix is square-scale (sx == sy)
  168. static SkRect make_square_rad(SkPoint center, SkScalar radius) {
  169. return {
  170. center.fX - radius, center.fY - radius,
  171. center.fX + radius, center.fY + radius
  172. };
  173. }
  174. static SkXRect make_xrect(const SkRect& r) {
  175. SkASSERT(SkRectPriv::FitsInFixed(r));
  176. return {
  177. SkScalarToFixed(r.fLeft), SkScalarToFixed(r.fTop),
  178. SkScalarToFixed(r.fRight), SkScalarToFixed(r.fBottom)
  179. };
  180. }
  181. static void bw_square_proc(const PtProcRec& rec, const SkPoint devPts[],
  182. int count, SkBlitter* blitter) {
  183. for (int i = 0; i < count; i++) {
  184. SkRect r = make_square_rad(devPts[i], rec.fRadius);
  185. if (r.intersect(rec.fClipBounds)) {
  186. SkScan::FillXRect(make_xrect(r), *rec.fRC, blitter);
  187. }
  188. }
  189. }
  190. static void aa_square_proc(const PtProcRec& rec, const SkPoint devPts[],
  191. int count, SkBlitter* blitter) {
  192. for (int i = 0; i < count; i++) {
  193. SkRect r = make_square_rad(devPts[i], rec.fRadius);
  194. if (r.intersect(rec.fClipBounds)) {
  195. SkScan::AntiFillXRect(make_xrect(r), *rec.fRC, blitter);
  196. }
  197. }
  198. }
  199. // If this guy returns true, then chooseProc() must return a valid proc
  200. bool PtProcRec::init(SkCanvas::PointMode mode, const SkPaint& paint,
  201. const SkMatrix* matrix, const SkRasterClip* rc) {
  202. if ((unsigned)mode > (unsigned)SkCanvas::kPolygon_PointMode) {
  203. return false;
  204. }
  205. if (paint.getPathEffect()) {
  206. return false;
  207. }
  208. SkScalar width = paint.getStrokeWidth();
  209. SkScalar radius = -1; // sentinel value, a "valid" value must be > 0
  210. if (0 == width) {
  211. radius = 0.5f;
  212. } else if (paint.getStrokeCap() != SkPaint::kRound_Cap &&
  213. matrix->isScaleTranslate() && SkCanvas::kPoints_PointMode == mode) {
  214. SkScalar sx = matrix->get(SkMatrix::kMScaleX);
  215. SkScalar sy = matrix->get(SkMatrix::kMScaleY);
  216. if (SkScalarNearlyZero(sx - sy)) {
  217. radius = SkScalarHalf(width * SkScalarAbs(sx));
  218. }
  219. }
  220. if (radius > 0) {
  221. SkRect clipBounds = SkRect::Make(rc->getBounds());
  222. // if we return true, the caller may assume that the constructed shapes can be represented
  223. // using SkFixed (after clipping), so we preflight that here.
  224. if (!SkRectPriv::FitsInFixed(clipBounds)) {
  225. return false;
  226. }
  227. fMode = mode;
  228. fPaint = &paint;
  229. fClip = nullptr;
  230. fRC = rc;
  231. fClipBounds = clipBounds;
  232. fRadius = radius;
  233. return true;
  234. }
  235. return false;
  236. }
  237. PtProcRec::Proc PtProcRec::chooseProc(SkBlitter** blitterPtr) {
  238. Proc proc = nullptr;
  239. SkBlitter* blitter = *blitterPtr;
  240. if (fRC->isBW()) {
  241. fClip = &fRC->bwRgn();
  242. } else {
  243. fWrapper.init(*fRC, blitter);
  244. fClip = &fWrapper.getRgn();
  245. blitter = fWrapper.getBlitter();
  246. *blitterPtr = blitter;
  247. }
  248. // for our arrays
  249. SkASSERT(0 == SkCanvas::kPoints_PointMode);
  250. SkASSERT(1 == SkCanvas::kLines_PointMode);
  251. SkASSERT(2 == SkCanvas::kPolygon_PointMode);
  252. SkASSERT((unsigned)fMode <= (unsigned)SkCanvas::kPolygon_PointMode);
  253. if (fPaint->isAntiAlias()) {
  254. if (0 == fPaint->getStrokeWidth()) {
  255. static const Proc gAAProcs[] = {
  256. aa_square_proc, aa_line_hair_proc, aa_poly_hair_proc
  257. };
  258. proc = gAAProcs[fMode];
  259. } else if (fPaint->getStrokeCap() != SkPaint::kRound_Cap) {
  260. SkASSERT(SkCanvas::kPoints_PointMode == fMode);
  261. proc = aa_square_proc;
  262. }
  263. } else { // BW
  264. if (fRadius <= 0.5f) { // small radii and hairline
  265. if (SkCanvas::kPoints_PointMode == fMode && fClip->isRect()) {
  266. uint32_t value;
  267. const SkPixmap* bm = blitter->justAnOpaqueColor(&value);
  268. if (bm && kRGB_565_SkColorType == bm->colorType()) {
  269. proc = bw_pt_rect_16_hair_proc;
  270. } else if (bm && kN32_SkColorType == bm->colorType()) {
  271. proc = bw_pt_rect_32_hair_proc;
  272. } else {
  273. proc = bw_pt_rect_hair_proc;
  274. }
  275. } else {
  276. static Proc gBWProcs[] = {
  277. bw_pt_hair_proc, bw_line_hair_proc, bw_poly_hair_proc
  278. };
  279. proc = gBWProcs[fMode];
  280. }
  281. } else {
  282. proc = bw_square_proc;
  283. }
  284. }
  285. return proc;
  286. }
  287. // each of these costs 8-bytes of stack space, so don't make it too large
  288. // must be even for lines/polygon to work
  289. #define MAX_DEV_PTS 32
  290. void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
  291. const SkPoint pts[], const SkPaint& paint,
  292. SkBaseDevice* device) const {
  293. // if we're in lines mode, force count to be even
  294. if (SkCanvas::kLines_PointMode == mode) {
  295. count &= ~(size_t)1;
  296. }
  297. if ((long)count <= 0) {
  298. return;
  299. }
  300. SkASSERT(pts != nullptr);
  301. SkDEBUGCODE(this->validate();)
  302. // nothing to draw
  303. if (fRC->isEmpty()) {
  304. return;
  305. }
  306. PtProcRec rec;
  307. if (!device && rec.init(mode, paint, fMatrix, fRC)) {
  308. SkAutoBlitterChoose blitter(*this, nullptr, paint);
  309. SkPoint devPts[MAX_DEV_PTS];
  310. const SkMatrix* matrix = fMatrix;
  311. SkBlitter* bltr = blitter.get();
  312. PtProcRec::Proc proc = rec.chooseProc(&bltr);
  313. // we have to back up subsequent passes if we're in polygon mode
  314. const size_t backup = (SkCanvas::kPolygon_PointMode == mode);
  315. do {
  316. int n = SkToInt(count);
  317. if (n > MAX_DEV_PTS) {
  318. n = MAX_DEV_PTS;
  319. }
  320. matrix->mapPoints(devPts, pts, n);
  321. if (!SkScalarsAreFinite(&devPts[0].fX, n * 2)) {
  322. return;
  323. }
  324. proc(rec, devPts, n, bltr);
  325. pts += n - backup;
  326. SkASSERT(SkToInt(count) >= n);
  327. count -= n;
  328. if (count > 0) {
  329. count += backup;
  330. }
  331. } while (count != 0);
  332. } else {
  333. switch (mode) {
  334. case SkCanvas::kPoints_PointMode: {
  335. // temporarily mark the paint as filling.
  336. SkPaint newPaint(paint);
  337. newPaint.setStyle(SkPaint::kFill_Style);
  338. SkScalar width = newPaint.getStrokeWidth();
  339. SkScalar radius = SkScalarHalf(width);
  340. if (newPaint.getStrokeCap() == SkPaint::kRound_Cap) {
  341. if (device) {
  342. for (size_t i = 0; i < count; ++i) {
  343. SkRect r = SkRect::MakeLTRB(pts[i].fX - radius, pts[i].fY - radius,
  344. pts[i].fX + radius, pts[i].fY + radius);
  345. device->drawOval(r, newPaint);
  346. }
  347. } else {
  348. SkPath path;
  349. SkMatrix preMatrix;
  350. path.addCircle(0, 0, radius);
  351. for (size_t i = 0; i < count; i++) {
  352. preMatrix.setTranslate(pts[i].fX, pts[i].fY);
  353. // pass true for the last point, since we can modify
  354. // then path then
  355. path.setIsVolatile((count-1) == i);
  356. this->drawPath(path, newPaint, &preMatrix, (count-1) == i);
  357. }
  358. }
  359. } else {
  360. SkRect r;
  361. for (size_t i = 0; i < count; i++) {
  362. r.fLeft = pts[i].fX - radius;
  363. r.fTop = pts[i].fY - radius;
  364. r.fRight = r.fLeft + width;
  365. r.fBottom = r.fTop + width;
  366. if (device) {
  367. device->drawRect(r, newPaint);
  368. } else {
  369. this->drawRect(r, newPaint);
  370. }
  371. }
  372. }
  373. break;
  374. }
  375. case SkCanvas::kLines_PointMode:
  376. if (2 == count && paint.getPathEffect()) {
  377. // most likely a dashed line - see if it is one of the ones
  378. // we can accelerate
  379. SkStrokeRec rec(paint);
  380. SkPathEffect::PointData pointData;
  381. SkPath path;
  382. path.moveTo(pts[0]);
  383. path.lineTo(pts[1]);
  384. SkRect cullRect = SkRect::Make(fRC->getBounds());
  385. if (paint.getPathEffect()->asPoints(&pointData, path, rec,
  386. *fMatrix, &cullRect)) {
  387. // 'asPoints' managed to find some fast path
  388. SkPaint newP(paint);
  389. newP.setPathEffect(nullptr);
  390. newP.setStyle(SkPaint::kFill_Style);
  391. if (!pointData.fFirst.isEmpty()) {
  392. if (device) {
  393. device->drawPath(pointData.fFirst, newP);
  394. } else {
  395. this->drawPath(pointData.fFirst, newP);
  396. }
  397. }
  398. if (!pointData.fLast.isEmpty()) {
  399. if (device) {
  400. device->drawPath(pointData.fLast, newP);
  401. } else {
  402. this->drawPath(pointData.fLast, newP);
  403. }
  404. }
  405. if (pointData.fSize.fX == pointData.fSize.fY) {
  406. // The rest of the dashed line can just be drawn as points
  407. SkASSERT(pointData.fSize.fX == SkScalarHalf(newP.getStrokeWidth()));
  408. if (SkPathEffect::PointData::kCircles_PointFlag & pointData.fFlags) {
  409. newP.setStrokeCap(SkPaint::kRound_Cap);
  410. } else {
  411. newP.setStrokeCap(SkPaint::kButt_Cap);
  412. }
  413. if (device) {
  414. device->drawPoints(SkCanvas::kPoints_PointMode,
  415. pointData.fNumPoints,
  416. pointData.fPoints,
  417. newP);
  418. } else {
  419. this->drawPoints(SkCanvas::kPoints_PointMode,
  420. pointData.fNumPoints,
  421. pointData.fPoints,
  422. newP,
  423. device);
  424. }
  425. break;
  426. } else {
  427. // The rest of the dashed line must be drawn as rects
  428. SkASSERT(!(SkPathEffect::PointData::kCircles_PointFlag &
  429. pointData.fFlags));
  430. SkRect r;
  431. for (int i = 0; i < pointData.fNumPoints; ++i) {
  432. r.set(pointData.fPoints[i].fX - pointData.fSize.fX,
  433. pointData.fPoints[i].fY - pointData.fSize.fY,
  434. pointData.fPoints[i].fX + pointData.fSize.fX,
  435. pointData.fPoints[i].fY + pointData.fSize.fY);
  436. if (device) {
  437. device->drawRect(r, newP);
  438. } else {
  439. this->drawRect(r, newP);
  440. }
  441. }
  442. }
  443. break;
  444. }
  445. }
  446. // couldn't take fast path so fall through!
  447. case SkCanvas::kPolygon_PointMode: {
  448. count -= 1;
  449. SkPath path;
  450. SkPaint p(paint);
  451. p.setStyle(SkPaint::kStroke_Style);
  452. size_t inc = (SkCanvas::kLines_PointMode == mode) ? 2 : 1;
  453. path.setIsVolatile(true);
  454. for (size_t i = 0; i < count; i += inc) {
  455. path.moveTo(pts[i]);
  456. path.lineTo(pts[i+1]);
  457. if (device) {
  458. device->drawPath(path, p, true);
  459. } else {
  460. this->drawPath(path, p, nullptr, true);
  461. }
  462. path.rewind();
  463. }
  464. break;
  465. }
  466. }
  467. }
  468. }
  469. static inline SkPoint compute_stroke_size(const SkPaint& paint, const SkMatrix& matrix) {
  470. SkASSERT(matrix.rectStaysRect());
  471. SkASSERT(SkPaint::kFill_Style != paint.getStyle());
  472. SkVector size;
  473. SkPoint pt = { paint.getStrokeWidth(), paint.getStrokeWidth() };
  474. matrix.mapVectors(&size, &pt, 1);
  475. return SkPoint::Make(SkScalarAbs(size.fX), SkScalarAbs(size.fY));
  476. }
  477. static bool easy_rect_join(const SkPaint& paint, const SkMatrix& matrix,
  478. SkPoint* strokeSize) {
  479. if (SkPaint::kMiter_Join != paint.getStrokeJoin() ||
  480. paint.getStrokeMiter() < SK_ScalarSqrt2) {
  481. return false;
  482. }
  483. *strokeSize = compute_stroke_size(paint, matrix);
  484. return true;
  485. }
  486. SkDraw::RectType SkDraw::ComputeRectType(const SkPaint& paint,
  487. const SkMatrix& matrix,
  488. SkPoint* strokeSize) {
  489. RectType rtype;
  490. const SkScalar width = paint.getStrokeWidth();
  491. const bool zeroWidth = (0 == width);
  492. SkPaint::Style style = paint.getStyle();
  493. if ((SkPaint::kStrokeAndFill_Style == style) && zeroWidth) {
  494. style = SkPaint::kFill_Style;
  495. }
  496. if (paint.getPathEffect() || paint.getMaskFilter() ||
  497. !matrix.rectStaysRect() || SkPaint::kStrokeAndFill_Style == style) {
  498. rtype = kPath_RectType;
  499. } else if (SkPaint::kFill_Style == style) {
  500. rtype = kFill_RectType;
  501. } else if (zeroWidth) {
  502. rtype = kHair_RectType;
  503. } else if (easy_rect_join(paint, matrix, strokeSize)) {
  504. rtype = kStroke_RectType;
  505. } else {
  506. rtype = kPath_RectType;
  507. }
  508. return rtype;
  509. }
  510. static const SkPoint* rect_points(const SkRect& r) {
  511. return reinterpret_cast<const SkPoint*>(&r);
  512. }
  513. static SkPoint* rect_points(SkRect& r) {
  514. return reinterpret_cast<SkPoint*>(&r);
  515. }
  516. static void draw_rect_as_path(const SkDraw& orig, const SkRect& prePaintRect,
  517. const SkPaint& paint, const SkMatrix* matrix) {
  518. SkDraw draw(orig);
  519. draw.fMatrix = matrix;
  520. SkPath tmp;
  521. tmp.addRect(prePaintRect);
  522. tmp.setFillType(SkPath::kWinding_FillType);
  523. draw.drawPath(tmp, paint, nullptr, true);
  524. }
  525. void SkDraw::drawRect(const SkRect& prePaintRect, const SkPaint& paint,
  526. const SkMatrix* paintMatrix, const SkRect* postPaintRect) const {
  527. SkDEBUGCODE(this->validate();)
  528. // nothing to draw
  529. if (fRC->isEmpty()) {
  530. return;
  531. }
  532. const SkMatrix* matrix;
  533. SkMatrix combinedMatrixStorage;
  534. if (paintMatrix) {
  535. SkASSERT(postPaintRect);
  536. combinedMatrixStorage.setConcat(*fMatrix, *paintMatrix);
  537. matrix = &combinedMatrixStorage;
  538. } else {
  539. SkASSERT(!postPaintRect);
  540. matrix = fMatrix;
  541. }
  542. SkPoint strokeSize;
  543. RectType rtype = ComputeRectType(paint, *fMatrix, &strokeSize);
  544. if (kPath_RectType == rtype) {
  545. draw_rect_as_path(*this, prePaintRect, paint, matrix);
  546. return;
  547. }
  548. SkRect devRect;
  549. const SkRect& paintRect = paintMatrix ? *postPaintRect : prePaintRect;
  550. // skip the paintMatrix when transforming the rect by the CTM
  551. fMatrix->mapPoints(rect_points(devRect), rect_points(paintRect), 2);
  552. devRect.sort();
  553. // look for the quick exit, before we build a blitter
  554. SkRect bbox = devRect;
  555. if (paint.getStyle() != SkPaint::kFill_Style) {
  556. // extra space for hairlines
  557. if (paint.getStrokeWidth() == 0) {
  558. bbox.outset(1, 1);
  559. } else {
  560. // For kStroke_RectType, strokeSize is already computed.
  561. const SkPoint& ssize = (kStroke_RectType == rtype)
  562. ? strokeSize
  563. : compute_stroke_size(paint, *fMatrix);
  564. bbox.outset(SkScalarHalf(ssize.x()), SkScalarHalf(ssize.y()));
  565. }
  566. }
  567. if (SkPathPriv::TooBigForMath(bbox)) {
  568. return;
  569. }
  570. if (!SkRectPriv::FitsInFixed(bbox) && rtype != kHair_RectType) {
  571. draw_rect_as_path(*this, prePaintRect, paint, matrix);
  572. return;
  573. }
  574. SkIRect ir = bbox.roundOut();
  575. if (fRC->quickReject(ir)) {
  576. return;
  577. }
  578. SkAutoBlitterChoose blitterStorage(*this, matrix, paint);
  579. const SkRasterClip& clip = *fRC;
  580. SkBlitter* blitter = blitterStorage.get();
  581. // we want to "fill" if we are kFill or kStrokeAndFill, since in the latter
  582. // case we are also hairline (if we've gotten to here), which devolves to
  583. // effectively just kFill
  584. switch (rtype) {
  585. case kFill_RectType:
  586. if (paint.isAntiAlias()) {
  587. SkScan::AntiFillRect(devRect, clip, blitter);
  588. } else {
  589. SkScan::FillRect(devRect, clip, blitter);
  590. }
  591. break;
  592. case kStroke_RectType:
  593. if (paint.isAntiAlias()) {
  594. SkScan::AntiFrameRect(devRect, strokeSize, clip, blitter);
  595. } else {
  596. SkScan::FrameRect(devRect, strokeSize, clip, blitter);
  597. }
  598. break;
  599. case kHair_RectType:
  600. if (paint.isAntiAlias()) {
  601. SkScan::AntiHairRect(devRect, clip, blitter);
  602. } else {
  603. SkScan::HairRect(devRect, clip, blitter);
  604. }
  605. break;
  606. default:
  607. SkDEBUGFAIL("bad rtype");
  608. }
  609. }
  610. void SkDraw::drawDevMask(const SkMask& srcM, const SkPaint& paint) const {
  611. if (srcM.fBounds.isEmpty()) {
  612. return;
  613. }
  614. const SkMask* mask = &srcM;
  615. SkMask dstM;
  616. if (paint.getMaskFilter() &&
  617. as_MFB(paint.getMaskFilter())->filterMask(&dstM, srcM, *fMatrix, nullptr)) {
  618. mask = &dstM;
  619. }
  620. SkAutoMaskFreeImage ami(dstM.fImage);
  621. SkAutoBlitterChoose blitterChooser(*this, nullptr, paint);
  622. SkBlitter* blitter = blitterChooser.get();
  623. SkAAClipBlitterWrapper wrapper;
  624. const SkRegion* clipRgn;
  625. if (fRC->isBW()) {
  626. clipRgn = &fRC->bwRgn();
  627. } else {
  628. wrapper.init(*fRC, blitter);
  629. clipRgn = &wrapper.getRgn();
  630. blitter = wrapper.getBlitter();
  631. }
  632. blitter->blitMaskRegion(*mask, *clipRgn);
  633. }
  634. static SkScalar fast_len(const SkVector& vec) {
  635. SkScalar x = SkScalarAbs(vec.fX);
  636. SkScalar y = SkScalarAbs(vec.fY);
  637. if (x < y) {
  638. using std::swap;
  639. swap(x, y);
  640. }
  641. return x + SkScalarHalf(y);
  642. }
  643. bool SkDrawTreatAAStrokeAsHairline(SkScalar strokeWidth, const SkMatrix& matrix,
  644. SkScalar* coverage) {
  645. SkASSERT(strokeWidth > 0);
  646. // We need to try to fake a thick-stroke with a modulated hairline.
  647. if (matrix.hasPerspective()) {
  648. return false;
  649. }
  650. SkVector src[2], dst[2];
  651. src[0].set(strokeWidth, 0);
  652. src[1].set(0, strokeWidth);
  653. matrix.mapVectors(dst, src, 2);
  654. SkScalar len0 = fast_len(dst[0]);
  655. SkScalar len1 = fast_len(dst[1]);
  656. if (len0 <= SK_Scalar1 && len1 <= SK_Scalar1) {
  657. if (coverage) {
  658. *coverage = SkScalarAve(len0, len1);
  659. }
  660. return true;
  661. }
  662. return false;
  663. }
  664. void SkDraw::drawRRect(const SkRRect& rrect, const SkPaint& paint) const {
  665. SkDEBUGCODE(this->validate());
  666. if (fRC->isEmpty()) {
  667. return;
  668. }
  669. {
  670. // TODO: Investigate optimizing these options. They are in the same
  671. // order as SkDraw::drawPath, which handles each case. It may be
  672. // that there is no way to optimize for these using the SkRRect path.
  673. SkScalar coverage;
  674. if (SkDrawTreatAsHairline(paint, *fMatrix, &coverage)) {
  675. goto DRAW_PATH;
  676. }
  677. if (paint.getPathEffect() || paint.getStyle() != SkPaint::kFill_Style) {
  678. goto DRAW_PATH;
  679. }
  680. }
  681. if (paint.getMaskFilter()) {
  682. // Transform the rrect into device space.
  683. SkRRect devRRect;
  684. if (rrect.transform(*fMatrix, &devRRect)) {
  685. SkAutoBlitterChoose blitter(*this, nullptr, paint);
  686. if (as_MFB(paint.getMaskFilter())->filterRRect(devRRect, *fMatrix,
  687. *fRC, blitter.get())) {
  688. return; // filterRRect() called the blitter, so we're done
  689. }
  690. }
  691. }
  692. DRAW_PATH:
  693. // Now fall back to the default case of using a path.
  694. SkPath path;
  695. path.addRRect(rrect);
  696. this->drawPath(path, paint, nullptr, true);
  697. }
  698. SkScalar SkDraw::ComputeResScaleForStroking(const SkMatrix& matrix) {
  699. // Not sure how to handle perspective differently, so we just don't try (yet)
  700. SkScalar sx = SkPoint::Length(matrix[SkMatrix::kMScaleX], matrix[SkMatrix::kMSkewY]);
  701. SkScalar sy = SkPoint::Length(matrix[SkMatrix::kMSkewX], matrix[SkMatrix::kMScaleY]);
  702. if (SkScalarsAreFinite(sx, sy)) {
  703. SkScalar scale = SkTMax(sx, sy);
  704. if (scale > 0) {
  705. return scale;
  706. }
  707. }
  708. return 1;
  709. }
  710. void SkDraw::drawDevPath(const SkPath& devPath, const SkPaint& paint, bool drawCoverage,
  711. SkBlitter* customBlitter, bool doFill) const {
  712. if (SkPathPriv::TooBigForMath(devPath)) {
  713. return;
  714. }
  715. SkBlitter* blitter = nullptr;
  716. SkAutoBlitterChoose blitterStorage;
  717. if (nullptr == customBlitter) {
  718. blitter = blitterStorage.choose(*this, nullptr, paint, drawCoverage);
  719. } else {
  720. blitter = customBlitter;
  721. }
  722. if (paint.getMaskFilter()) {
  723. SkStrokeRec::InitStyle style = doFill ? SkStrokeRec::kFill_InitStyle
  724. : SkStrokeRec::kHairline_InitStyle;
  725. if (as_MFB(paint.getMaskFilter())->filterPath(devPath, *fMatrix, *fRC, blitter, style)) {
  726. return; // filterPath() called the blitter, so we're done
  727. }
  728. }
  729. void (*proc)(const SkPath&, const SkRasterClip&, SkBlitter*);
  730. if (doFill) {
  731. if (paint.isAntiAlias()) {
  732. proc = SkScan::AntiFillPath;
  733. } else {
  734. proc = SkScan::FillPath;
  735. }
  736. } else { // hairline
  737. if (paint.isAntiAlias()) {
  738. switch (paint.getStrokeCap()) {
  739. case SkPaint::kButt_Cap:
  740. proc = SkScan::AntiHairPath;
  741. break;
  742. case SkPaint::kSquare_Cap:
  743. proc = SkScan::AntiHairSquarePath;
  744. break;
  745. case SkPaint::kRound_Cap:
  746. proc = SkScan::AntiHairRoundPath;
  747. break;
  748. default:
  749. proc SK_INIT_TO_AVOID_WARNING;
  750. SkDEBUGFAIL("unknown paint cap type");
  751. }
  752. } else {
  753. switch (paint.getStrokeCap()) {
  754. case SkPaint::kButt_Cap:
  755. proc = SkScan::HairPath;
  756. break;
  757. case SkPaint::kSquare_Cap:
  758. proc = SkScan::HairSquarePath;
  759. break;
  760. case SkPaint::kRound_Cap:
  761. proc = SkScan::HairRoundPath;
  762. break;
  763. default:
  764. proc SK_INIT_TO_AVOID_WARNING;
  765. SkDEBUGFAIL("unknown paint cap type");
  766. }
  767. }
  768. }
  769. proc(devPath, *fRC, blitter);
  770. }
  771. void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint,
  772. const SkMatrix* prePathMatrix, bool pathIsMutable,
  773. bool drawCoverage, SkBlitter* customBlitter) const {
  774. SkDEBUGCODE(this->validate();)
  775. // nothing to draw
  776. if (fRC->isEmpty()) {
  777. return;
  778. }
  779. SkPath* pathPtr = (SkPath*)&origSrcPath;
  780. bool doFill = true;
  781. SkPath tmpPathStorage;
  782. SkPath* tmpPath = &tmpPathStorage;
  783. SkMatrix tmpMatrix;
  784. const SkMatrix* matrix = fMatrix;
  785. tmpPath->setIsVolatile(true);
  786. if (prePathMatrix) {
  787. if (origPaint.getPathEffect() || origPaint.getStyle() != SkPaint::kFill_Style) {
  788. SkPath* result = pathPtr;
  789. if (!pathIsMutable) {
  790. result = tmpPath;
  791. pathIsMutable = true;
  792. }
  793. pathPtr->transform(*prePathMatrix, result);
  794. pathPtr = result;
  795. } else {
  796. tmpMatrix.setConcat(*matrix, *prePathMatrix);
  797. matrix = &tmpMatrix;
  798. }
  799. }
  800. // at this point we're done with prePathMatrix
  801. SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;)
  802. SkTCopyOnFirstWrite<SkPaint> paint(origPaint);
  803. {
  804. SkScalar coverage;
  805. if (SkDrawTreatAsHairline(origPaint, *matrix, &coverage)) {
  806. if (SK_Scalar1 == coverage) {
  807. paint.writable()->setStrokeWidth(0);
  808. } else if (SkBlendMode_SupportsCoverageAsAlpha(origPaint.getBlendMode())) {
  809. U8CPU newAlpha;
  810. #if 0
  811. newAlpha = SkToU8(SkScalarRoundToInt(coverage *
  812. origPaint.getAlpha()));
  813. #else
  814. // this is the old technique, which we preserve for now so
  815. // we don't change previous results (testing)
  816. // the new way seems fine, its just (a tiny bit) different
  817. int scale = (int)(coverage * 256);
  818. newAlpha = origPaint.getAlpha() * scale >> 8;
  819. #endif
  820. SkPaint* writablePaint = paint.writable();
  821. writablePaint->setStrokeWidth(0);
  822. writablePaint->setAlpha(newAlpha);
  823. }
  824. }
  825. }
  826. if (paint->getPathEffect() || paint->getStyle() != SkPaint::kFill_Style) {
  827. SkRect cullRect;
  828. const SkRect* cullRectPtr = nullptr;
  829. if (this->computeConservativeLocalClipBounds(&cullRect)) {
  830. cullRectPtr = &cullRect;
  831. }
  832. doFill = paint->getFillPath(*pathPtr, tmpPath, cullRectPtr,
  833. ComputeResScaleForStroking(*fMatrix));
  834. pathPtr = tmpPath;
  835. }
  836. // avoid possibly allocating a new path in transform if we can
  837. SkPath* devPathPtr = pathIsMutable ? pathPtr : tmpPath;
  838. // transform the path into device space
  839. pathPtr->transform(*matrix, devPathPtr);
  840. this->drawDevPath(*devPathPtr, *paint, drawCoverage, customBlitter, doFill);
  841. }
  842. void SkDraw::drawBitmapAsMask(const SkBitmap& bitmap, const SkPaint& paint) const {
  843. SkASSERT(bitmap.colorType() == kAlpha_8_SkColorType);
  844. // nothing to draw
  845. if (fRC->isEmpty()) {
  846. return;
  847. }
  848. if (SkTreatAsSprite(*fMatrix, bitmap.dimensions(), paint)) {
  849. int ix = SkScalarRoundToInt(fMatrix->getTranslateX());
  850. int iy = SkScalarRoundToInt(fMatrix->getTranslateY());
  851. SkPixmap pmap;
  852. if (!bitmap.peekPixels(&pmap)) {
  853. return;
  854. }
  855. SkMask mask;
  856. mask.fBounds.set(ix, iy, ix + pmap.width(), iy + pmap.height());
  857. mask.fFormat = SkMask::kA8_Format;
  858. mask.fRowBytes = SkToU32(pmap.rowBytes());
  859. // fImage is typed as writable, but in this case it is used read-only
  860. mask.fImage = (uint8_t*)pmap.addr8(0, 0);
  861. this->drawDevMask(mask, paint);
  862. } else { // need to xform the bitmap first
  863. SkRect r;
  864. SkMask mask;
  865. r.set(0, 0,
  866. SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.height()));
  867. fMatrix->mapRect(&r);
  868. r.round(&mask.fBounds);
  869. // set the mask's bounds to the transformed bitmap-bounds,
  870. // clipped to the actual device and further limited by the clip bounds
  871. {
  872. SkASSERT(fDst.bounds().contains(fRC->getBounds()));
  873. SkIRect devBounds = fDst.bounds();
  874. devBounds.intersect(fRC->getBounds().makeOutset(1, 1));
  875. // need intersect(l, t, r, b) on irect
  876. if (!mask.fBounds.intersect(devBounds)) {
  877. return;
  878. }
  879. }
  880. mask.fFormat = SkMask::kA8_Format;
  881. mask.fRowBytes = SkAlign4(mask.fBounds.width());
  882. size_t size = mask.computeImageSize();
  883. if (0 == size) {
  884. // the mask is too big to allocated, draw nothing
  885. return;
  886. }
  887. // allocate (and clear) our temp buffer to hold the transformed bitmap
  888. SkAutoTMalloc<uint8_t> storage(size);
  889. mask.fImage = storage.get();
  890. memset(mask.fImage, 0, size);
  891. // now draw our bitmap(src) into mask(dst), transformed by the matrix
  892. {
  893. SkBitmap device;
  894. device.installPixels(SkImageInfo::MakeA8(mask.fBounds.width(), mask.fBounds.height()),
  895. mask.fImage, mask.fRowBytes);
  896. SkCanvas c(device);
  897. // need the unclipped top/left for the translate
  898. c.translate(-SkIntToScalar(mask.fBounds.fLeft),
  899. -SkIntToScalar(mask.fBounds.fTop));
  900. c.concat(*fMatrix);
  901. // We can't call drawBitmap, or we'll infinitely recurse. Instead
  902. // we manually build a shader and draw that into our new mask
  903. SkPaint tmpPaint;
  904. tmpPaint.setAntiAlias(paint.isAntiAlias());
  905. tmpPaint.setDither(paint.isDither());
  906. tmpPaint.setFilterQuality(paint.getFilterQuality());
  907. SkPaint paintWithShader = make_paint_with_image(tmpPaint, bitmap);
  908. SkRect rr;
  909. rr.set(0, 0, SkIntToScalar(bitmap.width()),
  910. SkIntToScalar(bitmap.height()));
  911. c.drawRect(rr, paintWithShader);
  912. }
  913. this->drawDevMask(mask, paint);
  914. }
  915. }
  916. static bool clipped_out(const SkMatrix& m, const SkRasterClip& c,
  917. const SkRect& srcR) {
  918. SkRect dstR;
  919. m.mapRect(&dstR, srcR);
  920. return c.quickReject(dstR.roundOut());
  921. }
  922. static bool clipped_out(const SkMatrix& matrix, const SkRasterClip& clip,
  923. int width, int height) {
  924. SkRect r;
  925. r.set(0, 0, SkIntToScalar(width), SkIntToScalar(height));
  926. return clipped_out(matrix, clip, r);
  927. }
  928. static bool clipHandlesSprite(const SkRasterClip& clip, int x, int y, const SkPixmap& pmap) {
  929. return clip.isBW() || clip.quickContains(x, y, x + pmap.width(), y + pmap.height());
  930. }
  931. void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix,
  932. const SkRect* dstBounds, const SkPaint& origPaint) const {
  933. SkDEBUGCODE(this->validate();)
  934. // nothing to draw
  935. if (fRC->isEmpty() ||
  936. bitmap.width() == 0 || bitmap.height() == 0 ||
  937. bitmap.colorType() == kUnknown_SkColorType) {
  938. return;
  939. }
  940. SkTCopyOnFirstWrite<SkPaint> paint(origPaint);
  941. if (origPaint.getStyle() != SkPaint::kFill_Style) {
  942. paint.writable()->setStyle(SkPaint::kFill_Style);
  943. }
  944. SkMatrix matrix;
  945. matrix.setConcat(*fMatrix, prematrix);
  946. if (clipped_out(matrix, *fRC, bitmap.width(), bitmap.height())) {
  947. return;
  948. }
  949. if (bitmap.colorType() != kAlpha_8_SkColorType
  950. && SkTreatAsSprite(matrix, bitmap.dimensions(), *paint)) {
  951. //
  952. // It is safe to call lock pixels now, since we know the matrix is
  953. // (more or less) identity.
  954. //
  955. SkPixmap pmap;
  956. if (!bitmap.peekPixels(&pmap)) {
  957. return;
  958. }
  959. int ix = SkScalarRoundToInt(matrix.getTranslateX());
  960. int iy = SkScalarRoundToInt(matrix.getTranslateY());
  961. if (clipHandlesSprite(*fRC, ix, iy, pmap)) {
  962. SkSTArenaAlloc<kSkBlitterContextSize> allocator;
  963. // blitter will be owned by the allocator.
  964. SkBlitter* blitter = SkBlitter::ChooseSprite(fDst, *paint, pmap, ix, iy, &allocator);
  965. if (blitter) {
  966. SkScan::FillIRect(SkIRect::MakeXYWH(ix, iy, pmap.width(), pmap.height()),
  967. *fRC, blitter);
  968. return;
  969. }
  970. // if !blitter, then we fall-through to the slower case
  971. }
  972. }
  973. // now make a temp draw on the stack, and use it
  974. //
  975. SkDraw draw(*this);
  976. draw.fMatrix = &matrix;
  977. if (bitmap.colorType() == kAlpha_8_SkColorType && !paint->getColorFilter()) {
  978. draw.drawBitmapAsMask(bitmap, *paint);
  979. } else {
  980. SkPaint paintWithShader = make_paint_with_image(*paint, bitmap);
  981. const SkRect srcBounds = SkRect::MakeIWH(bitmap.width(), bitmap.height());
  982. if (dstBounds) {
  983. this->drawRect(srcBounds, paintWithShader, &prematrix, dstBounds);
  984. } else {
  985. draw.drawRect(srcBounds, paintWithShader);
  986. }
  987. }
  988. }
  989. void SkDraw::drawSprite(const SkBitmap& bitmap, int x, int y, const SkPaint& origPaint) const {
  990. SkDEBUGCODE(this->validate();)
  991. // nothing to draw
  992. if (fRC->isEmpty() ||
  993. bitmap.width() == 0 || bitmap.height() == 0 ||
  994. bitmap.colorType() == kUnknown_SkColorType) {
  995. return;
  996. }
  997. const SkIRect bounds = SkIRect::MakeXYWH(x, y, bitmap.width(), bitmap.height());
  998. if (fRC->quickReject(bounds)) {
  999. return; // nothing to draw
  1000. }
  1001. SkPaint paint(origPaint);
  1002. paint.setStyle(SkPaint::kFill_Style);
  1003. SkPixmap pmap;
  1004. if (!bitmap.peekPixels(&pmap)) {
  1005. return;
  1006. }
  1007. if (nullptr == paint.getColorFilter() && clipHandlesSprite(*fRC, x, y, pmap)) {
  1008. // blitter will be owned by the allocator.
  1009. SkSTArenaAlloc<kSkBlitterContextSize> allocator;
  1010. SkBlitter* blitter = SkBlitter::ChooseSprite(fDst, paint, pmap, x, y, &allocator);
  1011. if (blitter) {
  1012. SkScan::FillIRect(bounds, *fRC, blitter);
  1013. return;
  1014. }
  1015. }
  1016. SkMatrix matrix;
  1017. SkRect r;
  1018. // get a scalar version of our rect
  1019. r.set(bounds);
  1020. // create shader with offset
  1021. matrix.setTranslate(r.fLeft, r.fTop);
  1022. SkPaint paintWithShader = make_paint_with_image(paint, bitmap, &matrix);
  1023. SkDraw draw(*this);
  1024. matrix.reset();
  1025. draw.fMatrix = &matrix;
  1026. // call ourself with a rect
  1027. draw.drawRect(r, paintWithShader);
  1028. }
  1029. ////////////////////////////////////////////////////////////////////////////////////////////////
  1030. #ifdef SK_DEBUG
  1031. void SkDraw::validate() const {
  1032. SkASSERT(fMatrix != nullptr);
  1033. SkASSERT(fRC != nullptr);
  1034. const SkIRect& cr = fRC->getBounds();
  1035. SkIRect br;
  1036. br.set(0, 0, fDst.width(), fDst.height());
  1037. SkASSERT(cr.isEmpty() || br.contains(cr));
  1038. }
  1039. #endif
  1040. ////////////////////////////////////////////////////////////////////////////////////////////////
  1041. #include "include/core/SkPath.h"
  1042. #include "include/core/SkRegion.h"
  1043. #include "src/core/SkBlitter.h"
  1044. #include "src/core/SkDraw.h"
  1045. bool SkDraw::ComputeMaskBounds(const SkRect& devPathBounds, const SkIRect* clipBounds,
  1046. const SkMaskFilter* filter, const SkMatrix* filterMatrix,
  1047. SkIRect* bounds) {
  1048. // init our bounds from the path
  1049. *bounds = devPathBounds.makeOutset(SK_ScalarHalf, SK_ScalarHalf).roundOut();
  1050. SkIPoint margin = SkIPoint::Make(0, 0);
  1051. if (filter) {
  1052. SkASSERT(filterMatrix);
  1053. SkMask srcM, dstM;
  1054. srcM.fBounds = *bounds;
  1055. srcM.fFormat = SkMask::kA8_Format;
  1056. if (!as_MFB(filter)->filterMask(&dstM, srcM, *filterMatrix, &margin)) {
  1057. return false;
  1058. }
  1059. }
  1060. // (possibly) trim the bounds to reflect the clip
  1061. // (plus whatever slop the filter needs)
  1062. if (clipBounds) {
  1063. // Ugh. Guard against gigantic margins from wacky filters. Without this
  1064. // check we can request arbitrary amounts of slop beyond our visible
  1065. // clip, and bring down the renderer (at least on finite RAM machines
  1066. // like handsets, etc.). Need to balance this invented value between
  1067. // quality of large filters like blurs, and the corresponding memory
  1068. // requests.
  1069. static const int MAX_MARGIN = 128;
  1070. if (!bounds->intersect(clipBounds->makeOutset(SkMin32(margin.fX, MAX_MARGIN),
  1071. SkMin32(margin.fY, MAX_MARGIN)))) {
  1072. return false;
  1073. }
  1074. }
  1075. return true;
  1076. }
  1077. static void draw_into_mask(const SkMask& mask, const SkPath& devPath,
  1078. SkStrokeRec::InitStyle style) {
  1079. SkDraw draw;
  1080. if (!draw.fDst.reset(mask)) {
  1081. return;
  1082. }
  1083. SkRasterClip clip;
  1084. SkMatrix matrix;
  1085. SkPaint paint;
  1086. clip.setRect(SkIRect::MakeWH(mask.fBounds.width(), mask.fBounds.height()));
  1087. matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft),
  1088. -SkIntToScalar(mask.fBounds.fTop));
  1089. draw.fRC = &clip;
  1090. draw.fMatrix = &matrix;
  1091. paint.setAntiAlias(true);
  1092. switch (style) {
  1093. case SkStrokeRec::kHairline_InitStyle:
  1094. SkASSERT(!paint.getStrokeWidth());
  1095. paint.setStyle(SkPaint::kStroke_Style);
  1096. break;
  1097. case SkStrokeRec::kFill_InitStyle:
  1098. SkASSERT(paint.getStyle() == SkPaint::kFill_Style);
  1099. break;
  1100. }
  1101. draw.drawPath(devPath, paint);
  1102. }
  1103. bool SkDraw::DrawToMask(const SkPath& devPath, const SkIRect* clipBounds,
  1104. const SkMaskFilter* filter, const SkMatrix* filterMatrix,
  1105. SkMask* mask, SkMask::CreateMode mode,
  1106. SkStrokeRec::InitStyle style) {
  1107. if (devPath.isEmpty()) {
  1108. return false;
  1109. }
  1110. if (SkMask::kJustRenderImage_CreateMode != mode) {
  1111. if (!ComputeMaskBounds(devPath.getBounds(), clipBounds, filter,
  1112. filterMatrix, &mask->fBounds))
  1113. return false;
  1114. }
  1115. if (SkMask::kComputeBoundsAndRenderImage_CreateMode == mode) {
  1116. mask->fFormat = SkMask::kA8_Format;
  1117. mask->fRowBytes = mask->fBounds.width();
  1118. size_t size = mask->computeImageSize();
  1119. if (0 == size) {
  1120. // we're too big to allocate the mask, abort
  1121. return false;
  1122. }
  1123. mask->fImage = SkMask::AllocImage(size, SkMask::kZeroInit_Alloc);
  1124. }
  1125. if (SkMask::kJustComputeBounds_CreateMode != mode) {
  1126. draw_into_mask(*mask, devPath, style);
  1127. }
  1128. return true;
  1129. }