FuzzCanvas.cpp 65 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727
  1. /*
  2. * Copyright 2017 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. #include "fuzz/Fuzz.h"
  8. #include "fuzz/FuzzCommon.h"
  9. // CORE
  10. #include "include/core/SkCanvas.h"
  11. #include "include/core/SkColorFilter.h"
  12. #include "include/core/SkFontMgr.h"
  13. #include "include/core/SkImageFilter.h"
  14. #include "include/core/SkMaskFilter.h"
  15. #include "include/core/SkPathEffect.h"
  16. #include "include/core/SkPictureRecorder.h"
  17. #include "include/core/SkPoint3.h"
  18. #include "include/core/SkRSXform.h"
  19. #include "include/core/SkRegion.h"
  20. #include "include/core/SkSurface.h"
  21. #include "include/core/SkTypeface.h"
  22. #include "include/docs/SkPDFDocument.h"
  23. #include "include/private/SkTo.h"
  24. #include "include/utils/SkNullCanvas.h"
  25. #include "src/core/SkOSFile.h"
  26. #include "src/core/SkPicturePriv.h"
  27. #include "tools/debugger/DebugCanvas.h"
  28. // EFFECTS
  29. #include "include/core/SkTextBlob.h"
  30. #include "include/effects/Sk1DPathEffect.h"
  31. #include "include/effects/Sk2DPathEffect.h"
  32. #include "include/effects/SkAlphaThresholdFilter.h"
  33. #include "include/effects/SkArithmeticImageFilter.h"
  34. #include "include/effects/SkBlurImageFilter.h"
  35. #include "include/effects/SkBlurMaskFilter.h"
  36. #include "include/effects/SkColorFilterImageFilter.h"
  37. #include "include/effects/SkColorMatrixFilter.h"
  38. #include "include/effects/SkComposeImageFilter.h"
  39. #include "include/effects/SkCornerPathEffect.h"
  40. #include "include/effects/SkDashPathEffect.h"
  41. #include "include/effects/SkDiscretePathEffect.h"
  42. #include "include/effects/SkDisplacementMapEffect.h"
  43. #include "include/effects/SkDropShadowImageFilter.h"
  44. #include "include/effects/SkGradientShader.h"
  45. #include "include/effects/SkHighContrastFilter.h"
  46. #include "include/effects/SkImageSource.h"
  47. #include "include/effects/SkLightingImageFilter.h"
  48. #include "include/effects/SkLumaColorFilter.h"
  49. #include "include/effects/SkMagnifierImageFilter.h"
  50. #include "include/effects/SkMatrixConvolutionImageFilter.h"
  51. #include "include/effects/SkMergeImageFilter.h"
  52. #include "include/effects/SkMorphologyImageFilter.h"
  53. #include "include/effects/SkOffsetImageFilter.h"
  54. #include "include/effects/SkPaintImageFilter.h"
  55. #include "include/effects/SkPerlinNoiseShader.h"
  56. #include "include/effects/SkPictureImageFilter.h"
  57. #include "include/effects/SkTableColorFilter.h"
  58. #include "include/effects/SkTileImageFilter.h"
  59. #include "include/effects/SkXfermodeImageFilter.h"
  60. #include "src/core/SkReadBuffer.h"
  61. // SRC
  62. #include "src/utils/SkUTF.h"
  63. #include "tools/flags/CommandLineFlags.h"
  64. #if SK_SUPPORT_GPU
  65. #include "include/gpu/gl/GrGLFunctions.h"
  66. #include "src/gpu/GrContextPriv.h"
  67. #include "src/gpu/gl/GrGLGpu.h"
  68. #include "src/gpu/gl/GrGLUtil.h"
  69. #include "tools/gpu/GrContextFactory.h"
  70. #endif
  71. // MISC
  72. #include <iostream>
  73. #include <utility>
  74. static DEFINE_bool2(gpuInfo, g, false, "Display GPU information on relevant targets.");
  75. // TODO:
  76. // SkTextBlob with Unicode
  77. // SkImage: more types
  78. // be careful: `foo(make_fuzz_t<T>(f), make_fuzz_t<U>(f))` is undefined.
  79. // In fact, all make_fuzz_foo() functions have this potential problem.
  80. // Use sequence points!
  81. template <typename T>
  82. inline T make_fuzz_t(Fuzz* fuzz) {
  83. T t;
  84. fuzz->next(&t);
  85. return t;
  86. }
  87. static sk_sp<SkImage> make_fuzz_image(Fuzz*);
  88. static SkBitmap make_fuzz_bitmap(Fuzz*);
  89. static sk_sp<SkPicture> make_fuzz_picture(Fuzz*, int depth);
  90. static sk_sp<SkColorFilter> make_fuzz_colorfilter(Fuzz* fuzz, int depth) {
  91. if (depth <= 0) {
  92. return nullptr;
  93. }
  94. int colorFilterType;
  95. fuzz->nextRange(&colorFilterType, 0, 8);
  96. switch (colorFilterType) {
  97. case 0:
  98. return nullptr;
  99. case 1: {
  100. SkColor color;
  101. SkBlendMode mode;
  102. fuzz->next(&color);
  103. fuzz->nextEnum(&mode, SkBlendMode::kLastMode);
  104. return SkColorFilters::Blend(color, mode);
  105. }
  106. case 2: {
  107. sk_sp<SkColorFilter> outer = make_fuzz_colorfilter(fuzz, depth - 1);
  108. if (!outer) {
  109. return nullptr;
  110. }
  111. sk_sp<SkColorFilter> inner = make_fuzz_colorfilter(fuzz, depth - 1);
  112. // makeComposed should be able to handle nullptr.
  113. return outer->makeComposed(std::move(inner));
  114. }
  115. case 3: {
  116. float array[20];
  117. fuzz->nextN(array, SK_ARRAY_COUNT(array));
  118. return SkColorFilters::Matrix(array);
  119. }
  120. case 4: {
  121. SkColor mul, add;
  122. fuzz->next(&mul, &add);
  123. return SkColorMatrixFilter::MakeLightingFilter(mul, add);
  124. }
  125. case 5: {
  126. bool grayscale;
  127. int invertStyle;
  128. float contrast;
  129. fuzz->next(&grayscale);
  130. fuzz->nextRange(&invertStyle, 0, 2);
  131. fuzz->nextRange(&contrast, -1.0f, 1.0f);
  132. return SkHighContrastFilter::Make(SkHighContrastConfig(
  133. grayscale, SkHighContrastConfig::InvertStyle(invertStyle), contrast));
  134. }
  135. case 6:
  136. return SkLumaColorFilter::Make();
  137. case 7: {
  138. uint8_t table[256];
  139. fuzz->nextN(table, SK_ARRAY_COUNT(table));
  140. return SkTableColorFilter::Make(table);
  141. }
  142. case 8: {
  143. uint8_t tableA[256];
  144. uint8_t tableR[256];
  145. uint8_t tableG[256];
  146. uint8_t tableB[256];
  147. fuzz->nextN(tableA, SK_ARRAY_COUNT(tableA));
  148. fuzz->nextN(tableR, SK_ARRAY_COUNT(tableR));
  149. fuzz->nextN(tableG, SK_ARRAY_COUNT(tableG));
  150. fuzz->nextN(tableB, SK_ARRAY_COUNT(tableB));
  151. return SkTableColorFilter::MakeARGB(tableA, tableR, tableG, tableB);
  152. }
  153. default:
  154. SkASSERT(false);
  155. break;
  156. }
  157. return nullptr;
  158. }
  159. static void fuzz_gradient_stops(Fuzz* fuzz, SkScalar* pos, int colorCount) {
  160. SkScalar totalPos = 0;
  161. for (int i = 0; i < colorCount; ++i) {
  162. fuzz->nextRange(&pos[i], 1.0f, 1024.0f);
  163. totalPos += pos[i];
  164. }
  165. totalPos = 1.0f / totalPos;
  166. for (int i = 0; i < colorCount; ++i) {
  167. pos[i] *= totalPos;
  168. }
  169. // SkASSERT(fabs(pos[colorCount - 1] - 1.0f) < 0.00001f);
  170. pos[colorCount - 1] = 1.0f;
  171. }
  172. static sk_sp<SkShader> make_fuzz_shader(Fuzz* fuzz, int depth) {
  173. sk_sp<SkShader> shader1(nullptr), shader2(nullptr);
  174. sk_sp<SkColorFilter> colorFilter(nullptr);
  175. SkBitmap bitmap;
  176. sk_sp<SkImage> img;
  177. SkTileMode tmX, tmY;
  178. bool useMatrix;
  179. SkColor color;
  180. SkMatrix matrix;
  181. SkBlendMode blendMode;
  182. int shaderType;
  183. if (depth <= 0) {
  184. return nullptr;
  185. }
  186. fuzz->nextRange(&shaderType, 0, 14);
  187. switch (shaderType) {
  188. case 0:
  189. return nullptr;
  190. case 1:
  191. return SkShaders::Empty();
  192. case 2:
  193. fuzz->next(&color);
  194. return SkShaders::Color(color);
  195. case 3:
  196. img = make_fuzz_image(fuzz);
  197. fuzz->nextEnum(&tmX, SkTileMode::kLastTileMode);
  198. fuzz->nextEnum(&tmY, SkTileMode::kLastTileMode);
  199. fuzz->next(&useMatrix);
  200. if (useMatrix) {
  201. FuzzNiceMatrix(fuzz, &matrix);
  202. }
  203. return img->makeShader(tmX, tmY, useMatrix ? &matrix : nullptr);
  204. case 4:
  205. bitmap = make_fuzz_bitmap(fuzz);
  206. fuzz->nextEnum(&tmX, SkTileMode::kLastTileMode);
  207. fuzz->nextEnum(&tmY, SkTileMode::kLastTileMode);
  208. fuzz->next(&useMatrix);
  209. if (useMatrix) {
  210. FuzzNiceMatrix(fuzz, &matrix);
  211. }
  212. return bitmap.makeShader(tmX, tmY, useMatrix ? &matrix : nullptr);
  213. case 5:
  214. shader1 = make_fuzz_shader(fuzz, depth - 1); // limit recursion.
  215. FuzzNiceMatrix(fuzz, &matrix);
  216. return shader1 ? shader1->makeWithLocalMatrix(matrix) : nullptr;
  217. case 6:
  218. shader1 = make_fuzz_shader(fuzz, depth - 1); // limit recursion.
  219. colorFilter = make_fuzz_colorfilter(fuzz, depth - 1);
  220. return shader1 ? shader1->makeWithColorFilter(std::move(colorFilter)) : nullptr;
  221. case 7:
  222. shader1 = make_fuzz_shader(fuzz, depth - 1); // limit recursion.
  223. shader2 = make_fuzz_shader(fuzz, depth - 1);
  224. fuzz->nextEnum(&blendMode, SkBlendMode::kLastMode);
  225. return SkShaders::Blend(blendMode, std::move(shader1), std::move(shader2));
  226. case 8: {
  227. auto pic = make_fuzz_picture(fuzz, depth - 1);
  228. bool useTile;
  229. SkRect tile;
  230. fuzz->nextEnum(&tmX, SkTileMode::kLastTileMode);
  231. fuzz->nextEnum(&tmY, SkTileMode::kLastTileMode);
  232. fuzz->next(&useMatrix, &useTile);
  233. if (useMatrix) {
  234. FuzzNiceMatrix(fuzz, &matrix);
  235. }
  236. if (useTile) {
  237. fuzz->next(&tile);
  238. }
  239. return pic->makeShader(tmX, tmY, useMatrix ? &matrix : nullptr, useTile ? &tile : nullptr);
  240. }
  241. // EFFECTS:
  242. case 9:
  243. // Deprecated SkGaussianEdgeShader
  244. return nullptr;
  245. case 10: {
  246. constexpr int kMaxColors = 12;
  247. SkPoint pts[2];
  248. SkColor colors[kMaxColors];
  249. SkScalar pos[kMaxColors];
  250. int colorCount;
  251. bool usePos;
  252. fuzz->nextN(pts, 2);
  253. fuzz->nextRange(&colorCount, 2, kMaxColors);
  254. fuzz->nextN(colors, colorCount);
  255. fuzz->nextEnum(&tmX, SkTileMode::kLastTileMode);
  256. fuzz->next(&useMatrix, &usePos);
  257. if (useMatrix) {
  258. FuzzNiceMatrix(fuzz, &matrix);
  259. }
  260. if (usePos) {
  261. fuzz_gradient_stops(fuzz, pos, colorCount);
  262. }
  263. return SkGradientShader::MakeLinear(pts, colors, usePos ? pos : nullptr, colorCount,
  264. tmX, 0, useMatrix ? &matrix : nullptr);
  265. }
  266. case 11: {
  267. constexpr int kMaxColors = 12;
  268. SkPoint center;
  269. SkScalar radius;
  270. int colorCount;
  271. bool usePos;
  272. SkColor colors[kMaxColors];
  273. SkScalar pos[kMaxColors];
  274. fuzz->nextEnum(&tmX, SkTileMode::kLastTileMode);
  275. fuzz->next(&useMatrix, &usePos, &center, &radius);
  276. fuzz->nextRange(&colorCount, 2, kMaxColors);
  277. fuzz->nextN(colors, colorCount);
  278. if (useMatrix) {
  279. FuzzNiceMatrix(fuzz, &matrix);
  280. }
  281. if (usePos) {
  282. fuzz_gradient_stops(fuzz, pos, colorCount);
  283. }
  284. return SkGradientShader::MakeRadial(center, radius, colors, usePos ? pos : nullptr,
  285. colorCount, tmX, 0, useMatrix ? &matrix : nullptr);
  286. }
  287. case 12: {
  288. constexpr int kMaxColors = 12;
  289. SkPoint start, end;
  290. SkScalar startRadius, endRadius;
  291. int colorCount;
  292. bool usePos;
  293. SkColor colors[kMaxColors];
  294. SkScalar pos[kMaxColors];
  295. fuzz->nextEnum(&tmX, SkTileMode::kLastTileMode);
  296. fuzz->next(&useMatrix, &usePos, &startRadius, &endRadius, &start, &end);
  297. fuzz->nextRange(&colorCount, 2, kMaxColors);
  298. fuzz->nextN(colors, colorCount);
  299. if (useMatrix) {
  300. FuzzNiceMatrix(fuzz, &matrix);
  301. }
  302. if (usePos) {
  303. fuzz_gradient_stops(fuzz, pos, colorCount);
  304. }
  305. return SkGradientShader::MakeTwoPointConical(start, startRadius, end, endRadius, colors,
  306. usePos ? pos : nullptr, colorCount, tmX, 0,
  307. useMatrix ? &matrix : nullptr);
  308. }
  309. case 13: {
  310. constexpr int kMaxColors = 12;
  311. SkScalar cx, cy;
  312. int colorCount;
  313. bool usePos;
  314. SkColor colors[kMaxColors];
  315. SkScalar pos[kMaxColors];
  316. fuzz->next(&cx, &cy, &useMatrix, &usePos);
  317. fuzz->nextRange(&colorCount, 2, kMaxColors);
  318. fuzz->nextN(colors, colorCount);
  319. if (useMatrix) {
  320. FuzzNiceMatrix(fuzz, &matrix);
  321. }
  322. if (usePos) {
  323. fuzz_gradient_stops(fuzz, pos, colorCount);
  324. }
  325. return SkGradientShader::MakeSweep(cx, cy, colors, usePos ? pos : nullptr, colorCount,
  326. 0, useMatrix ? &matrix : nullptr);
  327. }
  328. case 14: {
  329. SkScalar baseFrequencyX, baseFrequencyY, seed;
  330. int numOctaves;
  331. SkISize tileSize;
  332. bool useTileSize, turbulence;
  333. fuzz->next(&baseFrequencyX, &baseFrequencyY, &seed, &useTileSize, &turbulence);
  334. if (useTileSize) {
  335. fuzz->next(&tileSize);
  336. }
  337. fuzz->nextRange(&numOctaves, 2, 7);
  338. if (turbulence) {
  339. return SkPerlinNoiseShader::MakeTurbulence(baseFrequencyX, baseFrequencyY,
  340. numOctaves, seed,
  341. useTileSize ? &tileSize : nullptr);
  342. } else {
  343. return SkPerlinNoiseShader::MakeFractalNoise(baseFrequencyX, baseFrequencyY,
  344. numOctaves, seed,
  345. useTileSize ? &tileSize : nullptr);
  346. }
  347. }
  348. default:
  349. SkASSERT(false);
  350. break;
  351. }
  352. return nullptr;
  353. }
  354. static sk_sp<SkPathEffect> make_fuzz_patheffect(Fuzz* fuzz, int depth) {
  355. if (depth <= 0) {
  356. return nullptr;
  357. }
  358. uint8_t pathEffectType;
  359. fuzz->nextRange(&pathEffectType, 0, 8);
  360. switch (pathEffectType) {
  361. case 0: {
  362. return nullptr;
  363. }
  364. case 1: {
  365. sk_sp<SkPathEffect> first = make_fuzz_patheffect(fuzz, depth - 1);
  366. sk_sp<SkPathEffect> second = make_fuzz_patheffect(fuzz, depth - 1);
  367. return SkPathEffect::MakeSum(std::move(first), std::move(second));
  368. }
  369. case 2: {
  370. sk_sp<SkPathEffect> first = make_fuzz_patheffect(fuzz, depth - 1);
  371. sk_sp<SkPathEffect> second = make_fuzz_patheffect(fuzz, depth - 1);
  372. return SkPathEffect::MakeCompose(std::move(first), std::move(second));
  373. }
  374. case 3: {
  375. SkPath path;
  376. FuzzNicePath(fuzz, &path, 20);
  377. SkScalar advance, phase;
  378. fuzz->next(&advance, &phase);
  379. SkPath1DPathEffect::Style style;
  380. fuzz->nextEnum(&style, SkPath1DPathEffect::kLastEnum_Style);
  381. return SkPath1DPathEffect::Make(path, advance, phase, style);
  382. }
  383. case 4: {
  384. SkScalar width;
  385. SkMatrix matrix;
  386. fuzz->next(&width);
  387. FuzzNiceMatrix(fuzz, &matrix);
  388. return SkLine2DPathEffect::Make(width, matrix);
  389. }
  390. case 5: {
  391. SkPath path;
  392. FuzzNicePath(fuzz, &path, 20);
  393. SkMatrix matrix;
  394. FuzzNiceMatrix(fuzz, &matrix);
  395. return SkPath2DPathEffect::Make(matrix, path);
  396. }
  397. case 6: {
  398. SkScalar radius;
  399. fuzz->next(&radius);
  400. return SkCornerPathEffect::Make(radius);
  401. }
  402. case 7: {
  403. SkScalar phase;
  404. fuzz->next(&phase);
  405. SkScalar intervals[20];
  406. int count;
  407. fuzz->nextRange(&count, 0, (int)SK_ARRAY_COUNT(intervals));
  408. fuzz->nextN(intervals, count);
  409. return SkDashPathEffect::Make(intervals, count, phase);
  410. }
  411. case 8: {
  412. SkScalar segLength, dev;
  413. uint32_t seed;
  414. fuzz->next(&segLength, &dev, &seed);
  415. return SkDiscretePathEffect::Make(segLength, dev, seed);
  416. }
  417. default:
  418. SkASSERT(false);
  419. return nullptr;
  420. }
  421. }
  422. static sk_sp<SkMaskFilter> make_fuzz_maskfilter(Fuzz* fuzz) {
  423. int maskfilterType;
  424. fuzz->nextRange(&maskfilterType, 0, 1);
  425. switch (maskfilterType) {
  426. case 0:
  427. return nullptr;
  428. case 1: {
  429. SkBlurStyle blurStyle;
  430. fuzz->nextEnum(&blurStyle, kLastEnum_SkBlurStyle);
  431. SkScalar sigma;
  432. fuzz->next(&sigma);
  433. bool respectCTM;
  434. fuzz->next(&respectCTM);
  435. return SkMaskFilter::MakeBlur(blurStyle, sigma, respectCTM);
  436. }
  437. default:
  438. SkASSERT(false);
  439. return nullptr;
  440. }
  441. }
  442. static sk_sp<SkTypeface> make_fuzz_typeface(Fuzz* fuzz) {
  443. if (make_fuzz_t<bool>(fuzz)) {
  444. return nullptr;
  445. }
  446. auto fontMugger = SkFontMgr::RefDefault();
  447. SkASSERT(fontMugger);
  448. int familyCount = fontMugger->countFamilies();
  449. int i, j;
  450. fuzz->nextRange(&i, 0, familyCount - 1);
  451. sk_sp<SkFontStyleSet> family(fontMugger->createStyleSet(i));
  452. int styleCount = family->count();
  453. fuzz->nextRange(&j, 0, styleCount - 1);
  454. return sk_sp<SkTypeface>(family->createTypeface(j));
  455. }
  456. static sk_sp<SkImageFilter> make_fuzz_imageFilter(Fuzz* fuzz, int depth);
  457. static sk_sp<SkImageFilter> make_fuzz_lighting_imagefilter(Fuzz* fuzz, int depth) {
  458. if (depth <= 0) {
  459. return nullptr;
  460. }
  461. uint8_t imageFilterType;
  462. fuzz->nextRange(&imageFilterType, 1, 6);
  463. SkPoint3 p, q;
  464. SkColor lightColor;
  465. SkScalar surfaceScale, k, specularExponent, cutoffAngle, shininess;
  466. sk_sp<SkImageFilter> input;
  467. SkImageFilter::CropRect cropRect;
  468. bool useCropRect;
  469. fuzz->next(&useCropRect);
  470. if (useCropRect) {
  471. fuzz->next(&cropRect);
  472. }
  473. switch (imageFilterType) {
  474. case 1:
  475. fuzz->next(&p, &lightColor, &surfaceScale, &k);
  476. input = make_fuzz_imageFilter(fuzz, depth - 1);
  477. return SkLightingImageFilter::MakeDistantLitDiffuse(p, lightColor, surfaceScale, k,
  478. std::move(input),
  479. useCropRect ? &cropRect : nullptr);
  480. case 2:
  481. fuzz->next(&p, &lightColor, &surfaceScale, &k);
  482. input = make_fuzz_imageFilter(fuzz, depth - 1);
  483. return SkLightingImageFilter::MakePointLitDiffuse(p, lightColor, surfaceScale, k,
  484. std::move(input),
  485. useCropRect ? &cropRect : nullptr);
  486. case 3:
  487. fuzz->next(&p, &q, &specularExponent, &cutoffAngle, &lightColor, &surfaceScale, &k);
  488. input = make_fuzz_imageFilter(fuzz, depth - 1);
  489. return SkLightingImageFilter::MakeSpotLitDiffuse(
  490. p, q, specularExponent, cutoffAngle, lightColor, surfaceScale, k,
  491. std::move(input), useCropRect ? &cropRect : nullptr);
  492. case 4:
  493. fuzz->next(&p, &lightColor, &surfaceScale, &k, &shininess);
  494. input = make_fuzz_imageFilter(fuzz, depth - 1);
  495. return SkLightingImageFilter::MakeDistantLitSpecular(p, lightColor, surfaceScale, k,
  496. shininess, std::move(input),
  497. useCropRect ? &cropRect : nullptr);
  498. case 5:
  499. fuzz->next(&p, &lightColor, &surfaceScale, &k, &shininess);
  500. input = make_fuzz_imageFilter(fuzz, depth - 1);
  501. return SkLightingImageFilter::MakePointLitSpecular(p, lightColor, surfaceScale, k,
  502. shininess, std::move(input),
  503. useCropRect ? &cropRect : nullptr);
  504. case 6:
  505. fuzz->next(&p, &q, &specularExponent, &cutoffAngle, &lightColor, &surfaceScale, &k,
  506. &shininess);
  507. input = make_fuzz_imageFilter(fuzz, depth - 1);
  508. return SkLightingImageFilter::MakeSpotLitSpecular(
  509. p, q, specularExponent, cutoffAngle, lightColor, surfaceScale, k, shininess,
  510. std::move(input), useCropRect ? &cropRect : nullptr);
  511. default:
  512. SkASSERT(false);
  513. return nullptr;
  514. }
  515. }
  516. static void fuzz_paint(Fuzz* fuzz, SkPaint* paint, int depth);
  517. static sk_sp<SkImageFilter> make_fuzz_imageFilter(Fuzz* fuzz, int depth) {
  518. if (depth <= 0) {
  519. return nullptr;
  520. }
  521. uint8_t imageFilterType;
  522. fuzz->nextRange(&imageFilterType, 0, 23);
  523. switch (imageFilterType) {
  524. case 0:
  525. return nullptr;
  526. case 1: {
  527. SkScalar sigmaX, sigmaY;
  528. sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
  529. bool useCropRect;
  530. fuzz->next(&sigmaX, &sigmaY, &useCropRect);
  531. SkImageFilter::CropRect cropRect;
  532. if (useCropRect) {
  533. fuzz->next(&cropRect);
  534. }
  535. return SkBlurImageFilter::Make(sigmaX, sigmaY, std::move(input),
  536. useCropRect ? &cropRect : nullptr);
  537. }
  538. case 2: {
  539. SkMatrix matrix;
  540. FuzzNiceMatrix(fuzz, &matrix);
  541. SkFilterQuality quality;
  542. fuzz->nextEnum(&quality, SkFilterQuality::kLast_SkFilterQuality);
  543. sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
  544. return SkImageFilter::MakeMatrixFilter(matrix, quality, std::move(input));
  545. }
  546. case 3: {
  547. SkRegion region;
  548. SkScalar innerMin, outerMax;
  549. sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
  550. bool useCropRect;
  551. fuzz->next(&region, &innerMin, &outerMax, &useCropRect);
  552. SkImageFilter::CropRect cropRect;
  553. if (useCropRect) {
  554. fuzz->next(&cropRect);
  555. }
  556. return SkAlphaThresholdFilter::Make(region, innerMin, outerMax, std::move(input),
  557. useCropRect ? &cropRect : nullptr);
  558. }
  559. case 4: {
  560. float k1, k2, k3, k4;
  561. bool enforcePMColor;
  562. bool useCropRect;
  563. fuzz->next(&k1, &k2, &k3, &k4, &enforcePMColor, &useCropRect);
  564. sk_sp<SkImageFilter> background = make_fuzz_imageFilter(fuzz, depth - 1);
  565. sk_sp<SkImageFilter> foreground = make_fuzz_imageFilter(fuzz, depth - 1);
  566. SkImageFilter::CropRect cropRect;
  567. if (useCropRect) {
  568. fuzz->next(&cropRect);
  569. }
  570. return SkArithmeticImageFilter::Make(k1, k2, k3, k4, enforcePMColor,
  571. std::move(background), std::move(foreground),
  572. useCropRect ? &cropRect : nullptr);
  573. }
  574. case 5: {
  575. sk_sp<SkColorFilter> cf = make_fuzz_colorfilter(fuzz, depth - 1);
  576. sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
  577. bool useCropRect;
  578. SkImageFilter::CropRect cropRect;
  579. fuzz->next(&useCropRect);
  580. if (useCropRect) {
  581. fuzz->next(&cropRect);
  582. }
  583. return SkColorFilterImageFilter::Make(std::move(cf), std::move(input),
  584. useCropRect ? &cropRect : nullptr);
  585. }
  586. case 6: {
  587. sk_sp<SkImageFilter> ifo = make_fuzz_imageFilter(fuzz, depth - 1);
  588. sk_sp<SkImageFilter> ifi = make_fuzz_imageFilter(fuzz, depth - 1);
  589. return SkComposeImageFilter::Make(std::move(ifo), std::move(ifi));
  590. }
  591. case 7: {
  592. SkDisplacementMapEffect::ChannelSelectorType xChannelSelector, yChannelSelector;
  593. fuzz->nextRange(&xChannelSelector, 1, 4);
  594. fuzz->nextRange(&yChannelSelector, 1, 4);
  595. SkScalar scale;
  596. bool useCropRect;
  597. fuzz->next(&scale, &useCropRect);
  598. SkImageFilter::CropRect cropRect;
  599. if (useCropRect) {
  600. fuzz->next(&cropRect);
  601. }
  602. sk_sp<SkImageFilter> displacement = make_fuzz_imageFilter(fuzz, depth - 1);
  603. sk_sp<SkImageFilter> color = make_fuzz_imageFilter(fuzz, depth - 1);
  604. return SkDisplacementMapEffect::Make(xChannelSelector, yChannelSelector, scale,
  605. std::move(displacement), std::move(color),
  606. useCropRect ? &cropRect : nullptr);
  607. }
  608. case 8: {
  609. SkScalar dx, dy, sigmaX, sigmaY;
  610. SkColor color;
  611. SkDropShadowImageFilter::ShadowMode shadowMode;
  612. fuzz->nextRange(&shadowMode, 0, 1);
  613. bool useCropRect;
  614. fuzz->next(&dx, &dy, &sigmaX, &sigmaY, &color, &useCropRect);
  615. SkImageFilter::CropRect cropRect;
  616. if (useCropRect) {
  617. fuzz->next(&cropRect);
  618. }
  619. sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
  620. return SkDropShadowImageFilter::Make(dx, dy, sigmaX, sigmaY, color, shadowMode,
  621. std::move(input),
  622. useCropRect ? &cropRect : nullptr);
  623. }
  624. case 9:
  625. return SkImageSource::Make(make_fuzz_image(fuzz));
  626. case 10: {
  627. sk_sp<SkImage> image = make_fuzz_image(fuzz);
  628. SkRect srcRect, dstRect;
  629. SkFilterQuality filterQuality;
  630. fuzz->next(&srcRect, &dstRect);
  631. fuzz->nextEnum(&filterQuality, SkFilterQuality::kLast_SkFilterQuality);
  632. return SkImageSource::Make(std::move(image), srcRect, dstRect, filterQuality);
  633. }
  634. case 11:
  635. return make_fuzz_lighting_imagefilter(fuzz, depth - 1);
  636. case 12: {
  637. SkRect srcRect;
  638. SkScalar inset;
  639. bool useCropRect;
  640. SkImageFilter::CropRect cropRect;
  641. fuzz->next(&srcRect, &inset, &useCropRect);
  642. if (useCropRect) {
  643. fuzz->next(&cropRect);
  644. }
  645. sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
  646. return SkMagnifierImageFilter::Make(srcRect, inset, std::move(input),
  647. useCropRect ? &cropRect : nullptr);
  648. }
  649. case 13: {
  650. constexpr int kMaxKernelSize = 5;
  651. int32_t n, m;
  652. fuzz->nextRange(&n, 1, kMaxKernelSize);
  653. fuzz->nextRange(&m, 1, kMaxKernelSize);
  654. SkScalar kernel[kMaxKernelSize * kMaxKernelSize];
  655. fuzz->nextN(kernel, n * m);
  656. int32_t offsetX, offsetY;
  657. fuzz->nextRange(&offsetX, 0, n - 1);
  658. fuzz->nextRange(&offsetY, 0, m - 1);
  659. SkScalar gain, bias;
  660. bool convolveAlpha, useCropRect;
  661. fuzz->next(&gain, &bias, &convolveAlpha, &useCropRect);
  662. SkMatrixConvolutionImageFilter::TileMode tileMode;
  663. fuzz->nextEnum(&tileMode, SkMatrixConvolutionImageFilter::TileMode::kLast_TileMode);
  664. SkImageFilter::CropRect cropRect;
  665. if (useCropRect) {
  666. fuzz->next(&cropRect);
  667. }
  668. sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
  669. return SkMatrixConvolutionImageFilter::Make(
  670. SkISize{n, m}, kernel, gain, bias, SkIPoint{offsetX, offsetY}, tileMode,
  671. convolveAlpha, std::move(input), useCropRect ? &cropRect : nullptr);
  672. }
  673. case 14: {
  674. sk_sp<SkImageFilter> first = make_fuzz_imageFilter(fuzz, depth - 1);
  675. sk_sp<SkImageFilter> second = make_fuzz_imageFilter(fuzz, depth - 1);
  676. bool useCropRect;
  677. fuzz->next(&useCropRect);
  678. SkImageFilter::CropRect cropRect;
  679. if (useCropRect) {
  680. fuzz->next(&cropRect);
  681. }
  682. return SkMergeImageFilter::Make(std::move(first), std::move(second),
  683. useCropRect ? &cropRect : nullptr);
  684. }
  685. case 15: {
  686. constexpr int kMaxCount = 4;
  687. sk_sp<SkImageFilter> ifs[kMaxCount];
  688. int count;
  689. fuzz->nextRange(&count, 1, kMaxCount);
  690. for (int i = 0; i < count; ++i) {
  691. ifs[i] = make_fuzz_imageFilter(fuzz, depth - 1);
  692. }
  693. bool useCropRect;
  694. fuzz->next(&useCropRect);
  695. SkImageFilter::CropRect cropRect;
  696. if (useCropRect) {
  697. fuzz->next(&cropRect);
  698. }
  699. return SkMergeImageFilter::Make(ifs, count, useCropRect ? &cropRect : nullptr);
  700. }
  701. case 16: {
  702. int rx, ry;
  703. fuzz->next(&rx, &ry);
  704. bool useCropRect;
  705. fuzz->next(&useCropRect);
  706. SkImageFilter::CropRect cropRect;
  707. if (useCropRect) {
  708. fuzz->next(&cropRect);
  709. }
  710. sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
  711. return SkDilateImageFilter::Make(rx, ry, std::move(input),
  712. useCropRect ? &cropRect : nullptr);
  713. }
  714. case 17: {
  715. int rx, ry;
  716. fuzz->next(&rx, &ry);
  717. bool useCropRect;
  718. fuzz->next(&useCropRect);
  719. SkImageFilter::CropRect cropRect;
  720. if (useCropRect) {
  721. fuzz->next(&cropRect);
  722. }
  723. sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
  724. return SkErodeImageFilter::Make(rx, ry, std::move(input),
  725. useCropRect ? &cropRect : nullptr);
  726. }
  727. case 18: {
  728. SkScalar dx, dy;
  729. fuzz->next(&dx, &dy);
  730. bool useCropRect;
  731. fuzz->next(&useCropRect);
  732. SkImageFilter::CropRect cropRect;
  733. if (useCropRect) {
  734. fuzz->next(&cropRect);
  735. }
  736. sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
  737. return SkOffsetImageFilter::Make(dx, dy, std::move(input),
  738. useCropRect ? &cropRect : nullptr);
  739. }
  740. case 19: {
  741. SkPaint paint;
  742. fuzz_paint(fuzz, &paint, depth - 1);
  743. bool useCropRect;
  744. fuzz->next(&useCropRect);
  745. SkImageFilter::CropRect cropRect;
  746. if (useCropRect) {
  747. fuzz->next(&cropRect);
  748. }
  749. return SkPaintImageFilter::Make(paint, useCropRect ? &cropRect : nullptr);
  750. }
  751. case 20: {
  752. sk_sp<SkPicture> picture = make_fuzz_picture(fuzz, depth - 1);
  753. return SkPictureImageFilter::Make(std::move(picture));
  754. }
  755. case 21: {
  756. SkRect cropRect;
  757. fuzz->next(&cropRect);
  758. sk_sp<SkPicture> picture = make_fuzz_picture(fuzz, depth - 1);
  759. return SkPictureImageFilter::Make(std::move(picture), cropRect);
  760. }
  761. case 22: {
  762. SkRect src, dst;
  763. fuzz->next(&src, &dst);
  764. sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
  765. return SkTileImageFilter::Make(src, dst, std::move(input));
  766. }
  767. case 23: {
  768. SkBlendMode blendMode;
  769. bool useCropRect;
  770. fuzz->next(&useCropRect);
  771. fuzz->nextEnum(&blendMode, SkBlendMode::kLastMode);
  772. SkImageFilter::CropRect cropRect;
  773. if (useCropRect) {
  774. fuzz->next(&cropRect);
  775. }
  776. sk_sp<SkImageFilter> bg = make_fuzz_imageFilter(fuzz, depth - 1);
  777. sk_sp<SkImageFilter> fg = make_fuzz_imageFilter(fuzz, depth - 1);
  778. return SkXfermodeImageFilter::Make(blendMode, std::move(bg), std::move(fg),
  779. useCropRect ? &cropRect : nullptr);
  780. }
  781. default:
  782. SkASSERT(false);
  783. return nullptr;
  784. }
  785. }
  786. static sk_sp<SkImage> make_fuzz_image(Fuzz* fuzz) {
  787. int w, h;
  788. fuzz->nextRange(&w, 1, 1024);
  789. fuzz->nextRange(&h, 1, 1024);
  790. SkAutoTMalloc<SkPMColor> data(w * h);
  791. SkPixmap pixmap(SkImageInfo::MakeN32Premul(w, h), data.get(), w * sizeof(SkPMColor));
  792. int n = w * h;
  793. for (int i = 0; i < n; ++i) {
  794. SkColor c;
  795. fuzz->next(&c);
  796. data[i] = SkPreMultiplyColor(c);
  797. }
  798. (void)data.release();
  799. return SkImage::MakeFromRaster(pixmap, [](const void* p, void*) { sk_free((void*)p); },
  800. nullptr);
  801. }
  802. static SkBitmap make_fuzz_bitmap(Fuzz* fuzz) {
  803. SkBitmap bitmap;
  804. int w, h;
  805. fuzz->nextRange(&w, 1, 1024);
  806. fuzz->nextRange(&h, 1, 1024);
  807. if (!bitmap.tryAllocN32Pixels(w, h)) {
  808. SkDEBUGF("Could not allocate pixels %d x %d", w, h);
  809. return bitmap;
  810. }
  811. for (int y = 0; y < h; ++y) {
  812. for (int x = 0; x < w; ++x) {
  813. SkColor c;
  814. fuzz->next(&c);
  815. *bitmap.getAddr32(x, y) = SkPreMultiplyColor(c);
  816. }
  817. }
  818. return bitmap;
  819. }
  820. template <typename T>
  821. static T make_fuzz_enum_range(Fuzz* fuzz, T maxv) {
  822. T value;
  823. fuzz->nextEnum(&value, maxv);
  824. return value;
  825. }
  826. static void fuzz_paint(Fuzz* fuzz, SkPaint* paint, int depth) {
  827. if (!fuzz || !paint || depth <= 0) {
  828. return;
  829. }
  830. paint->setAntiAlias( make_fuzz_t<bool>(fuzz));
  831. paint->setDither( make_fuzz_t<bool>(fuzz));
  832. paint->setColor( make_fuzz_t<SkColor>(fuzz));
  833. paint->setBlendMode( make_fuzz_enum_range<SkBlendMode>(fuzz, SkBlendMode::kLastMode));
  834. paint->setFilterQuality(make_fuzz_enum_range<SkFilterQuality>(fuzz, kLast_SkFilterQuality));
  835. paint->setStyle( make_fuzz_enum_range<SkPaint::Style>(fuzz,
  836. SkPaint::Style::kStrokeAndFill_Style));
  837. paint->setShader( make_fuzz_shader(fuzz, depth - 1));
  838. paint->setPathEffect( make_fuzz_patheffect(fuzz, depth - 1));
  839. paint->setMaskFilter( make_fuzz_maskfilter(fuzz));
  840. paint->setImageFilter( make_fuzz_imageFilter(fuzz, depth - 1));
  841. paint->setColorFilter( make_fuzz_colorfilter(fuzz, depth - 1));
  842. if (paint->getStyle() != SkPaint::kFill_Style) {
  843. paint->setStrokeWidth(make_fuzz_t<SkScalar>(fuzz));
  844. paint->setStrokeMiter(make_fuzz_t<SkScalar>(fuzz));
  845. paint->setStrokeCap( make_fuzz_enum_range<SkPaint::Cap>(fuzz, SkPaint::kLast_Cap));
  846. paint->setStrokeJoin( make_fuzz_enum_range<SkPaint::Join>(fuzz, SkPaint::kLast_Join));
  847. }
  848. }
  849. static SkFont fuzz_font(Fuzz* fuzz) {
  850. SkFont font;
  851. font.setTypeface( make_fuzz_typeface(fuzz));
  852. font.setSize( make_fuzz_t<SkScalar>(fuzz));
  853. font.setScaleX( make_fuzz_t<SkScalar>(fuzz));
  854. font.setSkewX( make_fuzz_t<SkScalar>(fuzz));
  855. font.setLinearMetrics( make_fuzz_t<bool>(fuzz));
  856. font.setSubpixel( make_fuzz_t<bool>(fuzz));
  857. font.setEmbeddedBitmaps( make_fuzz_t<bool>(fuzz));
  858. font.setForceAutoHinting( make_fuzz_t<bool>(fuzz));
  859. font.setEmbolden( make_fuzz_t<bool>(fuzz));
  860. font.setHinting( make_fuzz_enum_range<SkFontHinting>(fuzz, SkFontHinting::kFull));
  861. font.setEdging( make_fuzz_enum_range<SkFont::Edging>(fuzz,
  862. SkFont::Edging::kSubpixelAntiAlias));
  863. return font;
  864. }
  865. static SkTextEncoding fuzz_paint_text_encoding(Fuzz* fuzz) {
  866. return make_fuzz_enum_range<SkTextEncoding>(fuzz, SkTextEncoding::kUTF32);
  867. }
  868. constexpr int kMaxGlyphCount = 30;
  869. static SkTDArray<uint8_t> make_fuzz_text(Fuzz* fuzz, const SkFont& font, SkTextEncoding encoding) {
  870. SkTDArray<uint8_t> array;
  871. if (SkTextEncoding::kGlyphID == encoding) {
  872. int glyphRange = font.getTypefaceOrDefault()->countGlyphs();
  873. if (glyphRange == 0) {
  874. // Some fuzzing environments have no fonts, so empty array is the best
  875. // we can do.
  876. return array;
  877. }
  878. int glyphCount;
  879. fuzz->nextRange(&glyphCount, 1, kMaxGlyphCount);
  880. SkGlyphID* glyphs = (SkGlyphID*)array.append(glyphCount * sizeof(SkGlyphID));
  881. for (int i = 0; i < glyphCount; ++i) {
  882. fuzz->nextRange(&glyphs[i], 0, glyphRange - 1);
  883. }
  884. return array;
  885. }
  886. static const SkUnichar ranges[][2] = {
  887. {0x0020, 0x007F},
  888. {0x00A1, 0x0250},
  889. {0x0400, 0x0500},
  890. };
  891. int32_t count = 0;
  892. for (size_t i = 0; i < SK_ARRAY_COUNT(ranges); ++i) {
  893. count += (ranges[i][1] - ranges[i][0]);
  894. }
  895. constexpr int kMaxLength = kMaxGlyphCount;
  896. SkUnichar buffer[kMaxLength];
  897. int length;
  898. fuzz->nextRange(&length, 1, kMaxLength);
  899. for (int j = 0; j < length; ++j) {
  900. int32_t value;
  901. fuzz->nextRange(&value, 0, count - 1);
  902. for (size_t i = 0; i < SK_ARRAY_COUNT(ranges); ++i) {
  903. if (value + ranges[i][0] < ranges[i][1]) {
  904. buffer[j] = value + ranges[i][0];
  905. break;
  906. } else {
  907. value -= (ranges[i][1] - ranges[i][0]);
  908. }
  909. }
  910. }
  911. switch (encoding) {
  912. case SkTextEncoding::kUTF8: {
  913. size_t utf8len = 0;
  914. for (int j = 0; j < length; ++j) {
  915. utf8len += SkUTF::ToUTF8(buffer[j], nullptr);
  916. }
  917. char* ptr = (char*)array.append(utf8len);
  918. for (int j = 0; j < length; ++j) {
  919. ptr += SkUTF::ToUTF8(buffer[j], ptr);
  920. }
  921. } break;
  922. case SkTextEncoding::kUTF16: {
  923. size_t utf16len = 0;
  924. for (int j = 0; j < length; ++j) {
  925. utf16len += SkUTF::ToUTF16(buffer[j]);
  926. }
  927. uint16_t* ptr = (uint16_t*)array.append(utf16len * sizeof(uint16_t));
  928. for (int j = 0; j < length; ++j) {
  929. ptr += SkUTF::ToUTF16(buffer[j], ptr);
  930. }
  931. } break;
  932. case SkTextEncoding::kUTF32:
  933. memcpy(array.append(length * sizeof(SkUnichar)), buffer, length * sizeof(SkUnichar));
  934. break;
  935. default:
  936. SkASSERT(false);
  937. break;
  938. }
  939. return array;
  940. }
  941. static sk_sp<SkTextBlob> make_fuzz_textblob(Fuzz* fuzz) {
  942. SkTextBlobBuilder textBlobBuilder;
  943. int8_t runCount;
  944. fuzz->nextRange(&runCount, (int8_t)1, (int8_t)8);
  945. while (runCount-- > 0) {
  946. SkFont font;
  947. SkTextEncoding encoding = fuzz_paint_text_encoding(fuzz);
  948. font.setEdging(make_fuzz_t<bool>(fuzz) ? SkFont::Edging::kAlias : SkFont::Edging::kAntiAlias);
  949. SkTDArray<uint8_t> text = make_fuzz_text(fuzz, font, encoding);
  950. int glyphCount = font.countText(text.begin(), SkToSizeT(text.count()), encoding);
  951. SkASSERT(glyphCount <= kMaxGlyphCount);
  952. SkScalar x, y;
  953. const SkTextBlobBuilder::RunBuffer* buffer;
  954. uint8_t runType;
  955. fuzz->nextRange(&runType, (uint8_t)0, (uint8_t)2);
  956. const void* textPtr = text.begin();
  957. size_t textLen = SkToSizeT(text.count());
  958. switch (runType) {
  959. case 0:
  960. fuzz->next(&x, &y);
  961. // TODO: Test other variations of this.
  962. buffer = &textBlobBuilder.allocRun(font, glyphCount, x, y);
  963. (void)font.textToGlyphs(textPtr, textLen, encoding, buffer->glyphs, glyphCount);
  964. break;
  965. case 1:
  966. fuzz->next(&y);
  967. // TODO: Test other variations of this.
  968. buffer = &textBlobBuilder.allocRunPosH(font, glyphCount, y);
  969. (void)font.textToGlyphs(textPtr, textLen, encoding, buffer->glyphs, glyphCount);
  970. fuzz->nextN(buffer->pos, glyphCount);
  971. break;
  972. case 2:
  973. // TODO: Test other variations of this.
  974. buffer = &textBlobBuilder.allocRunPos(font, glyphCount);
  975. (void)font.textToGlyphs(textPtr, textLen, encoding, buffer->glyphs, glyphCount);
  976. fuzz->nextN(buffer->pos, glyphCount * 2);
  977. break;
  978. default:
  979. SkASSERT(false);
  980. break;
  981. }
  982. }
  983. return textBlobBuilder.make();
  984. }
  985. static void fuzz_canvas(Fuzz* fuzz, SkCanvas* canvas, int depth = 9) {
  986. if (!fuzz || !canvas || depth <= 0) {
  987. return;
  988. }
  989. SkAutoCanvasRestore autoCanvasRestore(canvas, false);
  990. unsigned N;
  991. fuzz->nextRange(&N, 0, 2000);
  992. for (unsigned i = 0; i < N; ++i) {
  993. if (fuzz->exhausted()) {
  994. return;
  995. }
  996. SkPaint paint;
  997. SkFont font;
  998. unsigned drawCommand;
  999. fuzz->nextRange(&drawCommand, 0, 53);
  1000. switch (drawCommand) {
  1001. case 0:
  1002. canvas->flush();
  1003. break;
  1004. case 1:
  1005. canvas->save();
  1006. break;
  1007. case 2: {
  1008. SkRect bounds;
  1009. fuzz->next(&bounds);
  1010. fuzz_paint(fuzz, &paint, depth - 1);
  1011. canvas->saveLayer(&bounds, &paint);
  1012. break;
  1013. }
  1014. case 3: {
  1015. SkRect bounds;
  1016. fuzz->next(&bounds);
  1017. canvas->saveLayer(&bounds, nullptr);
  1018. break;
  1019. }
  1020. case 4:
  1021. fuzz_paint(fuzz, &paint, depth - 1);
  1022. canvas->saveLayer(nullptr, &paint);
  1023. break;
  1024. case 5:
  1025. canvas->saveLayer(nullptr, nullptr);
  1026. break;
  1027. case 6: {
  1028. uint8_t alpha;
  1029. fuzz->next(&alpha);
  1030. canvas->saveLayerAlpha(nullptr, (U8CPU)alpha);
  1031. break;
  1032. }
  1033. case 7: {
  1034. SkRect bounds;
  1035. uint8_t alpha;
  1036. fuzz->next(&bounds, &alpha);
  1037. canvas->saveLayerAlpha(&bounds, (U8CPU)alpha);
  1038. break;
  1039. }
  1040. case 8: {
  1041. SkCanvas::SaveLayerRec saveLayerRec;
  1042. SkRect bounds;
  1043. if (make_fuzz_t<bool>(fuzz)) {
  1044. fuzz->next(&bounds);
  1045. saveLayerRec.fBounds = &bounds;
  1046. }
  1047. if (make_fuzz_t<bool>(fuzz)) {
  1048. fuzz_paint(fuzz, &paint, depth - 1);
  1049. saveLayerRec.fPaint = &paint;
  1050. }
  1051. sk_sp<SkImageFilter> imageFilter;
  1052. if (make_fuzz_t<bool>(fuzz)) {
  1053. imageFilter = make_fuzz_imageFilter(fuzz, depth - 1);
  1054. saveLayerRec.fBackdrop = imageFilter.get();
  1055. }
  1056. // _DumpCanvas can't handle this.
  1057. // if (make_fuzz_t<bool>(fuzz)) {
  1058. // saveLayerRec.fSaveLayerFlags |= SkCanvas::kPreserveLCDText_SaveLayerFlag;
  1059. // }
  1060. canvas->saveLayer(saveLayerRec);
  1061. break;
  1062. }
  1063. case 9:
  1064. canvas->restore();
  1065. break;
  1066. case 10: {
  1067. int saveCount;
  1068. fuzz->next(&saveCount);
  1069. canvas->restoreToCount(saveCount);
  1070. break;
  1071. }
  1072. case 11: {
  1073. SkScalar x, y;
  1074. fuzz->next(&x, &y);
  1075. canvas->translate(x, y);
  1076. break;
  1077. }
  1078. case 12: {
  1079. SkScalar x, y;
  1080. fuzz->next(&x, &y);
  1081. canvas->scale(x, y);
  1082. break;
  1083. }
  1084. case 13: {
  1085. SkScalar v;
  1086. fuzz->next(&v);
  1087. canvas->rotate(v);
  1088. break;
  1089. }
  1090. case 14: {
  1091. SkScalar x, y, v;
  1092. fuzz->next(&x, &y, &v);
  1093. canvas->rotate(v, x, y);
  1094. break;
  1095. }
  1096. case 15: {
  1097. SkScalar x, y;
  1098. fuzz->next(&x, &y);
  1099. canvas->skew(x, y);
  1100. break;
  1101. }
  1102. case 16: {
  1103. SkMatrix mat;
  1104. FuzzNiceMatrix(fuzz, &mat);
  1105. canvas->concat(mat);
  1106. break;
  1107. }
  1108. case 17: {
  1109. SkMatrix mat;
  1110. FuzzNiceMatrix(fuzz, &mat);
  1111. canvas->setMatrix(mat);
  1112. break;
  1113. }
  1114. case 18:
  1115. canvas->resetMatrix();
  1116. break;
  1117. case 19: {
  1118. SkRect r;
  1119. int op;
  1120. bool doAntiAlias;
  1121. fuzz->next(&r, &doAntiAlias);
  1122. fuzz->nextRange(&op, 0, 1);
  1123. r.sort();
  1124. canvas->clipRect(r, (SkClipOp)op, doAntiAlias);
  1125. break;
  1126. }
  1127. case 20: {
  1128. SkRRect rr;
  1129. int op;
  1130. bool doAntiAlias;
  1131. FuzzNiceRRect(fuzz, &rr);
  1132. fuzz->next(&doAntiAlias);
  1133. fuzz->nextRange(&op, 0, 1);
  1134. canvas->clipRRect(rr, (SkClipOp)op, doAntiAlias);
  1135. break;
  1136. }
  1137. case 21: {
  1138. SkPath path;
  1139. FuzzNicePath(fuzz, &path, 30);
  1140. int op;
  1141. bool doAntiAlias;
  1142. fuzz->next(&doAntiAlias);
  1143. fuzz->nextRange(&op, 0, 1);
  1144. canvas->clipPath(path, (SkClipOp)op, doAntiAlias);
  1145. break;
  1146. }
  1147. case 22: {
  1148. SkRegion region;
  1149. int op;
  1150. fuzz->next(&region);
  1151. fuzz->nextRange(&op, 0, 1);
  1152. canvas->clipRegion(region, (SkClipOp)op);
  1153. break;
  1154. }
  1155. case 23:
  1156. fuzz_paint(fuzz, &paint, depth - 1);
  1157. canvas->drawPaint(paint);
  1158. break;
  1159. case 24: {
  1160. fuzz_paint(fuzz, &paint, depth - 1);
  1161. SkCanvas::PointMode pointMode;
  1162. fuzz->nextRange(&pointMode,
  1163. SkCanvas::kPoints_PointMode, SkCanvas::kPolygon_PointMode);
  1164. size_t count;
  1165. constexpr int kMaxCount = 30;
  1166. fuzz->nextRange(&count, 0, kMaxCount);
  1167. SkPoint pts[kMaxCount];
  1168. fuzz->nextN(pts, count);
  1169. canvas->drawPoints(pointMode, count, pts, paint);
  1170. break;
  1171. }
  1172. case 25: {
  1173. fuzz_paint(fuzz, &paint, depth - 1);
  1174. SkRect r;
  1175. fuzz->next(&r);
  1176. if (!r.isFinite()) {
  1177. break;
  1178. }
  1179. canvas->drawRect(r, paint);
  1180. break;
  1181. }
  1182. case 26: {
  1183. fuzz_paint(fuzz, &paint, depth - 1);
  1184. SkRegion region;
  1185. fuzz->next(&region);
  1186. canvas->drawRegion(region, paint);
  1187. break;
  1188. }
  1189. case 27: {
  1190. fuzz_paint(fuzz, &paint, depth - 1);
  1191. SkRect r;
  1192. fuzz->next(&r);
  1193. if (!r.isFinite()) {
  1194. break;
  1195. }
  1196. canvas->drawOval(r, paint);
  1197. break;
  1198. }
  1199. case 28: break; // must have deleted this some time earlier
  1200. case 29: {
  1201. fuzz_paint(fuzz, &paint, depth - 1);
  1202. SkRRect rr;
  1203. FuzzNiceRRect(fuzz, &rr);
  1204. canvas->drawRRect(rr, paint);
  1205. break;
  1206. }
  1207. case 30: {
  1208. fuzz_paint(fuzz, &paint, depth - 1);
  1209. SkRRect orr, irr;
  1210. FuzzNiceRRect(fuzz, &orr);
  1211. FuzzNiceRRect(fuzz, &irr);
  1212. if (orr.getBounds().contains(irr.getBounds())) {
  1213. canvas->drawDRRect(orr, irr, paint);
  1214. }
  1215. break;
  1216. }
  1217. case 31: {
  1218. fuzz_paint(fuzz, &paint, depth - 1);
  1219. SkRect r;
  1220. SkScalar start, sweep;
  1221. bool useCenter;
  1222. fuzz->next(&r, &start, &sweep, &useCenter);
  1223. canvas->drawArc(r, start, sweep, useCenter, paint);
  1224. break;
  1225. }
  1226. case 32: {
  1227. fuzz_paint(fuzz, &paint, depth - 1);
  1228. SkPath path;
  1229. FuzzNicePath(fuzz, &path, 60);
  1230. canvas->drawPath(path, paint);
  1231. break;
  1232. }
  1233. case 33: {
  1234. sk_sp<SkImage> img = make_fuzz_image(fuzz);
  1235. SkScalar left, top;
  1236. bool usePaint;
  1237. fuzz->next(&left, &top, &usePaint);
  1238. if (usePaint) {
  1239. fuzz_paint(fuzz, &paint, depth - 1);
  1240. }
  1241. canvas->drawImage(img.get(), left, top, usePaint ? &paint : nullptr);
  1242. break;
  1243. }
  1244. case 34: {
  1245. auto img = make_fuzz_image(fuzz);
  1246. SkRect src, dst;
  1247. bool usePaint;
  1248. fuzz->next(&src, &dst, &usePaint);
  1249. if (usePaint) {
  1250. fuzz_paint(fuzz, &paint, depth - 1);
  1251. }
  1252. canvas->drawImageRect(img, src, dst, usePaint ? &paint : nullptr);
  1253. break;
  1254. }
  1255. case 35: {
  1256. auto img = make_fuzz_image(fuzz);
  1257. SkIRect src;
  1258. SkRect dst;
  1259. bool usePaint;
  1260. fuzz->next(&src, &dst, &usePaint);
  1261. if (usePaint) {
  1262. fuzz_paint(fuzz, &paint, depth - 1);
  1263. }
  1264. SkCanvas::SrcRectConstraint constraint =
  1265. make_fuzz_t<bool>(fuzz) ? SkCanvas::kStrict_SrcRectConstraint
  1266. : SkCanvas::kFast_SrcRectConstraint;
  1267. canvas->drawImageRect(img, src, dst, usePaint ? &paint : nullptr, constraint);
  1268. break;
  1269. }
  1270. case 36: {
  1271. bool usePaint;
  1272. auto img = make_fuzz_image(fuzz);
  1273. SkRect dst;
  1274. fuzz->next(&dst, &usePaint);
  1275. if (usePaint) {
  1276. fuzz_paint(fuzz, &paint, depth - 1);
  1277. }
  1278. canvas->drawImageRect(img, dst, usePaint ? &paint : nullptr);
  1279. break;
  1280. }
  1281. case 37: {
  1282. auto img = make_fuzz_image(fuzz);
  1283. SkIRect center;
  1284. SkRect dst;
  1285. bool usePaint;
  1286. fuzz->next(&usePaint);
  1287. if (usePaint) {
  1288. fuzz_paint(fuzz, &paint, depth - 1);
  1289. }
  1290. if (make_fuzz_t<bool>(fuzz)) {
  1291. fuzz->next(&center);
  1292. } else { // Make valid center, see SkLatticeIter::Valid().
  1293. fuzz->nextRange(&center.fLeft, 0, img->width() - 1);
  1294. fuzz->nextRange(&center.fTop, 0, img->height() - 1);
  1295. fuzz->nextRange(&center.fRight, center.fLeft + 1, img->width());
  1296. fuzz->nextRange(&center.fBottom, center.fTop + 1, img->height());
  1297. }
  1298. fuzz->next(&dst);
  1299. canvas->drawImageNine(img, center, dst, usePaint ? &paint : nullptr);
  1300. break;
  1301. }
  1302. case 38: {
  1303. SkBitmap bitmap = make_fuzz_bitmap(fuzz);
  1304. SkScalar left, top;
  1305. bool usePaint;
  1306. fuzz->next(&left, &top, &usePaint);
  1307. if (usePaint) {
  1308. fuzz_paint(fuzz, &paint, depth - 1);
  1309. }
  1310. canvas->drawBitmap(bitmap, left, top, usePaint ? &paint : nullptr);
  1311. break;
  1312. }
  1313. case 39: {
  1314. SkBitmap bitmap = make_fuzz_bitmap(fuzz);
  1315. SkRect src, dst;
  1316. bool usePaint;
  1317. fuzz->next(&src, &dst, &usePaint);
  1318. if (usePaint) {
  1319. fuzz_paint(fuzz, &paint, depth - 1);
  1320. }
  1321. SkCanvas::SrcRectConstraint constraint =
  1322. make_fuzz_t<bool>(fuzz) ? SkCanvas::kStrict_SrcRectConstraint
  1323. : SkCanvas::kFast_SrcRectConstraint;
  1324. canvas->drawBitmapRect(bitmap, src, dst, usePaint ? &paint : nullptr, constraint);
  1325. break;
  1326. }
  1327. case 40: {
  1328. SkBitmap img = make_fuzz_bitmap(fuzz);
  1329. SkIRect src;
  1330. SkRect dst;
  1331. bool usePaint;
  1332. fuzz->next(&src, &dst, &usePaint);
  1333. if (usePaint) {
  1334. fuzz_paint(fuzz, &paint, depth - 1);
  1335. }
  1336. SkCanvas::SrcRectConstraint constraint =
  1337. make_fuzz_t<bool>(fuzz) ? SkCanvas::kStrict_SrcRectConstraint
  1338. : SkCanvas::kFast_SrcRectConstraint;
  1339. canvas->drawBitmapRect(img, src, dst, usePaint ? &paint : nullptr, constraint);
  1340. break;
  1341. }
  1342. case 41: {
  1343. SkBitmap img = make_fuzz_bitmap(fuzz);
  1344. SkRect dst;
  1345. bool usePaint;
  1346. fuzz->next(&dst, &usePaint);
  1347. if (usePaint) {
  1348. fuzz_paint(fuzz, &paint, depth - 1);
  1349. }
  1350. SkCanvas::SrcRectConstraint constraint =
  1351. make_fuzz_t<bool>(fuzz) ? SkCanvas::kStrict_SrcRectConstraint
  1352. : SkCanvas::kFast_SrcRectConstraint;
  1353. canvas->drawBitmapRect(img, dst, usePaint ? &paint : nullptr, constraint);
  1354. break;
  1355. }
  1356. case 42: {
  1357. SkBitmap img = make_fuzz_bitmap(fuzz);
  1358. SkIRect center;
  1359. SkRect dst;
  1360. bool usePaint;
  1361. fuzz->next(&usePaint);
  1362. if (usePaint) {
  1363. fuzz_paint(fuzz, &paint, depth - 1);
  1364. }
  1365. if (make_fuzz_t<bool>(fuzz)) {
  1366. fuzz->next(&center);
  1367. } else { // Make valid center, see SkLatticeIter::Valid().
  1368. if (img.width() == 0 || img.height() == 0) {
  1369. // bitmap may not have had its pixels initialized.
  1370. break;
  1371. }
  1372. fuzz->nextRange(&center.fLeft, 0, img.width() - 1);
  1373. fuzz->nextRange(&center.fTop, 0, img.height() - 1);
  1374. fuzz->nextRange(&center.fRight, center.fLeft + 1, img.width());
  1375. fuzz->nextRange(&center.fBottom, center.fTop + 1, img.height());
  1376. }
  1377. fuzz->next(&dst);
  1378. canvas->drawBitmapNine(img, center, dst, usePaint ? &paint : nullptr);
  1379. break;
  1380. }
  1381. case 43: {
  1382. SkBitmap img = make_fuzz_bitmap(fuzz);
  1383. bool usePaint;
  1384. SkRect dst;
  1385. fuzz->next(&usePaint, &dst);
  1386. if (usePaint) {
  1387. fuzz_paint(fuzz, &paint, depth - 1);
  1388. }
  1389. constexpr int kMax = 6;
  1390. int xDivs[kMax], yDivs[kMax];
  1391. SkCanvas::Lattice lattice{xDivs, yDivs, nullptr, 0, 0, nullptr, nullptr};
  1392. fuzz->nextRange(&lattice.fXCount, 2, kMax);
  1393. fuzz->nextRange(&lattice.fYCount, 2, kMax);
  1394. fuzz->nextN(xDivs, lattice.fXCount);
  1395. fuzz->nextN(yDivs, lattice.fYCount);
  1396. canvas->drawBitmapLattice(img, lattice, dst, usePaint ? &paint : nullptr);
  1397. break;
  1398. }
  1399. case 44: {
  1400. auto img = make_fuzz_image(fuzz);
  1401. bool usePaint;
  1402. SkRect dst;
  1403. fuzz->next(&usePaint, &dst);
  1404. if (usePaint) {
  1405. fuzz_paint(fuzz, &paint, depth - 1);
  1406. }
  1407. constexpr int kMax = 6;
  1408. int xDivs[kMax], yDivs[kMax];
  1409. SkCanvas::Lattice lattice{xDivs, yDivs, nullptr, 0, 0, nullptr, nullptr};
  1410. fuzz->nextRange(&lattice.fXCount, 2, kMax);
  1411. fuzz->nextRange(&lattice.fYCount, 2, kMax);
  1412. fuzz->nextN(xDivs, lattice.fXCount);
  1413. fuzz->nextN(yDivs, lattice.fYCount);
  1414. canvas->drawImageLattice(img.get(), lattice, dst, usePaint ? &paint : nullptr);
  1415. break;
  1416. }
  1417. case 45: {
  1418. fuzz_paint(fuzz, &paint, depth - 1);
  1419. font = fuzz_font(fuzz);
  1420. SkTextEncoding encoding = fuzz_paint_text_encoding(fuzz);
  1421. SkScalar x, y;
  1422. fuzz->next(&x, &y);
  1423. SkTDArray<uint8_t> text = make_fuzz_text(fuzz, font, encoding);
  1424. canvas->drawSimpleText(text.begin(), SkToSizeT(text.count()), encoding, x, y,
  1425. font, paint);
  1426. break;
  1427. }
  1428. case 46: {
  1429. // was drawPosText
  1430. break;
  1431. }
  1432. case 47: {
  1433. // was drawPosTextH
  1434. break;
  1435. }
  1436. case 48: {
  1437. // was drawtextonpath
  1438. break;
  1439. }
  1440. case 49: {
  1441. // was drawtextonpath
  1442. break;
  1443. }
  1444. case 50: {
  1445. // was drawTextRSXform
  1446. break;
  1447. }
  1448. case 51: {
  1449. sk_sp<SkTextBlob> blob = make_fuzz_textblob(fuzz);
  1450. fuzz_paint(fuzz, &paint, depth - 1);
  1451. SkScalar x, y;
  1452. fuzz->next(&x, &y);
  1453. canvas->drawTextBlob(blob, x, y, paint);
  1454. break;
  1455. }
  1456. case 52: {
  1457. SkMatrix matrix;
  1458. bool usePaint, useMatrix;
  1459. fuzz->next(&usePaint, &useMatrix);
  1460. if (usePaint) {
  1461. fuzz_paint(fuzz, &paint, depth - 1);
  1462. }
  1463. if (useMatrix) {
  1464. FuzzNiceMatrix(fuzz, &matrix);
  1465. }
  1466. auto pic = make_fuzz_picture(fuzz, depth - 1);
  1467. canvas->drawPicture(pic, useMatrix ? &matrix : nullptr,
  1468. usePaint ? &paint : nullptr);
  1469. break;
  1470. }
  1471. case 53: {
  1472. fuzz_paint(fuzz, &paint, depth - 1);
  1473. SkVertices::VertexMode vertexMode;
  1474. SkBlendMode blendMode;
  1475. fuzz->nextRange(&vertexMode, 0, SkVertices::kTriangleFan_VertexMode);
  1476. fuzz->nextRange(&blendMode, 0, SkBlendMode::kLastMode);
  1477. constexpr int kMaxCount = 100;
  1478. int vertexCount;
  1479. SkPoint vertices[kMaxCount];
  1480. SkPoint texs[kMaxCount];
  1481. SkColor colors[kMaxCount];
  1482. fuzz->nextRange(&vertexCount, 3, kMaxCount);
  1483. fuzz->nextN(vertices, vertexCount);
  1484. bool useTexs, useColors;
  1485. fuzz->next(&useTexs, &useColors);
  1486. if (useTexs) {
  1487. fuzz->nextN(texs, vertexCount);
  1488. }
  1489. if (useColors) {
  1490. fuzz->nextN(colors, vertexCount);
  1491. }
  1492. int indexCount = 0;
  1493. uint16_t indices[kMaxCount * 2];
  1494. if (make_fuzz_t<bool>(fuzz)) {
  1495. fuzz->nextRange(&indexCount, vertexCount, vertexCount + kMaxCount);
  1496. for (int i = 0; i < indexCount; ++i) {
  1497. fuzz->nextRange(&indices[i], 0, vertexCount - 1);
  1498. }
  1499. }
  1500. canvas->drawVertices(SkVertices::MakeCopy(vertexMode, vertexCount, vertices,
  1501. useTexs ? texs : nullptr,
  1502. useColors ? colors : nullptr,
  1503. indexCount, indices),
  1504. blendMode, paint);
  1505. break;
  1506. }
  1507. default:
  1508. SkASSERT(false);
  1509. break;
  1510. }
  1511. }
  1512. }
  1513. static sk_sp<SkPicture> make_fuzz_picture(Fuzz* fuzz, int depth) {
  1514. SkScalar w, h;
  1515. fuzz->next(&w, &h);
  1516. SkPictureRecorder pictureRecorder;
  1517. fuzz_canvas(fuzz, pictureRecorder.beginRecording(w, h), depth - 1);
  1518. return pictureRecorder.finishRecordingAsPicture();
  1519. }
  1520. DEF_FUZZ(NullCanvas, fuzz) {
  1521. fuzz_canvas(fuzz, SkMakeNullCanvas().get());
  1522. }
  1523. constexpr SkISize kCanvasSize = {128, 160};
  1524. DEF_FUZZ(RasterN32Canvas, fuzz) {
  1525. auto surface = SkSurface::MakeRasterN32Premul(kCanvasSize.width(), kCanvasSize.height());
  1526. if (!surface || !surface->getCanvas()) { fuzz->signalBug(); }
  1527. fuzz_canvas(fuzz, surface->getCanvas());
  1528. }
  1529. DEF_FUZZ(RasterN32CanvasViaSerialization, fuzz) {
  1530. SkPictureRecorder recorder;
  1531. fuzz_canvas(fuzz, recorder.beginRecording(SkIntToScalar(kCanvasSize.width()),
  1532. SkIntToScalar(kCanvasSize.height())));
  1533. sk_sp<SkPicture> pic(recorder.finishRecordingAsPicture());
  1534. if (!pic) { fuzz->signalBug(); }
  1535. sk_sp<SkData> data = pic->serialize();
  1536. if (!data) { fuzz->signalBug(); }
  1537. SkReadBuffer rb(data->data(), data->size());
  1538. auto deserialized = SkPicturePriv::MakeFromBuffer(rb);
  1539. if (!deserialized) { fuzz->signalBug(); }
  1540. auto surface = SkSurface::MakeRasterN32Premul(kCanvasSize.width(), kCanvasSize.height());
  1541. SkASSERT(surface && surface->getCanvas());
  1542. surface->getCanvas()->drawPicture(deserialized);
  1543. }
  1544. DEF_FUZZ(ImageFilter, fuzz) {
  1545. auto fil = make_fuzz_imageFilter(fuzz, 20);
  1546. SkPaint paint;
  1547. paint.setImageFilter(fil);
  1548. SkBitmap bitmap;
  1549. SkCanvas canvas(bitmap);
  1550. canvas.saveLayer(SkRect::MakeWH(500, 500), &paint);
  1551. }
  1552. //SkRandom _rand;
  1553. #define SK_ADD_RANDOM_BIT_FLIPS
  1554. DEF_FUZZ(SerializedImageFilter, fuzz) {
  1555. SkBitmap bitmap;
  1556. if (!bitmap.tryAllocN32Pixels(256, 256)) {
  1557. SkDEBUGF("Could not allocate 256x256 bitmap in SerializedImageFilter");
  1558. return;
  1559. }
  1560. auto filter = make_fuzz_imageFilter(fuzz, 20);
  1561. if (!filter) {
  1562. return;
  1563. }
  1564. auto data = filter->serialize();
  1565. const unsigned char* ptr = static_cast<const unsigned char*>(data->data());
  1566. size_t len = data->size();
  1567. #ifdef SK_ADD_RANDOM_BIT_FLIPS
  1568. unsigned char* p = const_cast<unsigned char*>(ptr);
  1569. for (size_t i = 0; i < len; ++i, ++p) {
  1570. uint8_t j;
  1571. fuzz->nextRange(&j, 1, 250);
  1572. if (j == 1) { // 0.4% of the time, flip a bit or byte
  1573. uint8_t k;
  1574. fuzz->nextRange(&k, 1, 10);
  1575. if (k == 1) { // Then 10% of the time, change a whole byte
  1576. uint8_t s;
  1577. fuzz->nextRange(&s, 0, 2);
  1578. switch(s) {
  1579. case 0:
  1580. *p ^= 0xFF; // Flip entire byte
  1581. break;
  1582. case 1:
  1583. *p = 0xFF; // Set all bits to 1
  1584. break;
  1585. case 2:
  1586. *p = 0x00; // Set all bits to 0
  1587. break;
  1588. }
  1589. } else {
  1590. uint8_t s;
  1591. fuzz->nextRange(&s, 0, 7);
  1592. *p ^= (1 << 7);
  1593. }
  1594. }
  1595. }
  1596. #endif // SK_ADD_RANDOM_BIT_FLIPS
  1597. auto deserializedFil = SkImageFilter::Deserialize(ptr, len);
  1598. // uncomment below to write out a serialized image filter (to make corpus
  1599. // for -t filter_fuzz)
  1600. // SkString s("./serialized_filters/sf");
  1601. // s.appendU32(_rand.nextU());
  1602. // auto file = sk_fopen(s.c_str(), SkFILE_Flags::kWrite_SkFILE_Flag);
  1603. // sk_fwrite(data->bytes(), data->size(), file);
  1604. // sk_fclose(file);
  1605. SkPaint paint;
  1606. paint.setImageFilter(deserializedFil);
  1607. SkCanvas canvas(bitmap);
  1608. canvas.saveLayer(SkRect::MakeWH(256, 256), &paint);
  1609. canvas.restore();
  1610. }
  1611. #if SK_SUPPORT_GPU
  1612. static void dump_GPU_info(GrContext* context) {
  1613. const GrGLInterface* gl = static_cast<GrGLGpu*>(context->priv().getGpu())
  1614. ->glInterface();
  1615. const GrGLubyte* output;
  1616. GR_GL_CALL_RET(gl, output, GetString(GR_GL_RENDERER));
  1617. SkDebugf("GL_RENDERER %s\n", (const char*) output);
  1618. GR_GL_CALL_RET(gl, output, GetString(GR_GL_VENDOR));
  1619. SkDebugf("GL_VENDOR %s\n", (const char*) output);
  1620. GR_GL_CALL_RET(gl, output, GetString(GR_GL_VERSION));
  1621. SkDebugf("GL_VERSION %s\n", (const char*) output);
  1622. }
  1623. static void fuzz_ganesh(Fuzz* fuzz, GrContext* context) {
  1624. SkASSERT(context);
  1625. auto surface = SkSurface::MakeRenderTarget(
  1626. context,
  1627. SkBudgeted::kNo,
  1628. SkImageInfo::Make(kCanvasSize.width(), kCanvasSize.height(), kRGBA_8888_SkColorType, kPremul_SkAlphaType));
  1629. SkASSERT(surface && surface->getCanvas());
  1630. fuzz_canvas(fuzz, surface->getCanvas());
  1631. }
  1632. DEF_FUZZ(NativeGLCanvas, fuzz) {
  1633. sk_gpu_test::GrContextFactory f;
  1634. GrContext* context = f.get(sk_gpu_test::GrContextFactory::kGL_ContextType);
  1635. if (!context) {
  1636. context = f.get(sk_gpu_test::GrContextFactory::kGLES_ContextType);
  1637. }
  1638. if (FLAGS_gpuInfo) {
  1639. dump_GPU_info(context);
  1640. }
  1641. fuzz_ganesh(fuzz, context);
  1642. }
  1643. DEF_FUZZ(MockGPUCanvas, fuzz) {
  1644. sk_gpu_test::GrContextFactory f;
  1645. fuzz_ganesh(fuzz, f.get(sk_gpu_test::GrContextFactory::kMock_ContextType));
  1646. }
  1647. #endif
  1648. DEF_FUZZ(PDFCanvas, fuzz) {
  1649. SkNullWStream stream;
  1650. auto doc = SkPDF::MakeDocument(&stream);
  1651. fuzz_canvas(fuzz, doc->beginPage(SkIntToScalar(kCanvasSize.width()),
  1652. SkIntToScalar(kCanvasSize.height())));
  1653. }
  1654. // not a "real" thing to fuzz, used to debug errors found while fuzzing.
  1655. DEF_FUZZ(_DumpCanvas, fuzz) {
  1656. DebugCanvas debugCanvas(kCanvasSize.width(), kCanvasSize.height());
  1657. fuzz_canvas(fuzz, &debugCanvas);
  1658. std::unique_ptr<SkCanvas> nullCanvas = SkMakeNullCanvas();
  1659. UrlDataManager dataManager(SkString("data"));
  1660. SkDynamicMemoryWStream stream;
  1661. SkJSONWriter writer(&stream, SkJSONWriter::Mode::kPretty);
  1662. writer.beginObject(); // root
  1663. debugCanvas.toJSON(writer, dataManager, debugCanvas.getSize(), nullCanvas.get());
  1664. writer.endObject(); // root
  1665. writer.flush();
  1666. sk_sp<SkData> json = stream.detachAsData();
  1667. fwrite(json->data(), json->size(), 1, stdout);
  1668. }