From 1569f51caeef8534f60ec9c673196179c99c240e Mon Sep 17 00:00:00 2001 From: Vaivaswat Date: Sun, 16 Feb 2025 01:10:31 +0530 Subject: [PATCH 01/10] tried an approch for text case in pixelmatch --- package-lock.json | 20 +++ package.json | 1 + .../Drawing closed curve loops/000.png | Bin 857 -> 1325 bytes .../2D mode/Drawing closed curves/000.png | Bin 857 -> 1334 bytes .../Drawing simple closed curves/000.png | Bin 701 -> 1204 bytes .../2D mode/Drawing triangle fans/000.png | Bin 743 -> 917 bytes .../Drawing with cubic beziers/000.png | Bin 641 -> 963 bytes .../000.png | Bin 519 -> 868 bytes .../000.png | Bin 825 -> 1385 bytes .../2D mode/Drawing with triangles/000.png | Bin 693 -> 1057 bytes .../WebGL mode/3D cubic coordinates/000.png | Bin 613 -> 598 bytes .../Drawing closed curve loops/000.png | Bin 680 -> 654 bytes .../Drawing with cubic beziers/000.png | Bin 517 -> 526 bytes test/unit/visual/visualTest.js | 153 ++++++++++++------ 14 files changed, 128 insertions(+), 46 deletions(-) diff --git a/package-lock.json b/package-lock.json index edccbe8993..beed79d351 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ "libtess": "^1.2.2", "omggif": "^1.0.10", "pako": "^2.1.0", + "pixelmatch": "^6.0.0", "zod": "^3.23.8" }, "devDependencies": { @@ -8619,6 +8620,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pixelmatch": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-6.0.0.tgz", + "integrity": "sha512-FYpL4XiIWakTnIqLqvt3uN4L9B3TsuHIvhLILzTiJZMJUsGvmKNeL4H3b6I99LRyerK9W4IuOXw+N28AtRgK2g==", + "dependencies": { + "pngjs": "^7.0.0" + }, + "bin": { + "pixelmatch": "bin/pixelmatch" + } + }, "node_modules/pkg-dir": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", @@ -8642,6 +8654,14 @@ "semver-compare": "^1.0.0" } }, + "node_modules/pngjs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz", + "integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==", + "engines": { + "node": ">=14.19.0" + } + }, "node_modules/postcss": { "version": "8.5.1", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz", diff --git a/package.json b/package.json index e34a8ef5c7..daeebc4136 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "libtess": "^1.2.2", "omggif": "^1.0.10", "pako": "^2.1.0", + "pixelmatch": "^6.0.0", "zod": "^3.23.8" }, "devDependencies": { diff --git a/test/unit/visual/screenshots/Shape drawing/2D mode/Drawing closed curve loops/000.png b/test/unit/visual/screenshots/Shape drawing/2D mode/Drawing closed curve loops/000.png index 80536c3fec45666ca76d09905e54705c955df869..4daa4ef5bdbd099b4d777678428ac48d6256b88f 100644 GIT binary patch delta 1294 zcmV+p1@ZdX2CWK^Fn2?X}Ca<3tPxC#mG=&O(=?qW|+RLH6huJLK!ZYFiiP(o|>rmR@TGF*D0fCE1 zTU#3j2L}-z9*)q^P$ifl9g>SkM@I*HT3%jWh>VPsu2l<tqrMJF&dHjO*)b6c-nB znX$02fRT|AoPVF6!@fFpH@{QY&dv_rzI}_VtSmf#{`}9m z+S*zc&CJY9`1tsUvGv|NTttS4hq1c4${HehI3y(GPJhtk8TfWol{)-rnBG z&d$cmmoF7chKmSAVt#%eK|w+I@Zkdr3kz>GqN1V#dwYAVFx({@8yj$Qb3;l>3IYQI z6-I`O$ou#2F*`epuC6Y)xVYTf80kqxMMZ%Oefsq2y#~(B&B5Q_A4y3`2nYyJ2pKLS zOG`^E$$u#-R#sMMY;1(CuI^t3kWsH*y+T1j0heJjGc)k@^+jG@onwp|uxQS3idV70W`J^17hWFyd3yhAAvc5q?rAS&@8mM6K=GaYL z+(an+l<*!N9&A)0<2N@qS@j`uiV#mvPgWJh%yZmC$Ww`liK6m=m*o2TI-ASriP2vn z!hcPK!0qkr@%r^^A^3vN(%wUnr{^m~xQX=j_2K*X?`*+Rw$KD&W@d)CxHxWA+(f8> z(K!G4^Ji{wu?N@I)?jC6$4WiTc09sOy1K&I*_qupF)g9N3dxbXtoZTc2QDry*uNg=Cw6TW z!%|X2#3)qO9TgE}c~&g0Dk5S%r>uLbh$zdmVsZZi06%h1WeLe600000Ne4wvM6N<$ Ef+x3hC;$Ke delta 822 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 diff --git a/test/unit/visual/screenshots/Shape drawing/2D mode/Drawing triangle fans/000.png b/test/unit/visual/screenshots/Shape drawing/2D mode/Drawing triangle fans/000.png index 1802b735685f7397b5e12a6a618dbdd0379d6b39..5cf80608560b58c480dc722110a99a4c0c53176c 100644 GIT binary patch delta 882 zcmV-&1C9LW1(gSoFnmAu3vw6fNB(1!4VwP-v;EvY-en zv_(*~sZ3l%pBpJ?kzz>{^tGyGP_%TB8Wg!{8AY{-5}^X|Wd?jvkcxYcWpZYt*K=m> zJoC)VnWH8Y3Z+m4qLDxfj77;vfe`}9h-4&B5s;~sr@$&UD}NbL9J)LyN=EV&SjA@Z z%E;Z_9nR0s*}1m1Hq_VGD|YlNMWH|*A0KgXae?dWYXBK`bsVVq|0lo12@6$KyGH5EK3V{a9UH#pL9qFfgisP)*qFb_@*-fk33CrlyA3 z+1=gEVx+sfn;n08diuYYz^t#YV`F1ORn4dZa(sNuseh76rQmQlILah}Kmbms6Sudw z=;`U<-*$F((9qBTpU=m@Nr*ka-w%yO!>QQO(V@6rQ~_C8S>b|ydwb(t*J`y`SXf|3 zo12^YIbF<@g0%1Q@{)m0O-=DL)mB+q8KTiBMn^|~2S{IEAEyt2A)(YcI5^<;IzK-T ztJR9e#(zd$i^XC%JUoQU<>L0-+1bguB-G7FcWZ0w=Yh~+H#|Iyhlhu(m*3yt!(y=@ z91e5NKR-Y7dUbU*sHR$5TXA%Bgu1%AEIpl0hqbje#fPTi)FNjn-E~`sU^a zA0HpQURqiTyA=7M z1_uXKjVN?L27|%h8&N0^iehL?Cv;Ja@tI({y1ICLpPQS5$z;lTv7+gh21L3oQpYQ( zi)&RHO!}%za}`~6UtV6auDVrKReaT@`Kw^By1Dx1pZ)Ve@gX2UQPqJc;Qhi(NFc&O zDaepyL{K1wnURbL3#A}Kk`Y0H6lO*;A}o}G3`s@=1yY!qe^Bs{PlN_1E&u=k07*qo IM6N<$f(an48~^|S delta 707 zcmV;!0zCbd2j>NlFn#&r!PiDa&oNqvAHU8I-RUxxPSM0J#Qnkd{G@_wOU!j z3x$F?9*@?BR;y)pyPbVaAZ;*Jkb1ptjoogyPk`xkYG04XV+*t2@6BejF}K^zEEbC_ z&d#()4P-DFm~OXgjfK%r0ZW4L{bVvRxYp~n8jK1EA?S4&PgPuycDrpMu@}#@V1hv; z1Y-ckQWXi}LVrnx(lpH!Lhm*OfgrKZ=d(E+4mMO^JQl(WFptOMTWBRoVwGapVISad zNAiahfMAePsq{1+1~!{bYbZm=^`Hzt76IIc!=YI&m)@!bfuKrB55v1mWEczu0EG*m zLm>b{0auyPXcUzA!5}csT?BgNUKxV&IiR6PwOaL3#eW+F`Ej{ip7H+9X!$wSdAIi? zAn4xxe&2@7tA+4kH|O(rds!gL<+69edn-Z^&Cm)d!QLS7B6`SdHv3jiS*?)Fh%>NO)WvIb@^D(hynQ z8jXgjRDUX;1A!;dOWczBZY*IZ=N!fnMPuFyQiNe6=PiyLzYUFY4%2`L4lNn~gmDwu z9Tcew!cYrB6@*o+SS*@Or}Lb-+&@;>hy1|`sZwt5QVA`2D3TwGclkHBR;!u&{cgvQ zkV*Gd16Bude*{3BpM2-2EW=msAX$vi*b_lCygaCRMpQ)8n;K_DMKrvqc}7%3)0-M+ pMMX5csChDo;{a@cRG&002ovPDHLkV1gj$L#6-# diff --git a/test/unit/visual/screenshots/Shape drawing/2D mode/Drawing with cubic beziers/000.png b/test/unit/visual/screenshots/Shape drawing/2D mode/Drawing with cubic beziers/000.png index 4ed36210fca1966e11b4073c2992f907514a75c5..765d6854eeb9bf4b1bc3f9a9c9202f7ce59a4a82 100644 GIT binary patch delta 929 zcmV;S177@r1;YoBFnt+r`e5h=@-WZ4B5azU+8(ymsr3&{oLN+glLcb1X2=T|Ei-gm!q&d#y-eb4Xq z{C>~#e4g*~d(Lx?=J4?F6aT={s30k(qN+%W2?A9SRS}so@PGf6*7Nf-a&vQK%BOU* zT#9UOZ{zgz6gHbpx<{ETaDjxwVJt5%V|{&HrZA+NB41is!rR*$ zMn*>dZjigXJG8d8A{Y!JFE1};U<4~dk*}<*fXb}DzyG%&@9*zOOG{G>R20bL<0DKa z6a0QZii?Zc97bcz+1VMcuCDO#@Bo?yXvi!pD??394S(wE>rq--DjS$65Q=7ZcNhEn z`>ecCv-^if9NGfhoRY)mOHFaK64 znt!kfp5Fe{p7nZtLKsCr;!)7-MZ@Ls@iETN&vAWy4Xsv-%*;$S;zXlS&>zj5oE-My zR#H;J+AQ5q`KyncQGc(TMm<`~V(00000NkvXXu0mjf D+2G5; delta 604 zcmV-i0;B!I2Z05UFnyfw z0P#%4ponLJP*5Z&q7;Gum0G9MiSqfpQY_uLWhnxX*=$DR@qgIOQx&|hL8j9wO(qkC zEx2*X0>PsSg#txUAg=k`01$;&XbjL3~dy5s1&}B?9p| zy+j};y-|JvdgZQe7707%(r^DgkRj0QC`Kk(v01WdO?07uJpT%O4 z?)N+8aye?XT7U0%y&pVSgDe&cTCdm7jaMoa>i7HcJ-)-X+b!*OyZHNHFrZGSL$}*a z16*=$(R9u9{w5Y%z4kTnR>$@G=SL-rq^29Py~kpSfw>g@M>mMUfu z(yrI*Q8t@(qR!hO*chr zs+k(dYk7t`0D^I$N~Kc#{{Xjfs)Kw5!u(aM)t=&%%jHk$hyDV?XajieyU(wIn4O!6 z0QbpcGF6_Ualrry!=MSnu!$Eq&P&{{gK*D@bX@?EMofEsP((YzQvX2_X~eYG2Sv0a qEcG80kw#2=eNaR@!czZ#Mv)J+tcyS#OCm4;0000lNui{)-N`Pd6#IHkarMo4``&lnov-)Q>D}6S zpL2fC|2fajc?#n3cn1GLE6_lGLB;9mX*SEo#s+t`yjDa5;eYD)%L6n;e%ayN=`=-t za?$qoHrInn4~Rq}sH&=h-|y#|mXv-8;_mJaU0q#VgGvrKJv~K3LjxuzCb(uLgVfg6 z!sGF94JtXn=kwwE`WjBBlWSHoNKH)*=H}+O29+GJva*7clM_kvN(NCwk$61L)Y#nI z7P=8lfhvVa8Ehq1c4ilwC`u|aNcZ_(S^i~aq5WkA#l zt&fin=yWaJP@95~j(9jUt+uP-XsDGsht=ww0vV&u5Ypd8GcDo(j z-QBR+Y+{3qjg6tczMgIRY)$eWQ8TpMZZ~Mt4-XHE4YIhni2M6{OioUU4YIYhg`=Y* zkTODtRxlVuAP~U9!h+Z!XJ=<{xm;LZUl$vM4vixtBiPy55gX+4@)8b*1G~GsVuPHY zpR>C=?SB)YH+v`)!rIyzmY0{s2Jw2mxVpN+?Ch-AApQOQuvjc&A5q@l-%(mx3i>ZG znM~p;GCw~LD%A1HwUQ5w4-XIM>+8ek=O-)CG&eV+yu6%SIFmEr;NSp*gM--H+hc_~ z*>x>Cc~TCiXEK>YB9Q=rk>pe@Z)s^^V2zE9-+#TRsOX;=D4b}6Q@=jP@H zu~>}R?CI&j`1m+iiLbTE0?7tQ02J4x*z4;nQmNE;r|(}qolYZ@$w05y!(cG5@@P|2 z6FS=3+J4;Ff15WaAiOZh#qSzOF1#worlyD-@8#lMO_5x9RgTR+wvirB0jxLW00000 LNkvXXu0mjfT0EyC delta 481 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 delta 478 zcmV<40U`d51cd~UF@L{FL_t(&L+zNct%NWPhI0!r0VNYqQNjXDLB$fl5>!mV0#H&h z0VNZ#08c-XpWt*wV&c2#E=VVVbaDLow;jV{nxP?%1Fx3id|Q3$;Mzc~*dF+g92iwtX!SSWl8fO@GtG-bi|(Hi+x#^?M+$ zrJzf0(qqh;4sSIM^_xjml=(oB~E!Z2&qDK zQ`hz3UsYBAevadK+&4|5a1Rg+o)SQ85JbK#OO>Xn8iqkD$bbRVwr$pd*dXwnVD{bY z8y{exAk?w-YJYGGgwiSu!%Ir($V2KxQDgRzW@qV;zKQW?7aa&Cs4rE_5_b&4_>y3=U1S+4CW(0|l6MU5&b#7zjCxCV=w> z%9tpWWtlQ*&Eg<*aMBzW1i@vLd6jxJ+5iThpmau>w^x9i(}{*kn$^xj=JT*gvzbmh zz8yrzDb9a92q$WiYrG { + const region = 3; // Check 3x3 area + let transitions = 0; + let nonEmpty = 0; + + for (let dy = -region; dy <= region; dy++) { + for (let dx = -region; dx <= region; dx++) { + const px = x + dx; + const py = y + dy; + if (px < 0 || px >= width || py < 0 || py >= width) continue; + + const idx = (py * width + px) * 4; + // Check if pixel is non-transparent and has significant contrast + if (data.data[idx + 3] > 20) { + nonEmpty++; + // Check for contrast with neighboring pixels + if (px > 0) { + const prevIdx = (py * width + (px - 1)) * 4; + if (Math.abs(data.data[idx] - data.data[prevIdx]) > 30) { + transitions++; + } + } + } + } + } + + // Text typically has moderate density and high number of transitions + return nonEmpty > 4 && nonEmpty < 20 && transitions > 3; + }; + + // Custom comparison function that's more lenient with text + let diffCount = 0; + const shiftThreshold = 2; // Maximum pixels of shift allowed for text + + for (let y = 0; y < actual.height; y++) { + for (let x = 0; x < actual.width; x++) { + const idx = (y * actual.width + x) * 4; + + // Check if pixels match exactly + const exactMatch = [0, 1, 2, 3].every(i => + Math.abs(actualData.data[idx + i] - expectedData.data[idx + i]) < 0.4 * 255 + ); + + if (exactMatch) { + // Pixels match, copy expected pixel to diff + [0, 1, 2, 3].forEach(i => diffData.data[idx + i] = expectedData.data[idx + i]); + continue; + } + + // If pixels don't match, check if it might be shifted text + if (isLikelyText(expectedData, x, y, actual.width)) { + let foundMatch = false; + + // Look for matching pixel within shift threshold + searchLoop: + for (let dy = -shiftThreshold; dy <= shiftThreshold; dy++) { + for (let dx = -shiftThreshold; dx <= shiftThreshold; dx++) { + const sx = x + dx; + const sy = y + dy; + + if (sx < 0 || sx >= actual.width || sy < 0 || sy >= actual.height) continue; + + const shiftIdx = (sy * actual.width + sx) * 4; + const pixelMatch = [0, 1, 2, 3].every(i => + Math.abs(actualData.data[idx + i] - expectedData.data[shiftIdx + i]) < 0.4 * 255 + ); + + if (pixelMatch) { + foundMatch = true; + break searchLoop; + } + } + } + + if (foundMatch) { + // Mark as acceptable text shift (yellow in diff) + diffData.data[idx] = 255; // R + diffData.data[idx + 1] = 255; // G + diffData.data[idx + 2] = 0; // B + diffData.data[idx + 3] = 255; // A + continue; + } + } + + // If we get here, it's a real difference + diffCount++; + // Mark as difference (red in diff) + diffData.data[idx] = 255; // R + diffData.data[idx + 1] = 0; // G + diffData.data[idx + 2] = 0; // B + diffData.data[idx + 3] = 255; // A + } } - - const expectedWithBg = p5.createGraphics(expected.width, expected.height); - expectedWithBg.pixelDensity(1); - expectedWithBg.background(BG); - expectedWithBg.image(expected, 0, 0); - + + // Create diff image const cnv = p5.createGraphics(actual.width, actual.height); - cnv.pixelDensity(1); - cnv.background(BG); - cnv.image(actual, 0, 0); - cnv.blendMode(DIFFERENCE); - cnv.image(expectedWithBg, 0, 0); - for (let i = 0; i < shiftThreshold; i++) { - cnv.filter(ERODE, false); - } + cnv.drawingContext.putImageData(diffData, 0, 0); const diff = cnv.get(); cnv.remove(); - diff.loadPixels(); - expectedWithBg.remove(); - - let ok = true; - for (let i = 0; i < diff.pixels.length; i += 4) { - let diffSum = 0; - for (let off = 0; off < 3; off++) { - diffSum += diff.pixels[i+off] - } - diffSum /= 3; - if (diffSum > COLOR_THRESHOLD) { - ok = false; - break; - } - } - - return { ok, diff }; + + return { ok: diffCount === 0, diff }; } /** From 8e5025a25904c856082ec01e48944bafd76d733c Mon Sep 17 00:00:00 2001 From: Vaivaswat Date: Tue, 18 Feb 2025 00:02:32 +0530 Subject: [PATCH 02/10] regenrated test failing screenshots --- .../Shape Modes/Negative dimensions/arc/000.png | Bin 517 -> 0 bytes .../Negative dimensions/arc/metadata.json | 3 --- .../Negative dimensions/ellipse/000.png | Bin 557 -> 0 bytes .../Negative dimensions/ellipse/metadata.json | 3 --- .../Shape Modes/Shape arc/Mode CENTER/000.png | Bin 1195 -> 0 bytes .../Shape arc/Mode CENTER/metadata.json | 3 --- .../Shape Modes/Shape arc/Mode CORNER/000.png | Bin 1195 -> 0 bytes .../Shape arc/Mode CORNER/metadata.json | 3 --- .../Shape Modes/Shape arc/Mode CORNERS/000.png | Bin 1195 -> 0 bytes .../Shape arc/Mode CORNERS/metadata.json | 3 --- .../Shape Modes/Shape arc/Mode RADIUS/000.png | Bin 1195 -> 0 bytes .../Shape arc/Mode RADIUS/metadata.json | 3 --- .../2D mode/Drawing quad strips/000.png | Bin 479 -> 626 bytes .../2D mode/Drawing triangle strips/000.png | Bin 639 -> 910 bytes .../2D mode/Drawing with contours/000.png | Bin 839 -> 945 bytes 15 files changed, 18 deletions(-) delete mode 100644 test/unit/visual/screenshots/Shape Modes/Negative dimensions/arc/000.png delete mode 100644 test/unit/visual/screenshots/Shape Modes/Negative dimensions/arc/metadata.json delete mode 100644 test/unit/visual/screenshots/Shape Modes/Negative dimensions/ellipse/000.png delete mode 100644 test/unit/visual/screenshots/Shape Modes/Negative dimensions/ellipse/metadata.json delete mode 100644 test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CENTER/000.png delete mode 100644 test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CENTER/metadata.json delete mode 100644 test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CORNER/000.png delete mode 100644 test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CORNER/metadata.json delete mode 100644 test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CORNERS/000.png delete mode 100644 test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CORNERS/metadata.json delete mode 100644 test/unit/visual/screenshots/Shape Modes/Shape arc/Mode RADIUS/000.png delete mode 100644 test/unit/visual/screenshots/Shape Modes/Shape arc/Mode RADIUS/metadata.json diff --git a/test/unit/visual/screenshots/Shape Modes/Negative dimensions/arc/000.png b/test/unit/visual/screenshots/Shape Modes/Negative dimensions/arc/000.png deleted file mode 100644 index b0732e0093e770d0d538f527d5c134e6a58d17c3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 517 zcmV+g0{Z=lP)Px$zez+vRA@u(*0FC+Q5eVZ&$-GQ5{9O#lY|I~i9{?lkp2lsM-q#Hgh68P7l?$R z9jwGIMuQG&=w1mXLdD2N(%vI)UPFWSUMKE(-@G|zexBz%zwh_t<_2SO!kFYxf{dEU zVx$=9h(LK-9f3_ATZ|;5>!`69=?HA{*kU9ZT}O?@NJn6k#}*^W=sIdFMmhqUJhm7~ zM%PheG4h|l-o{BB#sNITwUpVzFtQjz?{bX2J;Dim#We9479Zf|$Oj44{utvV@e0FuV0jiFL;AjSZMnWhaIHto{e=SNF$=m z1;t2a;EmT6BaMhM7Zf9zfj3@Pj5H$3Tu_W;2Htqx*ckZPx$=Sf6CRA@u();()fK^VpH-@UupAYv0%Oso`ad?{@tpaegFmG~935K>xL*(uls zG_C2ZEUYX{M4r;RM$uAS*yytur8@;#wL=wd-x zuKuj5l{M*iCQh`qx*&~%_l#^5o0~xLL=Eo^#d4a2uW~L|}5Izs`u=jc|+m+BR zgqywVcl1A|KJ>2NX^rNQweH&D(4ep1t^3a~e4TQbGZf9Px(Wl2OqRCr$PUC(P1K@@&NN$8hq8IJI zP;ybRXGx)+)uVV+6j~DW;z3$%p@uYvcxa&zDJ!$x#Z72;-elj<)qa7{(9Yz0-}~mx z?wdC|RdmQ+>X7jzF5%-ubg8ee?_4&UJ)g;Bsv8>{x3#kd1_sJIJ3Hg8R_o)|*48H? zdQU`aLXH&2H4#2NIy(9!pUV*EK=Xt9{bS&Cn zVPS!0W@ehTT1|I+Yf0KEZX97foK`*0(?4$o?W9pQh6C1Izy zrXk&CtLJ%Vi0B~^T_d8`!5_oVPnA-iEy=N(OX6A)j#}q=o+eI8si!Qfg&HNrwIUpN z`az)Zn}EaBK<#Ia6&AsbBU~V&??DXT3}RTvSNPg1hIPE^7@iMeSWj#}EX8$-8%Ox^ z(9qD!+1c6L^z?M6&1*_2pZs34bh%vCv-GbI?d&Fw%Oxyi|G|F^2p_x#ZY_Yq z`}kKpO=IdPj%!lbS(;`b>-y*t57I-VhrHlLdMK5aT1{F!anjuigww50a_gWl(nC}a{V{;*VGs(a z9wwhxksc-mx>n7s3T*6HI(%%e()2~r73!!i_|E0e-6i&ZJ$t;Az$^4i8 z-du&n*Or*B5yv$VcDA;JHLbrMzys4APoO7yP}?-5v8EMz0Bc%U)AA2Jz?v50`inI! ztZD5YiPP1C+E$k(#&Ar16A(_lLu&u0Jt002ov JPDHLkV1lNTIFtYY diff --git a/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CENTER/metadata.json b/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CENTER/metadata.json deleted file mode 100644 index 2d4bfe30da..0000000000 --- a/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CENTER/metadata.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "numScreenshots": 1 -} \ No newline at end of file diff --git a/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CORNER/000.png b/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CORNER/000.png deleted file mode 100644 index d624061419aaaacd85af49537aadf960584abb21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1195 zcmV;c1XTNpP)Px(Wl2OqRCr$PUC(P1K@@&NN$8hq8IJI zP;ybRXGx)+)uVV+6j~DW;z3$%p@uYvcxa&zDJ!$x#Z72;-elj<)qa7{(9Yz0-}~mx z?wdC|RdmQ+>X7jzF5%-ubg8ee?_4&UJ)g;Bsv8>{x3#kd1_sJIJ3Hg8R_o)|*48H? zdQU`aLXH&2H4#2NIy(9!pUV*EK=Xt9{bS&Cn zVPS!0W@ehTT1|I+Yf0KEZX97foK`*0(?4$o?W9pQh6C1Izy zrXk&CtLJ%Vi0B~^T_d8`!5_oVPnA-iEy=N(OX6A)j#}q=o+eI8si!Qfg&HNrwIUpN z`az)Zn}EaBK<#Ia6&AsbBU~V&??DXT3}RTvSNPg1hIPE^7@iMeSWj#}EX8$-8%Ox^ z(9qD!+1c6L^z?M6&1*_2pZs34bh%vCv-GbI?d&Fw%Oxyi|G|F^2p_x#ZY_Yq z`}kKpO=IdPj%!lbS(;`b>-y*t57I-VhrHlLdMK5aT1{F!anjuigww50a_gWl(nC}a{V{;*VGs(a z9wwhxksc-mx>n7s3T*6HI(%%e()2~r73!!i_|E0e-6i&ZJ$t;Az$^4i8 z-du&n*Or*B5yv$VcDA;JHLbrMzys4APoO7yP}?-5v8EMz0Bc%U)AA2Jz?v50`inI! ztZD5YiPP1C+E$k(#&Ar16A(_lLu&u0Jt002ov JPDHLkV1lNTIFtYY diff --git a/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CORNER/metadata.json b/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CORNER/metadata.json deleted file mode 100644 index 2d4bfe30da..0000000000 --- a/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CORNER/metadata.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "numScreenshots": 1 -} \ No newline at end of file diff --git a/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CORNERS/000.png b/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CORNERS/000.png deleted file mode 100644 index d624061419aaaacd85af49537aadf960584abb21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1195 zcmV;c1XTNpP)Px(Wl2OqRCr$PUC(P1K@@&NN$8hq8IJI zP;ybRXGx)+)uVV+6j~DW;z3$%p@uYvcxa&zDJ!$x#Z72;-elj<)qa7{(9Yz0-}~mx z?wdC|RdmQ+>X7jzF5%-ubg8ee?_4&UJ)g;Bsv8>{x3#kd1_sJIJ3Hg8R_o)|*48H? zdQU`aLXH&2H4#2NIy(9!pUV*EK=Xt9{bS&Cn zVPS!0W@ehTT1|I+Yf0KEZX97foK`*0(?4$o?W9pQh6C1Izy zrXk&CtLJ%Vi0B~^T_d8`!5_oVPnA-iEy=N(OX6A)j#}q=o+eI8si!Qfg&HNrwIUpN z`az)Zn}EaBK<#Ia6&AsbBU~V&??DXT3}RTvSNPg1hIPE^7@iMeSWj#}EX8$-8%Ox^ z(9qD!+1c6L^z?M6&1*_2pZs34bh%vCv-GbI?d&Fw%Oxyi|G|F^2p_x#ZY_Yq z`}kKpO=IdPj%!lbS(;`b>-y*t57I-VhrHlLdMK5aT1{F!anjuigww50a_gWl(nC}a{V{;*VGs(a z9wwhxksc-mx>n7s3T*6HI(%%e()2~r73!!i_|E0e-6i&ZJ$t;Az$^4i8 z-du&n*Or*B5yv$VcDA;JHLbrMzys4APoO7yP}?-5v8EMz0Bc%U)AA2Jz?v50`inI! ztZD5YiPP1C+E$k(#&Ar16A(_lLu&u0Jt002ov JPDHLkV1lNTIFtYY diff --git a/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CORNERS/metadata.json b/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CORNERS/metadata.json deleted file mode 100644 index 2d4bfe30da..0000000000 --- a/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CORNERS/metadata.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "numScreenshots": 1 -} \ No newline at end of file diff --git a/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode RADIUS/000.png b/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode RADIUS/000.png deleted file mode 100644 index d624061419aaaacd85af49537aadf960584abb21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1195 zcmV;c1XTNpP)Px(Wl2OqRCr$PUC(P1K@@&NN$8hq8IJI zP;ybRXGx)+)uVV+6j~DW;z3$%p@uYvcxa&zDJ!$x#Z72;-elj<)qa7{(9Yz0-}~mx z?wdC|RdmQ+>X7jzF5%-ubg8ee?_4&UJ)g;Bsv8>{x3#kd1_sJIJ3Hg8R_o)|*48H? zdQU`aLXH&2H4#2NIy(9!pUV*EK=Xt9{bS&Cn zVPS!0W@ehTT1|I+Yf0KEZX97foK`*0(?4$o?W9pQh6C1Izy zrXk&CtLJ%Vi0B~^T_d8`!5_oVPnA-iEy=N(OX6A)j#}q=o+eI8si!Qfg&HNrwIUpN z`az)Zn}EaBK<#Ia6&AsbBU~V&??DXT3}RTvSNPg1hIPE^7@iMeSWj#}EX8$-8%Ox^ z(9qD!+1c6L^z?M6&1*_2pZs34bh%vCv-GbI?d&Fw%Oxyi|G|F^2p_x#ZY_Yq z`}kKpO=IdPj%!lbS(;`b>-y*t57I-VhrHlLdMK5aT1{F!anjuigww50a_gWl(nC}a{V{;*VGs(a z9wwhxksc-mx>n7s3T*6HI(%%e()2~r73!!i_|E0e-6i&ZJ$t;Az$^4i8 z-du&n*Or*B5yv$VcDA;JHLbrMzys4APoO7yP}?-5v8EMz0Bc%U)AA2Jz?v50`inI! ztZD5YiPP1C+E$k(#&Ar16A(_lLu&u0Jt002ov JPDHLkV1lNTIFtYY diff --git a/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode RADIUS/metadata.json b/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode RADIUS/metadata.json deleted file mode 100644 index 2d4bfe30da..0000000000 --- a/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode RADIUS/metadata.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "numScreenshots": 1 -} \ No newline at end of file diff --git a/test/unit/visual/screenshots/Shape drawing/2D mode/Drawing quad strips/000.png b/test/unit/visual/screenshots/Shape drawing/2D mode/Drawing quad strips/000.png index 6991e9e2db04fe4234b1416a3b13cb65cbc8c156..c2680ef9ab30ea0d1dee1bf7a6f1324de7d1d0a2 100644 GIT binary patch delta 589 zcmV-T0rJSqjf)GwApG zY^o@ONLNJ*M6xPcAd*$l29c_YHi%SJNFWkbA%UPOrBVqT#{sX`%kp=;+wI&vMcpf8 zkb1oikH-UiK7Sv1+hZf}gn-|N!vSiw8l=-{Qe(&| zh?I{6a=YE2(P+T^ekT?E8FV_G+>x5k=j41Okkx7h*XtD~lL@)-d*FCHc8@>pcAK1! z1k&wx-2-2_TqYNO4=fgo5DtgQ{=i%$5NZA(fk^ZR34g?dKbFfSv|6o?##DQ>dc7WG zG8s016bc21L?R#ggQSQ=e`te9^@lbH`r~rBz;rtOXr5oexIZ}jp$#I{AKD;N{h;XA&+2XA=qq{F5o-(5FUGQ5RNN$C$liz?t%ufm(0_FuSv@5Xxmr;aaKGQ- za=DN!9z_vcuU9fF${^Cp^XxkRu!S{(x)4;y(kftfR9?FQ!hXlFZZs>*ICstMU4T8-F z`qtu>54%A)<^yGfV?IzI9P?o>2-kdQ8{wJ{Z4j>cuoHxHKD3N*&W9EV=X}@)BJ;6r z8^m!;^0!^SE)B!*qw~k_AEI;~G4Wa9le5QP-Bbc0(K2AThyyX)VD0kGh<3{iPjE&I jH(0y8Gosxx!xO#$fE1uW*>u1O00000NkvXXu0mjfZMMs3 diff --git a/test/unit/visual/screenshots/Shape drawing/2D mode/Drawing triangle strips/000.png b/test/unit/visual/screenshots/Shape drawing/2D mode/Drawing triangle strips/000.png index b91dfd95afea083eb8bd51f7921c326c284413d1..ffb50a7b52679b9883bf7870ea75c8fcbee0d653 100644 GIT binary patch delta 875 zcmV-x1C;##1da!gFn7c&Z#BKg>nPksoFV97h~S40YiD+kaXM3k#^Puh-Jgv$Hdd zjEtb8qeDwRN}}Y*@$oS>Ha0LmKK@bo{hdD$yuQ97olfKF=?S&9wb1L=6!O85kI_4$0=`W>Mi{P)kb-9v>g!cDt=HsIjq8lusn&{{9|QQ&V_& zcn}q(prfNBM59sE)zx8dZ_nCN+uPgXd?F!K`0nlwnM_7hIFU$Lqe@?2ANKe6kxHek z@n?R1UVoI2f50W+XliOgI2>l@D+Y*!Nckx8 zkj-Wh2n0SB-O$j0_4RczA0kI2eEiPC<>lq4u3ukYSImb<2$v5#5B9x7e9#4pwpt|* zdutJ-kw`>|k5W9?7dt#W46oN)5g#H)RQV{!gMVF!4nEjIRQULc2fGMee6WQOAGf!+ z*xcMKxt+h`!4w~CAz$&K!h_p`jt}y8n3p{QTVdO&1@mtu;D23cuf9v4~=V-rin#JRWWNlwsFa z(NH2sh@r-c(>jibTW2WHal}w##c3T!#H}+F_zT-xX-~hOX$t@V002ovPDHLkV1fyw Br>y`0 delta 602 zcmV-g0;T@tEV7*>LyWM7;908`&DRjGCn9XL;YPF!(>#13>20<(P{T`wyB7-az3pgAOuv{*m zg+Q?Jc&ui{8iZrTv|v_1(+UZMVkOUl38HC*1Y%>Q$bu^?WRQ1OY%I94LI%mRLbc$+ z3JWA_g=68Bm4Crtz`h)_KvFB!Y85J#3j5xY1;U%{a5zjRXRtwbyB%CE7ZnI>O`Kl= zX*Qeic*yrH($>TqZ5+oO8ObqhBT^9a0ucnk=RvmHE!1i?Sgls93L-?O(@7pe@wp4F zT(4K?_xr5%*hVlP2!eltI`B^;!0~u|=4&#UBp}?NvwuOjZT0F>Ep4lhffU^^zXC$d zhnWYn6*cm~GD68mULH&kjeM{`Z1Z9J=%Ue9PC$zCU>f-fNKrnD^57~TWFznLVUq_} z`5=S5%7<+pT(y-Lgqnv^fSCE9=D}q?NJg^x;N-z&K1d*GKDc>s*;Zr_+)zumJgHB; zr2xTv;8VnXU+&&-76kKEuh&KIAHND?^Lg6EX9dZ-M_xCuUv;IerG2~y(XOa;J#R!> oLG9zc5$%df*YifC71Tcd2PhvuPyJZZ`2YX_07*qoM6N<$f``x-?EnA( diff --git a/test/unit/visual/screenshots/Shape drawing/2D mode/Drawing with contours/000.png b/test/unit/visual/screenshots/Shape drawing/2D mode/Drawing with contours/000.png index 179d949b9d64d4e1113e3167eb9ebb076ed81229..adc4faeb7f5c1be58c0a59b8b887ae0f7717c07c 100644 GIT binary patch delta 910 zcmV;919AMv2C)Z_F@I}GL_t(&L+zJ8NP1Be$B(m+TS8ldiv(F2u3|J4(Waq;6pn>|gUF%5Ezqr?**F*8!>2FbpZmKe@AuyN?w|9y=im1j zo}Qk%pn=bzgN&IM|8I|ce0)HqQXxLE+wCwlHTCEIk>!z2r+)))Z*S0OGzh@g*B2}< zE)wI*7UteEgZ*LD?US3F2 zW8O5IO_-gXg;*>GGcz*+AS?hI8ynzsI%S0=%_32dcsx!LdVhbPKN}%dR#u1y0)c?w z&O{5FolcWi#r`nt!+wL_^!a@JvbD7}l0$B{o94kK_i7hJGogh(+}YWI z+uPfJl7H+dYp$-YBtwICfoRpbxVRt?2L}gKZ)We{I)>RV1;r6wU*dmg)<0N zy8gimwH6i)Y>44-7#0>51h!x?h(@D;jTp7r+<)AhDi}!+Je3=DvE$>Y`}z4P73c_A4kDFG5zRI1Lv82x`&Glp0_itEPMl*n;Y-Vb;Lhh@&~r+|OcjV6-{UBN zVRn6eEoV8uW_x>^%sEP>KQj;%kC{wnASa}#FlV;5wiHW$CLm&ZO$wm*zZ&V!1Vn5U zP=5lVM*8a@!(Lc3p~Z~?SWf#Jpj3!qvSZItD*c&+78k delta 803 zcmV+;1Kj+v2ge4GF@FI`L_t(&L+zQdt^rXHhG!Gu33MJnrBH~1AXEwupjIg~3W-Dz ziA14MsMH=np&|&yMxju70G%fw5;wES5xdUr&YsO#;_fCll55ZI`DXr^^UuACs;Uq8 zflKj0zATIXJ0pj~LCXhzRw|XR$PGCoxarAc0)apP_WM1gQhzBZ6bjJkbTkkK^eHeB zNUc_bU@!>1UQgR}Hk;LDVZC0%X0w6o^$N@75=Ntu=UK7^L5O0p2<>*8w7G7#3-kHh za~Mkyrx1+v6ELPARuCv9yiiVNnerNj3xY)*4u_%N@4wYTtJQ+tZU>1(0%Eb4)&THY ztyXWflTN3hTz@V@JRT>>(#=h#AdyH!7j4W!E|=4~ld&@)4E`8la812lhw*sqW{;$` zT##fk`L-!VQMeH7EeLWtonX7&K3|L=jYh+h!Z!tZJoH`?K~z<>jE-3VFe9?%^#+2G zHOdML_k2Fvp5oXb27`gFR=lc{HxN9*r_-sBMBD^{RDTE-H*rC#)hfJ7ixoOWS|XBk z3xVsoHDV@_Xf$dnFV?w40w4_pGcp_wby^o`ztq~22EwZod>MmbZufXRKAkWcN~4)< zHk)v{Tx^?!G!T5SozKE(XEGVC8^&LLg+*ZzvV$>;q!om$q0AE-PZ`Saz;ttH+JZ2d z<@0$6g?~btoOpv3-iLY%VnSV;>BX|bi()h zT`TI>sJ=qj4Q41uH!x%nV?7`c+cZxSP9R|5WAMivnzIMSht(aW{$1DG!UK> zrhtfAf2klw-$en@e3PO$E_^8!T3BW zAnXt|PKy*6>g?kg2xg>IDv|#}`FfU6#%j+%e&#^Lh&h4zm_?!J-3ap)rjfdF-hG%E zX65mFis5wnK51RcY9n@r( Date: Wed, 5 Mar 2025 01:53:16 +0530 Subject: [PATCH 03/10] Revert "regenrated test failing screenshots" This reverts commit 8e5025a25904c856082ec01e48944bafd76d733c. --- .../Shape Modes/Negative dimensions/arc/000.png | Bin 0 -> 517 bytes .../Negative dimensions/arc/metadata.json | 3 +++ .../Negative dimensions/ellipse/000.png | Bin 0 -> 557 bytes .../Negative dimensions/ellipse/metadata.json | 3 +++ .../Shape Modes/Shape arc/Mode CENTER/000.png | Bin 0 -> 1195 bytes .../Shape arc/Mode CENTER/metadata.json | 3 +++ .../Shape Modes/Shape arc/Mode CORNER/000.png | Bin 0 -> 1195 bytes .../Shape arc/Mode CORNER/metadata.json | 3 +++ .../Shape Modes/Shape arc/Mode CORNERS/000.png | Bin 0 -> 1195 bytes .../Shape arc/Mode CORNERS/metadata.json | 3 +++ .../Shape Modes/Shape arc/Mode RADIUS/000.png | Bin 0 -> 1195 bytes .../Shape arc/Mode RADIUS/metadata.json | 3 +++ .../2D mode/Drawing quad strips/000.png | Bin 626 -> 479 bytes .../2D mode/Drawing triangle strips/000.png | Bin 910 -> 639 bytes .../2D mode/Drawing with contours/000.png | Bin 945 -> 839 bytes 15 files changed, 18 insertions(+) create mode 100644 test/unit/visual/screenshots/Shape Modes/Negative dimensions/arc/000.png create mode 100644 test/unit/visual/screenshots/Shape Modes/Negative dimensions/arc/metadata.json create mode 100644 test/unit/visual/screenshots/Shape Modes/Negative dimensions/ellipse/000.png create mode 100644 test/unit/visual/screenshots/Shape Modes/Negative dimensions/ellipse/metadata.json create mode 100644 test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CENTER/000.png create mode 100644 test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CENTER/metadata.json create mode 100644 test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CORNER/000.png create mode 100644 test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CORNER/metadata.json create mode 100644 test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CORNERS/000.png create mode 100644 test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CORNERS/metadata.json create mode 100644 test/unit/visual/screenshots/Shape Modes/Shape arc/Mode RADIUS/000.png create mode 100644 test/unit/visual/screenshots/Shape Modes/Shape arc/Mode RADIUS/metadata.json diff --git a/test/unit/visual/screenshots/Shape Modes/Negative dimensions/arc/000.png b/test/unit/visual/screenshots/Shape Modes/Negative dimensions/arc/000.png new file mode 100644 index 0000000000000000000000000000000000000000..b0732e0093e770d0d538f527d5c134e6a58d17c3 GIT binary patch literal 517 zcmV+g0{Z=lP)Px$zez+vRA@u(*0FC+Q5eVZ&$-GQ5{9O#lY|I~i9{?lkp2lsM-q#Hgh68P7l?$R z9jwGIMuQG&=w1mXLdD2N(%vI)UPFWSUMKE(-@G|zexBz%zwh_t<_2SO!kFYxf{dEU zVx$=9h(LK-9f3_ATZ|;5>!`69=?HA{*kU9ZT}O?@NJn6k#}*^W=sIdFMmhqUJhm7~ zM%PheG4h|l-o{BB#sNITwUpVzFtQjz?{bX2J;Dim#We9479Zf|$Oj44{utvV@e0FuV0jiFL;AjSZMnWhaIHto{e=SNF$=m z1;t2a;EmT6BaMhM7Zf9zfj3@Pj5H$3Tu_W;2Htqx*ckZPx$=Sf6CRA@u();()fK^VpH-@UupAYv0%Oso`ad?{@tpaegFmG~935K>xL*(uls zG_C2ZEUYX{M4r;RM$uAS*yytur8@;#wL=wd-x zuKuj5l{M*iCQh`qx*&~%_l#^5o0~xLL=Eo^#d4a2uW~L|}5Izs`u=jc|+m+BR zgqywVcl1A|KJ>2NX^rNQweH&D(4ep1t^3a~e4TQbGZf9Px(Wl2OqRCr$PUC(P1K@@&NN$8hq8IJI zP;ybRXGx)+)uVV+6j~DW;z3$%p@uYvcxa&zDJ!$x#Z72;-elj<)qa7{(9Yz0-}~mx z?wdC|RdmQ+>X7jzF5%-ubg8ee?_4&UJ)g;Bsv8>{x3#kd1_sJIJ3Hg8R_o)|*48H? zdQU`aLXH&2H4#2NIy(9!pUV*EK=Xt9{bS&Cn zVPS!0W@ehTT1|I+Yf0KEZX97foK`*0(?4$o?W9pQh6C1Izy zrXk&CtLJ%Vi0B~^T_d8`!5_oVPnA-iEy=N(OX6A)j#}q=o+eI8si!Qfg&HNrwIUpN z`az)Zn}EaBK<#Ia6&AsbBU~V&??DXT3}RTvSNPg1hIPE^7@iMeSWj#}EX8$-8%Ox^ z(9qD!+1c6L^z?M6&1*_2pZs34bh%vCv-GbI?d&Fw%Oxyi|G|F^2p_x#ZY_Yq z`}kKpO=IdPj%!lbS(;`b>-y*t57I-VhrHlLdMK5aT1{F!anjuigww50a_gWl(nC}a{V{;*VGs(a z9wwhxksc-mx>n7s3T*6HI(%%e()2~r73!!i_|E0e-6i&ZJ$t;Az$^4i8 z-du&n*Or*B5yv$VcDA;JHLbrMzys4APoO7yP}?-5v8EMz0Bc%U)AA2Jz?v50`inI! ztZD5YiPP1C+E$k(#&Ar16A(_lLu&u0Jt002ov JPDHLkV1lNTIFtYY literal 0 HcmV?d00001 diff --git a/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CENTER/metadata.json b/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CENTER/metadata.json new file mode 100644 index 0000000000..2d4bfe30da --- /dev/null +++ b/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CENTER/metadata.json @@ -0,0 +1,3 @@ +{ + "numScreenshots": 1 +} \ No newline at end of file diff --git a/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CORNER/000.png b/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CORNER/000.png new file mode 100644 index 0000000000000000000000000000000000000000..d624061419aaaacd85af49537aadf960584abb21 GIT binary patch literal 1195 zcmV;c1XTNpP)Px(Wl2OqRCr$PUC(P1K@@&NN$8hq8IJI zP;ybRXGx)+)uVV+6j~DW;z3$%p@uYvcxa&zDJ!$x#Z72;-elj<)qa7{(9Yz0-}~mx z?wdC|RdmQ+>X7jzF5%-ubg8ee?_4&UJ)g;Bsv8>{x3#kd1_sJIJ3Hg8R_o)|*48H? zdQU`aLXH&2H4#2NIy(9!pUV*EK=Xt9{bS&Cn zVPS!0W@ehTT1|I+Yf0KEZX97foK`*0(?4$o?W9pQh6C1Izy zrXk&CtLJ%Vi0B~^T_d8`!5_oVPnA-iEy=N(OX6A)j#}q=o+eI8si!Qfg&HNrwIUpN z`az)Zn}EaBK<#Ia6&AsbBU~V&??DXT3}RTvSNPg1hIPE^7@iMeSWj#}EX8$-8%Ox^ z(9qD!+1c6L^z?M6&1*_2pZs34bh%vCv-GbI?d&Fw%Oxyi|G|F^2p_x#ZY_Yq z`}kKpO=IdPj%!lbS(;`b>-y*t57I-VhrHlLdMK5aT1{F!anjuigww50a_gWl(nC}a{V{;*VGs(a z9wwhxksc-mx>n7s3T*6HI(%%e()2~r73!!i_|E0e-6i&ZJ$t;Az$^4i8 z-du&n*Or*B5yv$VcDA;JHLbrMzys4APoO7yP}?-5v8EMz0Bc%U)AA2Jz?v50`inI! ztZD5YiPP1C+E$k(#&Ar16A(_lLu&u0Jt002ov JPDHLkV1lNTIFtYY literal 0 HcmV?d00001 diff --git a/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CORNER/metadata.json b/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CORNER/metadata.json new file mode 100644 index 0000000000..2d4bfe30da --- /dev/null +++ b/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CORNER/metadata.json @@ -0,0 +1,3 @@ +{ + "numScreenshots": 1 +} \ No newline at end of file diff --git a/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CORNERS/000.png b/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CORNERS/000.png new file mode 100644 index 0000000000000000000000000000000000000000..d624061419aaaacd85af49537aadf960584abb21 GIT binary patch literal 1195 zcmV;c1XTNpP)Px(Wl2OqRCr$PUC(P1K@@&NN$8hq8IJI zP;ybRXGx)+)uVV+6j~DW;z3$%p@uYvcxa&zDJ!$x#Z72;-elj<)qa7{(9Yz0-}~mx z?wdC|RdmQ+>X7jzF5%-ubg8ee?_4&UJ)g;Bsv8>{x3#kd1_sJIJ3Hg8R_o)|*48H? zdQU`aLXH&2H4#2NIy(9!pUV*EK=Xt9{bS&Cn zVPS!0W@ehTT1|I+Yf0KEZX97foK`*0(?4$o?W9pQh6C1Izy zrXk&CtLJ%Vi0B~^T_d8`!5_oVPnA-iEy=N(OX6A)j#}q=o+eI8si!Qfg&HNrwIUpN z`az)Zn}EaBK<#Ia6&AsbBU~V&??DXT3}RTvSNPg1hIPE^7@iMeSWj#}EX8$-8%Ox^ z(9qD!+1c6L^z?M6&1*_2pZs34bh%vCv-GbI?d&Fw%Oxyi|G|F^2p_x#ZY_Yq z`}kKpO=IdPj%!lbS(;`b>-y*t57I-VhrHlLdMK5aT1{F!anjuigww50a_gWl(nC}a{V{;*VGs(a z9wwhxksc-mx>n7s3T*6HI(%%e()2~r73!!i_|E0e-6i&ZJ$t;Az$^4i8 z-du&n*Or*B5yv$VcDA;JHLbrMzys4APoO7yP}?-5v8EMz0Bc%U)AA2Jz?v50`inI! ztZD5YiPP1C+E$k(#&Ar16A(_lLu&u0Jt002ov JPDHLkV1lNTIFtYY literal 0 HcmV?d00001 diff --git a/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CORNERS/metadata.json b/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CORNERS/metadata.json new file mode 100644 index 0000000000..2d4bfe30da --- /dev/null +++ b/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode CORNERS/metadata.json @@ -0,0 +1,3 @@ +{ + "numScreenshots": 1 +} \ No newline at end of file diff --git a/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode RADIUS/000.png b/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode RADIUS/000.png new file mode 100644 index 0000000000000000000000000000000000000000..d624061419aaaacd85af49537aadf960584abb21 GIT binary patch literal 1195 zcmV;c1XTNpP)Px(Wl2OqRCr$PUC(P1K@@&NN$8hq8IJI zP;ybRXGx)+)uVV+6j~DW;z3$%p@uYvcxa&zDJ!$x#Z72;-elj<)qa7{(9Yz0-}~mx z?wdC|RdmQ+>X7jzF5%-ubg8ee?_4&UJ)g;Bsv8>{x3#kd1_sJIJ3Hg8R_o)|*48H? zdQU`aLXH&2H4#2NIy(9!pUV*EK=Xt9{bS&Cn zVPS!0W@ehTT1|I+Yf0KEZX97foK`*0(?4$o?W9pQh6C1Izy zrXk&CtLJ%Vi0B~^T_d8`!5_oVPnA-iEy=N(OX6A)j#}q=o+eI8si!Qfg&HNrwIUpN z`az)Zn}EaBK<#Ia6&AsbBU~V&??DXT3}RTvSNPg1hIPE^7@iMeSWj#}EX8$-8%Ox^ z(9qD!+1c6L^z?M6&1*_2pZs34bh%vCv-GbI?d&Fw%Oxyi|G|F^2p_x#ZY_Yq z`}kKpO=IdPj%!lbS(;`b>-y*t57I-VhrHlLdMK5aT1{F!anjuigww50a_gWl(nC}a{V{;*VGs(a z9wwhxksc-mx>n7s3T*6HI(%%e()2~r73!!i_|E0e-6i&ZJ$t;Az$^4i8 z-du&n*Or*B5yv$VcDA;JHLbrMzys4APoO7yP}?-5v8EMz0Bc%U)AA2Jz?v50`inI! ztZD5YiPP1C+E$k(#&Ar16A(_lLu&u0Jt002ov JPDHLkV1lNTIFtYY literal 0 HcmV?d00001 diff --git a/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode RADIUS/metadata.json b/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode RADIUS/metadata.json new file mode 100644 index 0000000000..2d4bfe30da --- /dev/null +++ b/test/unit/visual/screenshots/Shape Modes/Shape arc/Mode RADIUS/metadata.json @@ -0,0 +1,3 @@ +{ + "numScreenshots": 1 +} \ No newline at end of file diff --git a/test/unit/visual/screenshots/Shape drawing/2D mode/Drawing quad strips/000.png b/test/unit/visual/screenshots/Shape drawing/2D mode/Drawing quad strips/000.png index c2680ef9ab30ea0d1dee1bf7a6f1324de7d1d0a2..6991e9e2db04fe4234b1416a3b13cb65cbc8c156 100644 GIT binary patch delta 441 zcmV;q0Y?7v1m6RYFn;XA&+2XA=qq{F5o-(5FUGQ5RNN$C$liz?t%ufm(0_FuSv@5Xxmr;aaKGQ- za=DN!9z_vcuU9fF${^Cp^XxkRu!S{(x)4;y(kftfR9?FQ!hXlFZZs>*ICstMU4T8-F z`qtu>54%A)<^yGfV?IzI9P?o>2-kdQ8{wJ{Z4j>cuoHxHKD3N*&W9EV=X}@)BJ;6r z8^m!;^0!^SE)B!*qw~k_AEI;~G4Wa9le5QP-Bbc0(K2AThyyX)VD0kGh<3{iPjE&I jH(0y8Gosxx!xO#$fE1uW*>u1O00000NkvXXu0mjfZMMs3 delta 589 zcmV-T0rJSqjf)GwApG zY^o@ONLNJ*M6xPcAd*$l29c_YHi%SJNFWkbA%UPOrBVqT#{sX`%kp=;+wI&vMcpf8 zkb1oikH-UiK7Sv1+hZf}gn-|N!vSiw8l=-{Qe(&| zh?I{6a=YE2(P+T^ekT?E8FV_G+>x5k=j41Okkx7h*XtD~lL@)-d*FCHc8@>pcAK1! z1k&wx-2-2_TqYNO4=fgo5DtgQ{=i%$5NZA(fk^ZR34g?dKbFfSv|6o?##DQ>dc7WG zG8s016bc21L?R#ggQSQ=e`te9^@lbH`r~rBz;rtOXr5oexIZ}jp$#I{AKD;N{h@tEV7*>LyWM7;908`&DRjGCn9XL;YPF!(>#13>20<(P{T`wyB7-az3pgAOuv{*m zg+Q?Jc&ui{8iZrTv|v_1(+UZMVkOUl38HC*1Y%>Q$bu^?WRQ1OY%I94LI%mRLbc$+ z3JWA_g=68Bm4Crtz`h)_KvFB!Y85J#3j5xY1;U%{a5zjRXRtwbyB%CE7ZnI>O`Kl= zX*Qeic*yrH($>TqZ5+oO8ObqhBT^9a0ucnk=RvmHE!1i?Sgls93L-?O(@7pe@wp4F zT(4K?_xr5%*hVlP2!eltI`B^;!0~u|=4&#UBp}?NvwuOjZT0F>Ep4lhffU^^zXC$d zhnWYn6*cm~GD68mULH&kjeM{`Z1Z9J=%Ue9PC$zCU>f-fNKrnD^57~TWFznLVUq_} z`5=S5%7<+pT(y-Lgqnv^fSCE9=D}q?NJg^x;N-z&K1d*GKDc>s*;Zr_+)zumJgHB; zr2xTv;8VnXU+&&-76kKEuh&KIAHND?^Lg6EX9dZ-M_xCuUv;IerG2~y(XOa;J#R!> oLG9zc5$%df*YifC71Tcd2PhvuPyJZZ`2YX_07*qoM6N<$f``x-?EnA( delta 875 zcmV-x1C;##1da!gFn7c&Z#BKg>nPksoFV97h~S40YiD+kaXM3k#^Puh-Jgv$Hdd zjEtb8qeDwRN}}Y*@$oS>Ha0LmKK@bo{hdD$yuQ97olfKF=?S&9wb1L=6!O85kI_4$0=`W>Mi{P)kb-9v>g!cDt=HsIjq8lusn&{{9|QQ&V_& zcn}q(prfNBM59sE)zx8dZ_nCN+uPgXd?F!K`0nlwnM_7hIFU$Lqe@?2ANKe6kxHek z@n?R1UVoI2f50W+XliOgI2>l@D+Y*!Nckx8 zkj-Wh2n0SB-O$j0_4RczA0kI2eEiPC<>lq4u3ukYSImb<2$v5#5B9x7e9#4pwpt|* zdutJ-kw`>|k5W9?7dt#W46oN)5g#H)RQV{!gMVF!4nEjIRQULc2fGMee6WQOAGf!+ z*xcMKxt+h`!4w~CAz$&K!h_p`jt}y8n3p{QTVdO&1@mtu;D23cuf9v4~=V-rin#JRWWNlwsFa z(NH2sh@r-c(>jibTW2WHal}w##c3T!#H}+F_zT-xX-~hOX$t@V002ovPDHLkV1fyw Br>y`0 diff --git a/test/unit/visual/screenshots/Shape drawing/2D mode/Drawing with contours/000.png b/test/unit/visual/screenshots/Shape drawing/2D mode/Drawing with contours/000.png index adc4faeb7f5c1be58c0a59b8b887ae0f7717c07c..179d949b9d64d4e1113e3167eb9ebb076ed81229 100644 GIT binary patch delta 803 zcmV+;1Kj+v2ge4GF@FI`L_t(&L+zQdt^rXHhG!Gu33MJnrBH~1AXEwupjIg~3W-Dz ziA14MsMH=np&|&yMxju70G%fw5;wES5xdUr&YsO#;_fCll55ZI`DXr^^UuACs;Uq8 zflKj0zATIXJ0pj~LCXhzRw|XR$PGCoxarAc0)apP_WM1gQhzBZ6bjJkbTkkK^eHeB zNUc_bU@!>1UQgR}Hk;LDVZC0%X0w6o^$N@75=Ntu=UK7^L5O0p2<>*8w7G7#3-kHh za~Mkyrx1+v6ELPARuCv9yiiVNnerNj3xY)*4u_%N@4wYTtJQ+tZU>1(0%Eb4)&THY ztyXWflTN3hTz@V@JRT>>(#=h#AdyH!7j4W!E|=4~ld&@)4E`8la812lhw*sqW{;$` zT##fk`L-!VQMeH7EeLWtonX7&K3|L=jYh+h!Z!tZJoH`?K~z<>jE-3VFe9?%^#+2G zHOdML_k2Fvp5oXb27`gFR=lc{HxN9*r_-sBMBD^{RDTE-H*rC#)hfJ7ixoOWS|XBk z3xVsoHDV@_Xf$dnFV?w40w4_pGcp_wby^o`ztq~22EwZod>MmbZufXRKAkWcN~4)< zHk)v{Tx^?!G!T5SozKE(XEGVC8^&LLg+*ZzvV$>;q!om$q0AE-PZ`Saz;ttH+JZ2d z<@0$6g?~btoOpv3-iLY%VnSV;>BX|bi()h zT`TI>sJ=qj4Q41uH!x%nV?7`c+cZxSP9R|5WAMivnzIMSht(aW{$1DG!UK> zrhtfAf2klw-$en@e3PO$E_^8!T3BW zAnXt|PKy*6>g?kg2xg>IDv|#}`FfU6#%j+%e&#^Lh&h4zm_?!J-3ap)rjfdF-hG%E zX65mFis5wnK51RcY9n@r((Waq;6pn>|gUF%5Ezqr?**F*8!>2FbpZmKe@AuyN?w|9y=im1j zo}Qk%pn=bzgN&IM|8I|ce0)HqQXxLE+wCwlHTCEIk>!z2r+)))Z*S0OGzh@g*B2}< zE)wI*7UteEgZ*LD?US3F2 zW8O5IO_-gXg;*>GGcz*+AS?hI8ynzsI%S0=%_32dcsx!LdVhbPKN}%dR#u1y0)c?w z&O{5FolcWi#r`nt!+wL_^!a@JvbD7}l0$B{o94kK_i7hJGogh(+}YWI z+uPfJl7H+dYp$-YBtwICfoRpbxVRt?2L}gKZ)We{I)>RV1;r6wU*dmg)<0N zy8gimwH6i)Y>44-7#0>51h!x?h(@D;jTp7r+<)AhDi}!+Je3=DvE$>Y`}z4P73c_A4kDFG5zRI1Lv82x`&Glp0_itEPMl*n;Y-Vb;Lhh@&~r+|OcjV6-{UBN zVRn6eEoV8uW_x>^%sEP>KQj;%kC{wnASa}#FlV;5wiHW$CLm&ZO$wm*zZ&V!1Vn5U zP=5lVM*8a@!(Lc3p~Z~?SWf#Jpj3!qvSZItD*c&+78k From 7cdd321427b890def7449938c644953811da2173 Mon Sep 17 00:00:00 2001 From: Vaivaswat Date: Wed, 5 Mar 2025 01:54:24 +0530 Subject: [PATCH 04/10] Revert "tried an approch for text case in pixelmatch" This reverts commit 1569f51caeef8534f60ec9c673196179c99c240e. --- package-lock.json | 20 --- package.json | 1 - .../Drawing closed curve loops/000.png | Bin 1325 -> 857 bytes .../2D mode/Drawing closed curves/000.png | Bin 1334 -> 857 bytes .../Drawing simple closed curves/000.png | Bin 1204 -> 701 bytes .../2D mode/Drawing triangle fans/000.png | Bin 917 -> 743 bytes .../Drawing with cubic beziers/000.png | Bin 963 -> 641 bytes .../000.png | Bin 868 -> 519 bytes .../000.png | Bin 1385 -> 825 bytes .../2D mode/Drawing with triangles/000.png | Bin 1057 -> 693 bytes .../WebGL mode/3D cubic coordinates/000.png | Bin 598 -> 613 bytes .../Drawing closed curve loops/000.png | Bin 654 -> 680 bytes .../Drawing with cubic beziers/000.png | Bin 526 -> 517 bytes test/unit/visual/visualTest.js | 153 ++++++------------ 14 files changed, 46 insertions(+), 128 deletions(-) diff --git a/package-lock.json b/package-lock.json index beed79d351..edccbe8993 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,6 @@ "libtess": "^1.2.2", "omggif": "^1.0.10", "pako": "^2.1.0", - "pixelmatch": "^6.0.0", "zod": "^3.23.8" }, "devDependencies": { @@ -8620,17 +8619,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pixelmatch": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-6.0.0.tgz", - "integrity": "sha512-FYpL4XiIWakTnIqLqvt3uN4L9B3TsuHIvhLILzTiJZMJUsGvmKNeL4H3b6I99LRyerK9W4IuOXw+N28AtRgK2g==", - "dependencies": { - "pngjs": "^7.0.0" - }, - "bin": { - "pixelmatch": "bin/pixelmatch" - } - }, "node_modules/pkg-dir": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", @@ -8654,14 +8642,6 @@ "semver-compare": "^1.0.0" } }, - "node_modules/pngjs": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz", - "integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==", - "engines": { - "node": ">=14.19.0" - } - }, "node_modules/postcss": { "version": "8.5.1", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz", diff --git a/package.json b/package.json index daeebc4136..e34a8ef5c7 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,6 @@ "libtess": "^1.2.2", "omggif": "^1.0.10", "pako": "^2.1.0", - "pixelmatch": "^6.0.0", "zod": "^3.23.8" }, "devDependencies": { diff --git a/test/unit/visual/screenshots/Shape drawing/2D mode/Drawing closed curve loops/000.png b/test/unit/visual/screenshots/Shape drawing/2D mode/Drawing closed curve loops/000.png index 4daa4ef5bdbd099b4d777678428ac48d6256b88f..80536c3fec45666ca76d09905e54705c955df869 100644 GIT binary patch delta 822 zcmV-61IhfY3fTsbFn2)q5J+KXmkSUC3ky*p#8iS8U?B(= zRtkdH*_a>*DMS!rWhYozS_p!mBB&@>2zHja0t>++cz6dUY&`1D?CyvpJ0SQsGw(Cs z@6O$9HapNS7U_yQFH=-%e9uvB|Ar-&wr=rJk2jFWRXUrL95k@ zYPFjA9Tlx03<8+hY^F$t`DLX*>h=1~y4T+W*=#nn+wG*{1n$U3DwQ(tKNnUIwg^D> z`#n{wRb4^Ia?NIw?(gp@91hd#>nmk48A>D)x^s>GK?nrGTCEm+eSI-8dTBTi2r%)* zV)0wo+uIxaPJdOLNr5;V4vNKM7eTVwEJdTy9}t{|!@$j~b~P!GQmI7we4d@^sezbq zxm;8(m(P00a5$uwmlpsBMg#Gr>Rn@SStJ&-c0ZdgCG_jA0LI&t5FNV#d^J-P*11bLl^}8 zR=eG%!GB<2RHN{`r>7@!yWLVQCIy1V(Tc#j@wVg@RPOA`PO_y?+1zcfxIr$R&rN%C4PcbhP&+O_yXaIy7zO&=d0?7r&x`T1mL%tenz zBkK42>~3s2oifq5MbWz>6HSkXLHGu6Gu$XH77Los=l|^+32?X}Ca<3tPxC#mG=&O(=?qW|+RLH6huJLK!ZYFiiP(o|>rmR@TGF*D0fCE1 zTU#3j2L}-z9*)q^P$ifl9g>SkM@I*HT3%jWh>VPsu2l<tqrMJF&dHjO*)b6c-nB znX$02fRT|AoPVF6!@fFpH@{QY&dv_rzI}_VtSmf#{`}9m z+S*zc&CJY9`1tsUvGv|NTttS4hq1c4${HehI3y(GPJhtk8TfWol{)-rnBG z&d$cmmoF7chKmSAVt#%eK|w+I@Zkdr3kz>GqN1V#dwYAVFx({@8yj$Qb3;l>3IYQI z6-I`O$ou#2F*`epuC6Y)xVYTf80kqxMMZ%Oefsq2y#~(B&B5Q_A4y3`2nYyJ2pKLS zOG`^E$$u#-R#sMMY;1(CuI^t3kWsH*y+T1j0heJjGc)k@^+jG@onwp|uxQS3idV70W`J^17hWFyd3yhAAvc5q?rAS&@8mM6K=GaYL z+(an+l<*!N9&A)0<2N@qS@j`uiV#mvPgWJh%yZmC$Ww`liK6m=m*o2TI-ASriP2vn z!hcPK!0qkr@%r^^A^3vN(%wUnr{^m~xQX=j_2K*X?`*+Rw$KD&W@d)CxHxWA+(f8> z(K!G4^Ji{wu?N@I)?jC6$4WiTc09sOy1K&I*_qupF)g9N3dxbXtoZTc2QDry*uNg=Cw6TW z!%|X2#3)qO9TgE}c~&g0Dk5S%r>uLbh$zdmVsZZi06%h1WeLe600000Ne4wvM6N<$ Ef+x3hC;$Ke diff --git a/test/unit/visual/screenshots/Shape drawing/2D mode/Drawing closed curves/000.png b/test/unit/visual/screenshots/Shape drawing/2D mode/Drawing closed curves/000.png index 4442bb3ed680f0fafe11a8a6b777991eb51f809f..80536c3fec45666ca76d09905e54705c955df869 100644 GIT binary patch delta 822 zcmV-61Ihfh3fTsbFn2)q5J+KXmkSUC3ky*p#8iS8U?B(= zRtkdH*_a>*DMS!rWhYozS_p!mBB&@>2zHja0t>++cz6dUY&`1D?CyvpJ0SQsGw(Cs z@6O$9HapNS7U_yQFH=-%e9uvB|Ar-&wr=rJk2jFWRXUrL95k@ zYPFjA9Tlx03<8+hY^F$t`DLX*>h=1~y4T+W*=#nn+wG*{1n$U3DwQ(tKNnUIwg^D> z`#n{wRb4^Ia?NIw?(gp@91hd#>nmk48A>D)x^s>GK?nrGTCEm+eSI-8dTBTi2r%)* zV)0wo+uIxaPJdOLNr5;V4vNKM7eTVwEJdTy9}t{|!@$j~b~P!GQmI7we4d@^sezbq zxm;8(m(P00a5$uwmlpsBMg#Gr>Rn@SStJ&-c0ZdgCG_jA0LI&t5FNV#d^J-P*11bLl^}8 zR=eG%!GB<2RHN{`r>7@!yWLVQCIy1V(Tc#j@wVg@RPOA`PO_y?+1zcfxIr$R&rN%C4PcbhP&+O_yXaIy7zO&=d0?7r&x`T1mL%tenz zBkK42>~3s2oifq5MbWz>6HSkXLHGu6Gu$XH77Los=l|^+32FnFFsnH8o{& zLpm%Mk+iflY;JC%rlv-^MVSz|h~(zxVrXaxJv}`#xgi~vi^#{1A5m3Rg)d*eKub$Y zx>XqvxQNu%)#1~pPY4YSMR0Ji3~oq=%*^KzhG-?i;$2Iu5)6QxQJ9#RN%*tA2>KTKuJl7Qd>kI zJ3AXWIXN&eFhE&Z89Ngb69YRtJEiBvC~y(!>gr62U;r;vfe{>>0KOY+#8>}&0CEve) zhqJRY5)u;N=jW#~GF(LJ>+3NwF@ctr7C1UOqPx5MKMv593J(tlIcjQZdaZ+#lauiB z@dCu;o*UI z@7}4TX1IvZb$Rvb71r0+k(ihWZEbDl^o5L$jtWw=~K2!tZHwY7zllM{9o zQc_abH6sVk&dxxuzgQ_OEJST>EvQA`xpPMp3^x(VNPBxbYoAmj^x*mW`l7$TpS>GI zREi`eC4m|SZ;f5H#Z83LPX+Jd;=)E1a(;PvnROo`rwV!UFVD3c(kwTU}kvGEdi6h;S3>=;*-C&JM_s+(Hw? zg9i@~9UaYWikk>MU^LFt$}6`lE-u2_+M2a`n(cUmo5=R|HezFALBBU4bcJc$p#hUe zxQP%L4SBRM85fGcz*?3k!q2y**yOe8~kPn12YZ zz4Wn8p-^xc5TZ0YJBtq=KClgx3jMlo1DA0H6CnT^An9vJR8*7@Kd;oKsevYjv9U4s zQG#A}eSLjF*rJHg&P^$&&qQK&?%my83=9mg$P#1HIKYk27J-y$eNSh_C$tx=>n17$2XFESdeQj+GPEJm6aByJfjf{*0MgLFAqKOa~ zbuWr2IY*A}?d{?2-Mh@rMQ6Kz|2_;24Pjzpf`<*u&}bQ6$DW$ zv9++W6D&M{V5Oj7Doy+ zLZ)J*NXP`CNRdd9fGqI8Tx+-65qc_>a(Wn>t0DlX*Xz{nc7JKHSkQL6rCP1#^e{D7 zkjZ31i9~`rosP5aUav>z^O^eneyD(4K{A;P-EP0jF#tiOu&Co1M7dR1fIfmCKBm(t zt=H?1;SdHG5s*i9=JPoXheP9eKomqJgKxx+I0#@?s}&WCMWczpcd&o*p;oI!r_+fl zl}g~Q7AVN0tAC9~qd=7@NYHWe z2;^m-VS@y?YLh-vr2{&F}R zSOumQ2&`mE6?I&;ZJU+VwLwg%q96hbc4ZoFXKc6f-E21oc6C^+YhEERJY?flN*xmYAtZJ}08r;V3!k^{!4e~r8fF7G4E96CC5e}lGc=%D^f(lijs3gibz^hVy+*dUJ?LL2~Kgt00000NkvXXu0mjfmX9}c delta 1172 zcmV;F1Z(@f1+)o}Fn)HG0X*8No`~{|`Bl3r3QJ0ZFEFsWkM3)gQt-!yvwWg+~uz$C=2L}fSczSxm&dyFt z>na~sG$Z}}{a9RFM0$EU#>dC8y}gad$Vm3Fva*uzS>>66L_R-1k&%&sfq?j zPft%sO-;r6`Z|)5k`NXargBK~-~@@Bot+^*J|6Gy@Bc$zSy^F(oSdAHo0|($Q&V{n zs5DEE2yLUr#(zc}A0PkLT~SdH%NUUf2nbLqEa@Q zb#-+iFE0;eWn~Bt59gkzbf6%S!^1;VRaN2O;6RceDt`oNX=(8A@L;5V!UTz2US6{D zdv$dsIhN<=XCx;l zg%O=6+S#dt(;2b0wiX5Z-GIKnK4fNQqNb(>K|w*XafBv{5}~q62bfB$5+j*I%{4AA zj%_)$O@EX~eSJL=5)zP-lA_r6(a{lNVq)Op;-Y#H5GB&x-OUbaQ&W>-A_PGFCMqfl z`uh5;BC2JgL>3knnEIWZoK(vv!y%n^a&m%(h6WfK8Y;#XB|^fHWXI|0sbXi}0jS4N z&mlc$Vq&5QUz7-;hlGT%ib z!>X&RF)}iOmX;RTWVndXfj2WVV~(_CwY9a33^h)Bdwa=lxQMK+t)Zu<2dk^Ak{w8y zP*+!niHQl28j!k;xrk6O{{H^#z-wDG6&4nP7LH1@v9U4tI&c%ALrF428(sN(w6U?V z?0+XZm%PSJWOQ_t$@!t7Azo}no6hv$L~5!2={%NobM+7c)sjXj{=L z&Ckz+_OLeX@$r$VWU693R|rW&DDd9iUVmI%Twr*3SZh4y=H^(13=9lJc6K(GAIU^0 zD+J!$+>GexXf7wbgQzlgbadeS{G2_<1_uZ8PL=nM)$;N(NPmrujUhBNl-t>_2GTWw z9>)g<2ibL+o{;2VO3uhvFmz7n@y^G`hrQJM`S}TU;=8*$(DM?h=*`VdCf})W(0^I; z^73Mj97-PbWD_Amw9RNWmzI`TfO>j*u(Y&NlFn#&r!PiDa&oNqvAHU8I-RUxxPSM0J#Qnkd{G@_wOU!j z3x$F?9*@?BR;y)pyPbVaAZ;*Jkb1ptjoogyPk`xkYG04XV+*t2@6BejF}K^zEEbC_ z&d#()4P-DFm~OXgjfK%r0ZW4L{bVvRxYp~n8jK1EA?S4&PgPuycDrpMu@}#@V1hv; z1Y-ckQWXi}LVrnx(lpH!Lhm*OfgrKZ=d(E+4mMO^JQl(WFptOMTWBRoVwGapVISad zNAiahfMAePsq{1+1~!{bYbZm=^`Hzt76IIc!=YI&m)@!bfuKrB55v1mWEczu0EG*m zLm>b{0auyPXcUzA!5}csT?BgNUKxV&IiR6PwOaL3#eW+F`Ej{ip7H+9X!$wSdAIi? zAn4xxe&2@7tA+4kH|O(rds!gL<+69edn-Z^&Cm)d!QLS7B6`SdHv3jiS*?)Fh%>NO)WvIb@^D(hynQ z8jXgjRDUX;1A!;dOWczBZY*IZ=N!fnMPuFyQiNe6=PiyLzYUFY4%2`L4lNn~gmDwu z9Tcew!cYrB6@*o+SS*@Or}Lb-+&@;>hy1|`sZwt5QVA`2D3TwGclkHBR;!u&{cgvQ zkV*Gd16Bude*{3BpM2-2EW=msAX$vi*b_lCygaCRMpQ)8n;K_DMKrvqc}7%3)0-M+ pMMX5csChDo;{a@cRG&002ovPDHLkV1gj$L#6-# delta 882 zcmV-&1C9LW1(gSoFnmAu3vw6fNB(1!4VwP-v;EvY-en zv_(*~sZ3l%pBpJ?kzz>{^tGyGP_%TB8Wg!{8AY{-5}^X|Wd?jvkcxYcWpZYt*K=m> zJoC)VnWH8Y3Z+m4qLDxfj77;vfe`}9h-4&B5s;~sr@$&UD}NbL9J)LyN=EV&SjA@Z z%E;Z_9nR0s*}1m1Hq_VGD|YlNMWH|*A0KgXae?dWYXBK`bsVVq|0lo12@6$KyGH5EK3V{a9UH#pL9qFfgisP)*qFb_@*-fk33CrlyA3 z+1=gEVx+sfn;n08diuYYz^t#YV`F1ORn4dZa(sNuseh76rQmQlILah}Kmbms6Sudw z=;`U<-*$F((9qBTpU=m@Nr*ka-w%yO!>QQO(V@6rQ~_C8S>b|ydwb(t*J`y`SXf|3 zo12^YIbF<@g0%1Q@{)m0O-=DL)mB+q8KTiBMn^|~2S{IEAEyt2A)(YcI5^<;IzK-T ztJR9e#(zd$i^XC%JUoQU<>L0-+1bguB-G7FcWZ0w=Yh~+H#|Iyhlhu(m*3yt!(y=@ z91e5NKR-Y7dUbU*sHR$5TXA%Bgu1%AEIpl0hqbje#fPTi)FNjn-E~`sU^a zA0HpQURqiTyA=7M z1_uXKjVN?L27|%h8&N0^iehL?Cv;Ja@tI({y1ICLpPQS5$z;lTv7+gh21L3oQpYQ( zi)&RHO!}%za}`~6UtV6auDVrKReaT@`Kw^By1Dx1pZ)Ve@gX2UQPqJc;Qhi(NFc&O zDaepyL{K1wnURbL3#A}Kk`Y0H6lO*;A}o}G3`s@=1yY!qe^Bs{PlN_1E&u=k07*qo IM6N<$f(an48~^|S diff --git a/test/unit/visual/screenshots/Shape drawing/2D mode/Drawing with cubic beziers/000.png b/test/unit/visual/screenshots/Shape drawing/2D mode/Drawing with cubic beziers/000.png index 765d6854eeb9bf4b1bc3f9a9c9202f7ce59a4a82..4ed36210fca1966e11b4073c2992f907514a75c5 100644 GIT binary patch delta 604 zcmV-i0;B!I2Z05UFnyfw z0P#%4ponLJP*5Z&q7;Gum0G9MiSqfpQY_uLWhnxX*=$DR@qgIOQx&|hL8j9wO(qkC zEx2*X0>PsSg#txUAg=k`01$;&XbjL3~dy5s1&}B?9p| zy+j};y-|JvdgZQe7707%(r^DgkRj0QC`Kk(v01WdO?07uJpT%O4 z?)N+8aye?XT7U0%y&pVSgDe&cTCdm7jaMoa>i7HcJ-)-X+b!*OyZHNHFrZGSL$}*a z16*=$(R9u9{w5Y%z4kTnR>$@G=SL-rq^29Py~kpSfw>g@M>mMUfu z(yrI*Q8t@(qR!hO*chr zs+k(dYk7t`0D^I$N~Kc#{{Xjfs)Kw5!u(aM)t=&%%jHk$hyDV?XajieyU(wIn4O!6 z0QbpcGF6_Ualrry!=MSnu!$Eq&P&{{gK*D@bX@?EMofEsP((YzQvX2_X~eYG2Sv0a qEcG80kw#2=eNaR@!czZ#Mv)J+tcyS#OCm4;0000t+r`e5h=@-WZ4B5azU+8(ymsr3&{oLN+glLcb1X2=T|Ei-gm!q&d#y-eb4Xq z{C>~#e4g*~d(Lx?=J4?F6aT={s30k(qN+%W2?A9SRS}so@PGf6*7Nf-a&vQK%BOU* zT#9UOZ{zgz6gHbpx<{ETaDjxwVJt5%V|{&HrZA+NB41is!rR*$ zMn*>dZjigXJG8d8A{Y!JFE1};U<4~dk*}<*fXb}DzyG%&@9*zOOG{G>R20bL<0DKa z6a0QZii?Zc97bcz+1VMcuCDO#@Bo?yXvi!pD??394S(wE>rq--DjS$65Q=7ZcNhEn z`>ecCv-^if9NGfhoRY)mOHFaK64 znt!kfp5Fe{p7nZtLKsCr;!)7-MZ@Ls@iETN&vAWy4Xsv-%*;$S;zXlS&>zj5oE-My zR#H;J+AQ5q`KyncQGc(TMm<`~V(00000NkvXXu0mjf D+2G5; diff --git a/test/unit/visual/screenshots/Shape drawing/2D mode/Drawing with curves in the middle of other shapes/000.png b/test/unit/visual/screenshots/Shape drawing/2D mode/Drawing with curves in the middle of other shapes/000.png index 34563ac1055d90832c5ea3ebfbd0a64852cbef5b..3645b1eabce6fdc25e45673e516d891b95606196 100644 GIT binary patch delta 481 zcmV<70UrM328RTYFnj4Am|z89j!%+1Mr=whJQ5>^vv`5gu~%rahZBk zRaL=uyR{3l*=*o?z3Sg?aRh?oc@9NUXswd=2r9xLT3`M=;A0d)M9=d;2%&X{)1if{ z-|cpgrm41;Fo;%bO9PI_BP2<(ensy0I}F31ttHNf7BzD*h@~w+GDAth&MQK#C943T z)Di|E1-GR^lz$Yw3Pl)X9ufcbJ)+h@DT=EIEe7GxvXpM;WlNui{)-N`Pd6#IHkarMo4``&lnov-)Q>D}6S zpL2fC|2fajc?#n3cn1GLE6_lGLB;9mX*SEo#s+t`yjDa5;eYD)%L6n;e%ayN=`=-t za?$qoHrInn4~Rq}sH&=h-|y#|mXv-8;_mJaU0q#VgGvrKJv~K3LjxuzCb(uLgVfg6 z!sGF94JtXn=kwwE`WjBBlWSHoNKH)*=H}+O29+GJva*7clM_kvN(NCwk$61L)Y#nI z7P=8lfhvVa8Ehq1c4ilwC`u|aNcZ_(S^i~aq5WkA#l zt&fin=yWaJP@95~j(9jUt+uP-XsDGsht=ww0vV&u5Ypd8GcDo(j z-QBR+Y+{3qjg6tczMgIRY)$eWQ8TpMZZ~Mt4-XHE4YIhni2M6{OioUU4YIYhg`=Y* zkTODtRxlVuAP~U9!h+Z!XJ=<{xm;LZUl$vM4vixtBiPy55gX+4@)8b*1G~GsVuPHY zpR>C=?SB)YH+v`)!rIyzmY0{s2Jw2mxVpN+?Ch-AApQOQuvjc&A5q@l-%(mx3i>ZG znM~p;GCw~LD%A1HwUQ5w4-XIM>+8ek=O-)CG&eV+yu6%SIFmEr;NSp*gM--H+hc_~ z*>x>Cc~TCiXEK>YB9Q=rk>pe@Z)s^^V2zE9-+#TRsOX;=D4b}6Q@=jP@H zu~>}R?CI&j`1m+iiLbTE0?7tQ02J4x*z4;nQmNE;r|(}qolYZ@$w05y!(cG5@@P|2 z6FS=3+J4;Ff15WaAiOZh#qSzOF1#worlyD-@8#lMO_5x9RgTR+wvirB0jxLW00000 LNkvXXu0mjfT0EyC diff --git a/test/unit/visual/screenshots/Shape drawing/2D mode/Drawing with curves with tightness/000.png b/test/unit/visual/screenshots/Shape drawing/2D mode/Drawing with curves with tightness/000.png index 0a613221b12b1b73f51d01a7410aae27edd5e98e..36ee10117a1850bf4af80c7d3a182571a3224412 100644 GIT binary patch delta 790 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 diff --git a/test/unit/visual/visualTest.js b/test/unit/visual/visualTest.js index 5b1bf06abd..068e8c7247 100644 --- a/test/unit/visual/visualTest.js +++ b/test/unit/visual/visualTest.js @@ -1,7 +1,6 @@ import p5 from '../../../src/app.js'; import { server } from '@vitest/browser/context' import { THRESHOLD, DIFFERENCE, ERODE } from '../../../src/core/constants.js'; -import pixelmatch from 'pixelmatch'; const { readFile, writeFile } = server.commands // By how much can each color channel value (0-255) differ before @@ -88,116 +87,56 @@ export function visualSuite( } export async function checkMatch(actual, expected, p5) { - // First do standard pixelmatch comparison - const diffData = actual.drawingContext.createImageData(actual.width, actual.height); - - // Get image data from both canvases - const actualData = actual.drawingContext.getImageData(0, 0, actual.width, actual.height); - const expectedData = expected.drawingContext.getImageData(0, 0, actual.width, actual.height); - - // Function to check if a region looks like text - // Text typically has high contrast and specific density patterns - const isLikelyText = (data, x, y, width) => { - const region = 3; // Check 3x3 area - let transitions = 0; - let nonEmpty = 0; - - for (let dy = -region; dy <= region; dy++) { - for (let dx = -region; dx <= region; dx++) { - const px = x + dx; - const py = y + dy; - if (px < 0 || px >= width || py < 0 || py >= width) continue; - - const idx = (py * width + px) * 4; - // Check if pixel is non-transparent and has significant contrast - if (data.data[idx + 3] > 20) { - nonEmpty++; - // Check for contrast with neighboring pixels - if (px > 0) { - const prevIdx = (py * width + (px - 1)) * 4; - if (Math.abs(data.data[idx] - data.data[prevIdx]) > 30) { - transitions++; - } - } - } - } - } - - // Text typically has moderate density and high number of transitions - return nonEmpty > 4 && nonEmpty < 20 && transitions > 3; - }; - - // Custom comparison function that's more lenient with text - let diffCount = 0; - const shiftThreshold = 2; // Maximum pixels of shift allowed for text - - for (let y = 0; y < actual.height; y++) { - for (let x = 0; x < actual.width; x++) { - const idx = (y * actual.width + x) * 4; - - // Check if pixels match exactly - const exactMatch = [0, 1, 2, 3].every(i => - Math.abs(actualData.data[idx + i] - expectedData.data[idx + i]) < 0.4 * 255 - ); - - if (exactMatch) { - // Pixels match, copy expected pixel to diff - [0, 1, 2, 3].forEach(i => diffData.data[idx + i] = expectedData.data[idx + i]); - continue; - } - - // If pixels don't match, check if it might be shifted text - if (isLikelyText(expectedData, x, y, actual.width)) { - let foundMatch = false; - - // Look for matching pixel within shift threshold - searchLoop: - for (let dy = -shiftThreshold; dy <= shiftThreshold; dy++) { - for (let dx = -shiftThreshold; dx <= shiftThreshold; dx++) { - const sx = x + dx; - const sy = y + dy; - - if (sx < 0 || sx >= actual.width || sy < 0 || sy >= actual.height) continue; - - const shiftIdx = (sy * actual.width + sx) * 4; - const pixelMatch = [0, 1, 2, 3].every(i => - Math.abs(actualData.data[idx + i] - expectedData.data[shiftIdx + i]) < 0.4 * 255 - ); - - if (pixelMatch) { - foundMatch = true; - break searchLoop; - } - } - } - - if (foundMatch) { - // Mark as acceptable text shift (yellow in diff) - diffData.data[idx] = 255; // R - diffData.data[idx + 1] = 255; // G - diffData.data[idx + 2] = 0; // B - diffData.data[idx + 3] = 255; // A - continue; - } - } - - // If we get here, it's a real difference - diffCount++; - // Mark as difference (red in diff) - diffData.data[idx] = 255; // R - diffData.data[idx + 1] = 0; // G - diffData.data[idx + 2] = 0; // B - diffData.data[idx + 3] = 255; // A - } + let scale = Math.min(MAX_SIDE/expected.width, MAX_SIDE/expected.height); + + // Long screenshots end up super tiny when fit to a small square, so we + // can double the max side length for these + const ratio = expected.width / expected.height; + const narrow = ratio !== 1; + if (narrow) { + scale *= 2; + } + + for (const img of [actual, expected]) { + img.resize( + Math.ceil(img.width * scale), + Math.ceil(img.height * scale) + ); } - - // Create diff image + + const expectedWithBg = p5.createGraphics(expected.width, expected.height); + expectedWithBg.pixelDensity(1); + expectedWithBg.background(BG); + expectedWithBg.image(expected, 0, 0); + const cnv = p5.createGraphics(actual.width, actual.height); - cnv.drawingContext.putImageData(diffData, 0, 0); + cnv.pixelDensity(1); + cnv.background(BG); + cnv.image(actual, 0, 0); + cnv.blendMode(DIFFERENCE); + cnv.image(expectedWithBg, 0, 0); + for (let i = 0; i < shiftThreshold; i++) { + cnv.filter(ERODE, false); + } const diff = cnv.get(); cnv.remove(); - - return { ok: diffCount === 0, diff }; + diff.loadPixels(); + expectedWithBg.remove(); + + let ok = true; + for (let i = 0; i < diff.pixels.length; i += 4) { + let diffSum = 0; + for (let off = 0; off < 3; off++) { + diffSum += diff.pixels[i+off] + } + diffSum /= 3; + if (diffSum > COLOR_THRESHOLD) { + ok = false; + break; + } + } + + return { ok, diff }; } /** From 6e793f2b06a194137d00d1f194aeec17c21772ae Mon Sep 17 00:00:00 2001 From: Vaivaswat Date: Wed, 5 Mar 2025 02:26:34 +0530 Subject: [PATCH 05/10] tried pixelmatch with some customizations --- package-lock.json | 20 ++++ package.json | 1 + test/unit/visual/visualTest.js | 177 +++++++++++++++++++++++++++------ 3 files changed, 166 insertions(+), 32 deletions(-) diff --git a/package-lock.json b/package-lock.json index edccbe8993..bc9e66139d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ "libtess": "^1.2.2", "omggif": "^1.0.10", "pako": "^2.1.0", + "pixelmatch": "^7.1.0", "zod": "^3.23.8" }, "devDependencies": { @@ -8619,6 +8620,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pixelmatch": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-7.1.0.tgz", + "integrity": "sha512-1wrVzJ2STrpmONHKBy228LM1b84msXDUoAzVEl0R8Mz4Ce6EPr+IVtxm8+yvrqLYMHswREkjYFaMxnyGnaY3Ng==", + "dependencies": { + "pngjs": "^7.0.0" + }, + "bin": { + "pixelmatch": "bin/pixelmatch" + } + }, "node_modules/pkg-dir": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", @@ -8642,6 +8654,14 @@ "semver-compare": "^1.0.0" } }, + "node_modules/pngjs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz", + "integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==", + "engines": { + "node": ">=14.19.0" + } + }, "node_modules/postcss": { "version": "8.5.1", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz", diff --git a/package.json b/package.json index e34a8ef5c7..effe967822 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "libtess": "^1.2.2", "omggif": "^1.0.10", "pako": "^2.1.0", + "pixelmatch": "^7.1.0", "zod": "^3.23.8" }, "devDependencies": { diff --git a/test/unit/visual/visualTest.js b/test/unit/visual/visualTest.js index 068e8c7247..0883754ff1 100644 --- a/test/unit/visual/visualTest.js +++ b/test/unit/visual/visualTest.js @@ -2,6 +2,7 @@ import p5 from '../../../src/app.js'; import { server } from '@vitest/browser/context' import { THRESHOLD, DIFFERENCE, ERODE } from '../../../src/core/constants.js'; const { readFile, writeFile } = server.commands +import pixelmatch from 'pixelmatch'; // By how much can each color channel value (0-255) differ before // we call it a mismatch? This should be large enough to not trigger @@ -88,15 +89,12 @@ export function visualSuite( export async function checkMatch(actual, expected, p5) { let scale = Math.min(MAX_SIDE/expected.width, MAX_SIDE/expected.height); - - // Long screenshots end up super tiny when fit to a small square, so we - // can double the max side length for these const ratio = expected.width / expected.height; const narrow = ratio !== 1; if (narrow) { scale *= 2; } - + for (const img of [actual, expected]) { img.resize( Math.ceil(img.width * scale), @@ -104,39 +102,154 @@ export async function checkMatch(actual, expected, p5) { ); } - const expectedWithBg = p5.createGraphics(expected.width, expected.height); - expectedWithBg.pixelDensity(1); - expectedWithBg.background(BG); - expectedWithBg.image(expected, 0, 0); - - const cnv = p5.createGraphics(actual.width, actual.height); - cnv.pixelDensity(1); - cnv.background(BG); - cnv.image(actual, 0, 0); - cnv.blendMode(DIFFERENCE); - cnv.image(expectedWithBg, 0, 0); - for (let i = 0; i < shiftThreshold; i++) { - cnv.filter(ERODE, false); + // Ensure both images have the same dimensions + const width = expected.width; + const height = expected.height; + + // Create canvases with background color + const actualCanvas = p5.createGraphics(width, height); + const expectedCanvas = p5.createGraphics(width, height); + actualCanvas.pixelDensity(1); + expectedCanvas.pixelDensity(1); + + actualCanvas.background(BG); + expectedCanvas.background(BG); + + actualCanvas.image(actual, 0, 0); + expectedCanvas.image(expected, 0, 0); + + // Load pixel data + actualCanvas.loadPixels(); + expectedCanvas.loadPixels(); + + // Create diff output canvas + const diffCanvas = p5.createGraphics(width, height); + diffCanvas.pixelDensity(1); + diffCanvas.loadPixels(); + + // Run pixelmatch + const diffCount = pixelmatch( + actualCanvas.pixels, + expectedCanvas.pixels, + diffCanvas.pixels, + width, + height, + { + threshold: 0.3, + includeAA: false, + alpha: 0.1 + } + ); + + // If no differences, return early + if (diffCount === 0) { + actualCanvas.remove(); + expectedCanvas.remove(); + diffCanvas.updatePixels(); + return { ok: true, diff: diffCanvas }; } - const diff = cnv.get(); - cnv.remove(); - diff.loadPixels(); - expectedWithBg.remove(); + + // Post-process to identify and filter out isolated differences + const visited = new Set(); + const clusterSizes = []; + + for (let y = 0; y < height; y++) { + for (let x = 0; x < width; x++) { + const pos = (y * width + x) * 4; + + // If this is a diff pixel (red in pixelmatch output) and not yet visited + if ( + diffCanvas.pixels[pos] === 255 && + diffCanvas.pixels[pos + 1] === 0 && + diffCanvas.pixels[pos + 2] === 0 && + !visited.has(pos) + ) { + // Find the connected cluster size using BFS + const clusterSize = findClusterSize(diffCanvas.pixels, x, y, width, height, 1, visited); + clusterSizes.push(clusterSize); + } + } + } + + // Define significance thresholds + const MIN_CLUSTER_SIZE = 4; // Minimum pixels in a significant cluster + const MAX_TOTAL_DIFF_PIXELS = 40; // Maximum total different pixels + + // Determine if the differences are significant + const significantClusters = clusterSizes.filter(size => size >= MIN_CLUSTER_SIZE); + const significantDiffPixels = significantClusters.reduce((sum, size) => sum + size, 0); - let ok = true; - for (let i = 0; i < diff.pixels.length; i += 4) { - let diffSum = 0; - for (let off = 0; off < 3; off++) { - diffSum += diff.pixels[i+off] + // Update the diff canvas + diffCanvas.updatePixels(); + + // Clean up canvases + actualCanvas.remove(); + expectedCanvas.remove(); + + // Determine test result + const ok = ( + diffCount === 0 || // No differences at all + ( + significantDiffPixels === 0 || // No significant clusters + ( + significantDiffPixels <= MAX_TOTAL_DIFF_PIXELS && // Total different pixels within tolerance + significantClusters.length <= 2 // Not too many significant clusters + ) + ) + ); + + return { + ok, + diff: diffCanvas, + details: { + totalDiffPixels: diffCount, + significantDiffPixels, + clusters: clusterSizes, + significantClusters } - diffSum /= 3; - if (diffSum > COLOR_THRESHOLD) { - ok = false; - break; + }; +} + +/** + * Find the size of a connected cluster of diff pixels using BFS + */ +function findClusterSize(pixels, startX, startY, width, height, radius, visited) { + const queue = [{x: startX, y: startY}]; + let size = 0; + + while (queue.length > 0) { + const {x, y} = queue.shift(); + const pos = (y * width + x) * 4; + + // Skip if already visited + if (visited.has(pos)) continue; + + // Skip if not a diff pixel + if (pixels[pos] !== 255 || pixels[pos + 1] !== 0 || pixels[pos + 2] !== 0) continue; + + // Mark as visited + visited.add(pos); + size++; + + // Add neighbors to queue + for (let dy = -radius; dy <= radius; dy++) { + for (let dx = -radius; dx <= radius; dx++) { + const nx = x + dx; + const ny = y + dy; + + // Skip if out of bounds + if (nx < 0 || nx >= width || ny < 0 || ny >= height) continue; + + // Skip if already visited + const npos = (ny * width + nx) * 4; + if (!visited.has(npos)) { + queue.push({x: nx, y: ny}); + } + } } } - - return { ok, diff }; + + return size; } /** From 8f50108ca23b05e38ee3647f9c3d05d05fa9738d Mon Sep 17 00:00:00 2001 From: Vaivaswat Date: Wed, 5 Mar 2025 02:34:43 +0530 Subject: [PATCH 06/10] test commit for checking CI breakages in higher tolerance thresholds of pixelmatch --- test/unit/visual/visualTest.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/visual/visualTest.js b/test/unit/visual/visualTest.js index 0883754ff1..fad463ddeb 100644 --- a/test/unit/visual/visualTest.js +++ b/test/unit/visual/visualTest.js @@ -135,7 +135,7 @@ export async function checkMatch(actual, expected, p5) { width, height, { - threshold: 0.3, + threshold: 0.6, includeAA: false, alpha: 0.1 } From 71ebd2ddba0fb003cee7690a0285fb58b5a7894f Mon Sep 17 00:00:00 2001 From: Vaivaswat Date: Fri, 7 Mar 2025 03:42:43 +0530 Subject: [PATCH 07/10] tried to fix environmental shifting --- test/unit/visual/visualTest.js | 66 ++++++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/test/unit/visual/visualTest.js b/test/unit/visual/visualTest.js index fad463ddeb..042097912e 100644 --- a/test/unit/visual/visualTest.js +++ b/test/unit/visual/visualTest.js @@ -135,7 +135,7 @@ export async function checkMatch(actual, expected, p5) { width, height, { - threshold: 0.6, + threshold: 0.35, includeAA: false, alpha: 0.1 } @@ -174,10 +174,15 @@ export async function checkMatch(actual, expected, p5) { // Define significance thresholds const MIN_CLUSTER_SIZE = 4; // Minimum pixels in a significant cluster const MAX_TOTAL_DIFF_PIXELS = 40; // Maximum total different pixels + const MAX_LINE_SHIFT_PIXELS = 100; // Determine if the differences are significant - const significantClusters = clusterSizes.filter(size => size >= MIN_CLUSTER_SIZE); - const significantDiffPixels = significantClusters.reduce((sum, size) => sum + size, 0); + const lineShiftClusters = clusterSizes.filter(c => c.isLineShift && c.size > MIN_CLUSTER_SIZE); + const nonLineShiftClusters = clusterSizes.filter(c => !c.isLineShift && c.size >= MIN_CLUSTER_SIZE); + + // Calculate significant differences excluding line shifts + const significantDiffPixels = nonLineShiftClusters.reduce((sum, c) => sum + c.size, 0); + const lineShiftPixels = lineShiftClusters.reduce((sum, c) => sum + c.size, 0); // Update the diff canvas diffCanvas.updatePixels(); @@ -188,12 +193,12 @@ export async function checkMatch(actual, expected, p5) { // Determine test result const ok = ( - diffCount === 0 || // No differences at all + diffCount === 0 || ( - significantDiffPixels === 0 || // No significant clusters + significantDiffPixels === 0 || ( - significantDiffPixels <= MAX_TOTAL_DIFF_PIXELS && // Total different pixels within tolerance - significantClusters.length <= 2 // Not too many significant clusters + (significantDiffPixels <= MAX_TOTAL_DIFF_PIXELS) && + (nonLineShiftClusters.length <= 2) // Not too many significant clusters ) ) ); @@ -204,8 +209,7 @@ export async function checkMatch(actual, expected, p5) { details: { totalDiffPixels: diffCount, significantDiffPixels, - clusters: clusterSizes, - significantClusters + clusters: clusterSizes } }; } @@ -216,6 +220,7 @@ export async function checkMatch(actual, expected, p5) { function findClusterSize(pixels, startX, startY, width, height, radius, visited) { const queue = [{x: startX, y: startY}]; let size = 0; + const clusterPixels = []; while (queue.length > 0) { const {x, y} = queue.shift(); @@ -230,6 +235,7 @@ function findClusterSize(pixels, startX, startY, width, height, radius, visited) // Mark as visited visited.add(pos); size++; + clusterPixels.push({x, y}); // Add neighbors to queue for (let dy = -radius; dy <= radius; dy++) { @@ -248,8 +254,48 @@ function findClusterSize(pixels, startX, startY, width, height, radius, visited) } } } + + let isLineShift = false; + if (clusterPixels.length > 0) { + // Count pixels with limited neighbors (line-like characteristic) + let linelikePixels = 0; + + for (const {x, y} of clusterPixels) { + // Count neighbors + let neighbors = 0; + for (let dy = -1; dy <= 1; dy++) { + for (let dx = -1; dx <= 1; dx++) { + if (dx === 0 && dy === 0) continue; // Skip self + + const nx = x + dx; + const ny = y + dy; + + // Skip if out of bounds + if (nx < 0 || nx >= width || ny < 0 || ny >= height) continue; + + const npos = (ny * width + nx) * 4; + // Check if neighbor is a diff pixel + if (pixels[npos] === 255 && pixels[npos + 1] === 0 && pixels[npos + 2] === 0) { + neighbors++; + } + } + } + + // Line-like pixels typically have 1-2 neighbors + if (neighbors <= 2) { + linelikePixels++; + } + } + + // If most pixels (>80%) in the cluster have ≤2 neighbors, it's likely a line shift + isLineShift = linelikePixels / clusterPixels.length > 0.8; + } - return size; + return { + size, + pixels: clusterPixels, + isLineShift + }; } /** From 7ec24f5b359d6ce7535ab1ffc244e1d764e0ce91 Mon Sep 17 00:00:00 2001 From: Vaivaswat Date: Fri, 7 Mar 2025 09:34:11 +0530 Subject: [PATCH 08/10] back to more tolerant for checks --- test/unit/visual/visualTest.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/unit/visual/visualTest.js b/test/unit/visual/visualTest.js index 042097912e..4a7b1da7f1 100644 --- a/test/unit/visual/visualTest.js +++ b/test/unit/visual/visualTest.js @@ -135,7 +135,7 @@ export async function checkMatch(actual, expected, p5) { width, height, { - threshold: 0.35, + threshold: 0.6, includeAA: false, alpha: 0.1 } @@ -174,7 +174,7 @@ export async function checkMatch(actual, expected, p5) { // Define significance thresholds const MIN_CLUSTER_SIZE = 4; // Minimum pixels in a significant cluster const MAX_TOTAL_DIFF_PIXELS = 40; // Maximum total different pixels - const MAX_LINE_SHIFT_PIXELS = 100; + const MAX_LINE_SHIFT_PIXELS = 200; // Determine if the differences are significant const lineShiftClusters = clusterSizes.filter(c => c.isLineShift && c.size > MIN_CLUSTER_SIZE); @@ -290,7 +290,6 @@ function findClusterSize(pixels, startX, startY, width, height, radius, visited) // If most pixels (>80%) in the cluster have ≤2 neighbors, it's likely a line shift isLineShift = linelikePixels / clusterPixels.length > 0.8; } - return { size, pixels: clusterPixels, From a9f909bc686997df63832ad5b55453c33bdf1f3f Mon Sep 17 00:00:00 2001 From: Vaivaswat Date: Fri, 7 Mar 2025 11:53:21 +0530 Subject: [PATCH 09/10] updated threshold for tests --- test/unit/visual/visualTest.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/unit/visual/visualTest.js b/test/unit/visual/visualTest.js index 4a7b1da7f1..234f916e29 100644 --- a/test/unit/visual/visualTest.js +++ b/test/unit/visual/visualTest.js @@ -135,7 +135,7 @@ export async function checkMatch(actual, expected, p5) { width, height, { - threshold: 0.6, + threshold: 0.5, includeAA: false, alpha: 0.1 } @@ -290,6 +290,7 @@ function findClusterSize(pixels, startX, startY, width, height, radius, visited) // If most pixels (>80%) in the cluster have ≤2 neighbors, it's likely a line shift isLineShift = linelikePixels / clusterPixels.length > 0.8; } + return { size, pixels: clusterPixels, From dc4ed3f651821f7ae30bba4fbd4e0b92482413c3 Mon Sep 17 00:00:00 2001 From: Vaivaswat Date: Sat, 8 Mar 2025 09:32:56 +0530 Subject: [PATCH 10/10] Added docs and removed unnecessary code --- test/unit/visual/visualTest.js | 49 +++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/test/unit/visual/visualTest.js b/test/unit/visual/visualTest.js index 234f916e29..120ce79565 100644 --- a/test/unit/visual/visualTest.js +++ b/test/unit/visual/visualTest.js @@ -87,6 +87,52 @@ export function visualSuite( }); } +/** + * Image Diff Algorithm for p5.js Visual Tests + * + * This algorithm addresses the challenge of cross-platform rendering differences in p5.js visual tests. + * Different operating systems and browsers render graphics with subtle variations, particularly with + * anti-aliasing, text rendering, and sub-pixel positioning. This can cause false negatives in tests + * when the visual differences are acceptable rendering variations rather than actual bugs. + * + * Key components of the approach: + * + * 1. Initial pixel-by-pixel comparison: + * - Uses pixelmatch to identify differences between expected and actual images + * - Sets a moderate threshold (0.5) to filter out minor color/intensity variations + * - Produces a diff image with red pixels marking differences + * + * 2. Cluster identification using BFS (Breadth-First Search): + * - Groups connected difference pixels into clusters + * - Uses a queue-based BFS algorithm to find all connected pixels + * - Defines connectivity based on 8-way adjacency (all surrounding pixels) + * + * 3. Cluster categorization by type: + * - Analyzes each pixel's neighborhood characteristics + * - Specifically identifies "line shift" clusters - differences that likely represent + * the same visual elements shifted by 1px due to platform rendering differences + * - Line shifts are identified when >80% of pixels in a cluster have ≤2 neighboring diff pixels + * + * 4. Intelligent failure criteria: + * - Filters out clusters smaller than MIN_CLUSTER_SIZE pixels (noise reduction) + * - Applies different thresholds for regular differences vs. line shifts + * - Considers both the total number of significant pixels and number of distinct clusters + * + * This approach balances the need to catch genuine visual bugs (like changes to shape geometry, + * colors, or positioning) while tolerating acceptable cross-platform rendering variations. + * + * Parameters: + * - MIN_CLUSTER_SIZE: Minimum size for a cluster to be considered significant (default: 4) + * - MAX_TOTAL_DIFF_PIXELS: Maximum allowed non-line-shift difference pixels (default: 40) + * Note: These can be adjusted for further updation + * + * Note for contributors: When running tests locally, you may not see these differences as they + * mainly appear when tests run on different operating systems or browser rendering engines. + * However, the same code may produce slightly different renderings on CI environments, particularly + * with text positioning, thin lines, or curved shapes. This algorithm helps distinguish between + * these acceptable variations and actual visual bugs. + */ + export async function checkMatch(actual, expected, p5) { let scale = Math.min(MAX_SIDE/expected.width, MAX_SIDE/expected.height); const ratio = expected.width / expected.height; @@ -174,15 +220,12 @@ export async function checkMatch(actual, expected, p5) { // Define significance thresholds const MIN_CLUSTER_SIZE = 4; // Minimum pixels in a significant cluster const MAX_TOTAL_DIFF_PIXELS = 40; // Maximum total different pixels - const MAX_LINE_SHIFT_PIXELS = 200; // Determine if the differences are significant - const lineShiftClusters = clusterSizes.filter(c => c.isLineShift && c.size > MIN_CLUSTER_SIZE); const nonLineShiftClusters = clusterSizes.filter(c => !c.isLineShift && c.size >= MIN_CLUSTER_SIZE); // Calculate significant differences excluding line shifts const significantDiffPixels = nonLineShiftClusters.reduce((sum, c) => sum + c.size, 0); - const lineShiftPixels = lineShiftClusters.reduce((sum, c) => sum + c.size, 0); // Update the diff canvas diffCanvas.updatePixels();