RegionTests.cs 71 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147
  1. namespace Terminal.Gui.DrawingTests;
  2. public class RegionTests
  3. {
  4. [Fact]
  5. public void Constructor_EmptyRegion_IsEmpty ()
  6. {
  7. var region = new Region ();
  8. Assert.True (region.IsEmpty ());
  9. }
  10. [Fact]
  11. public void Constructor_WithRectangle_IsNotEmpty ()
  12. {
  13. var region = new Region (new Rectangle (10, 10, 50, 50));
  14. Assert.False (region.IsEmpty ());
  15. }
  16. [Fact]
  17. public void Union_Rectangle_AddsToRegion ()
  18. {
  19. var region = new Region ();
  20. region.Union (new Rectangle (10, 10, 50, 50));
  21. Assert.False (region.IsEmpty ());
  22. Assert.True (region.Contains (20, 20));
  23. }
  24. [Fact]
  25. public void Union_Region_MergesRegions ()
  26. {
  27. var region1 = new Region (new Rectangle (10, 10, 50, 50));
  28. var region2 = new Region (new Rectangle (30, 30, 50, 50));
  29. region1.Union (region2);
  30. Assert.True (region1.Contains (20, 20));
  31. Assert.True (region1.Contains (40, 40));
  32. }
  33. [Fact]
  34. public void Intersect_Rectangle_IntersectsRegion ()
  35. {
  36. var region = new Region (new Rectangle (10, 10, 50, 50));
  37. region.Intersect (new Rectangle (30, 30, 50, 50));
  38. Assert.False (region.Contains (20, 20));
  39. Assert.True (region.Contains (40, 40));
  40. }
  41. [Fact]
  42. public void Intersect_Region_IntersectsRegions ()
  43. {
  44. var region1 = new Region (new Rectangle (10, 10, 50, 50));
  45. var region2 = new Region (new Rectangle (30, 30, 50, 50));
  46. region1.Intersect (region2);
  47. Assert.False (region1.Contains (20, 20));
  48. Assert.True (region1.Contains (40, 40));
  49. }
  50. [Fact]
  51. public void Exclude_Rectangle_ExcludesFromRegion ()
  52. {
  53. var region = new Region (new Rectangle (10, 10, 50, 50));
  54. region.Exclude (new Rectangle (20, 20, 20, 20));
  55. Assert.False (region.Contains (25, 25));
  56. Assert.True (region.Contains (15, 15));
  57. }
  58. [Fact]
  59. public void Exclude_Region_ExcludesRegions ()
  60. {
  61. var region1 = new Region (new Rectangle (10, 10, 50, 50));
  62. var region2 = new Region (new Rectangle (20, 20, 20, 20));
  63. region1.Exclude (region2);
  64. Assert.False (region1.Contains (25, 25));
  65. Assert.True (region1.Contains (15, 15));
  66. }
  67. [Fact]
  68. public void Complement_Rectangle_ComplementsRegion ()
  69. {
  70. var region = new Region (new Rectangle (10, 10, 50, 50));
  71. region.Complement (new Rectangle (0, 0, 100, 100));
  72. Assert.True (region.Contains (5, 5));
  73. Assert.False (region.Contains (20, 20));
  74. }
  75. [Fact]
  76. public void Clone_CreatesExactCopy ()
  77. {
  78. var region = new Region (new Rectangle (10, 10, 50, 50));
  79. var clone = region.Clone ();
  80. Assert.True (clone.Contains (20, 20));
  81. Assert.Equal (region.GetRegionScans (), clone.GetRegionScans ());
  82. }
  83. [Fact]
  84. public void GetBounds_ReturnsBoundingRectangle ()
  85. {
  86. var region = new Region (new Rectangle (10, 10, 50, 50));
  87. region.Union (new Rectangle (100, 100, 20, 20));
  88. var bounds = region.GetBounds ();
  89. Assert.Equal (new Rectangle (10, 10, 110, 110), bounds);
  90. }
  91. [Fact]
  92. public void IsEmpty_EmptyRegion_ReturnsTrue ()
  93. {
  94. var region = new Region ();
  95. Assert.True (region.IsEmpty ());
  96. }
  97. [Fact]
  98. public void Contains_PointInsideRegion_ReturnsTrue ()
  99. {
  100. var region = new Region (new Rectangle (10, 10, 50, 50));
  101. Assert.True (region.Contains (20, 20));
  102. }
  103. [Fact]
  104. public void Contains_RectangleInsideRegion_ReturnsTrue ()
  105. {
  106. var region = new Region (new Rectangle (10, 10, 50, 50));
  107. Assert.True (region.Contains (new Rectangle (20, 20, 10, 10)));
  108. }
  109. [Fact]
  110. public void GetRegionScans_ReturnsAllRectangles ()
  111. {
  112. var region = new Region (new Rectangle (10, 10, 50, 50));
  113. region.Union (new Rectangle (100, 100, 20, 20));
  114. var scans = region.GetRegionScans ();
  115. Assert.Equal (2, scans.Length);
  116. Assert.Contains (new Rectangle (10, 10, 50, 50), scans);
  117. Assert.Contains (new Rectangle (100, 100, 20, 20), scans);
  118. }
  119. [Fact]
  120. public void Union_WithRectangle_AddsRectangle ()
  121. {
  122. var region = new Region ();
  123. var rect = new Rectangle (10, 10, 50, 50);
  124. region.Union (rect);
  125. Assert.True (region.Contains (20, 20));
  126. Assert.False (region.Contains (100, 100));
  127. }
  128. [Fact]
  129. public void Intersect_WithRectangle_IntersectsRectangles ()
  130. {
  131. var region = new Region (new (10, 10, 50, 50));
  132. var rect = new Rectangle (30, 30, 50, 50);
  133. region.Intersect (rect);
  134. Assert.True (region.Contains (35, 35));
  135. Assert.False (region.Contains (20, 20));
  136. }
  137. [Fact]
  138. public void Exclude_WithRectangle_ExcludesRectangle ()
  139. {
  140. var region = new Region (new (10, 10, 50, 50));
  141. var rect = new Rectangle (30, 30, 50, 50);
  142. region.Exclude (rect);
  143. Assert.True (region.Contains (20, 20));
  144. Assert.False (region.Contains (35, 35));
  145. }
  146. [Fact]
  147. public void Contains_Point_ReturnsCorrectResult ()
  148. {
  149. var region = new Region (new (10, 10, 50, 50));
  150. Assert.True (region.Contains (20, 20));
  151. Assert.False (region.Contains (100, 100));
  152. }
  153. [Fact]
  154. public void IsEmpty_ReturnsCorrectResult ()
  155. {
  156. var region = new Region ();
  157. Assert.True (region.IsEmpty ());
  158. region.Union (new Rectangle(10, 10, 50, 50));
  159. Assert.False (region.IsEmpty ());
  160. }
  161. [Fact]
  162. public void GetBounds_ReturnsCorrectBounds ()
  163. {
  164. var region = new Region ();
  165. region.Union (new Rectangle (10, 10, 50, 50));
  166. region.Union (new Rectangle (30, 30, 50, 50));
  167. Rectangle bounds = region.GetBounds ();
  168. Assert.Equal (new (10, 10, 70, 70), bounds);
  169. }
  170. [Fact]
  171. public void Dispose_ClearsRectangles ()
  172. {
  173. var region = new Region (new (10, 10, 50, 50));
  174. region.Dispose ();
  175. Assert.True (region.IsEmpty ());
  176. }
  177. [Fact]
  178. public void Union_WithRegion_AddsRegion ()
  179. {
  180. var region1 = new Region (new (10, 10, 50, 50));
  181. var region2 = new Region (new (30, 30, 50, 50));
  182. region1.Union (region2.GetBounds ());
  183. Assert.True (region1.Contains (20, 20));
  184. Assert.True (region1.Contains (40, 40));
  185. }
  186. [Fact]
  187. public void Intersect_WithRegion_IntersectsRegions ()
  188. {
  189. var region1 = new Region (new (10, 10, 50, 50));
  190. var region2 = new Region (new (30, 30, 50, 50));
  191. region1.Intersect (region2.GetBounds ());
  192. Assert.True (region1.Contains (35, 35));
  193. Assert.False (region1.Contains (20, 20));
  194. }
  195. [Fact]
  196. public void Exclude_WithRegion_ExcludesRegion ()
  197. {
  198. var region1 = new Region (new (10, 10, 50, 50));
  199. var region2 = new Region (new (30, 30, 50, 50));
  200. region1.Exclude (region2.GetBounds ());
  201. Assert.True (region1.Contains (20, 20));
  202. Assert.False (region1.Contains (35, 35));
  203. }
  204. //[Fact]
  205. //public void Complement_WithRectangle_ComplementsRegion ()
  206. //{
  207. // var region = new Region (new (10, 10, 50, 50));
  208. // var rect = new Rectangle (30, 30, 50, 50);
  209. // region.Complement (rect);
  210. // Assert.True (region.Contains (35, 35));
  211. // Assert.False (region.Contains (20, 20));
  212. //}
  213. //[Fact]
  214. //public void Complement_WithRegion_ComplementsRegion ()
  215. //{
  216. // var region1 = new Region (new (10, 10, 50, 50));
  217. // var region2 = new Region (new (30, 30, 50, 50));
  218. // region1.Complement (region2.GetBounds ());
  219. // Assert.True (region1.Contains (35, 35));
  220. // Assert.False (region1.Contains (20, 20));
  221. //}
  222. private static Region CreateDisposedRegion ()
  223. {
  224. Region region = new ();
  225. region.Dispose ();
  226. return region;
  227. }
  228. public static IEnumerable<object []> Region_TestData ()
  229. {
  230. yield return new object [] { new Region () };
  231. yield return new object [] { new Region (new Rectangle (0, 0, 0, 0)) };
  232. yield return new object [] { new Region (new Rectangle (1, 2, 3, 4)) };
  233. }
  234. public static IEnumerable<object []> Complement_TestData ()
  235. {
  236. yield return new object []
  237. {
  238. new Region (new Rectangle (10, 10, 100, 100)),
  239. new Rectangle [] { new (40, 60, 100, 20) },
  240. new Rectangle [] { new (110, 60, 30, 20) }
  241. };
  242. yield return new object []
  243. {
  244. new Region (new Rectangle (70, 10, 100, 100)),
  245. new Rectangle [] { new (40, 60, 100, 20) },
  246. new Rectangle [] { new (40, 60, 30, 20) }
  247. };
  248. yield return new object []
  249. {
  250. new Region (new Rectangle (40, 100, 100, 100)),
  251. new Rectangle [] { new (70, 80, 50, 40) },
  252. new Rectangle [] { new (70, 80, 50, 20) }
  253. };
  254. yield return new object []
  255. {
  256. new Region (new Rectangle (40, 10, 100, 100)),
  257. new Rectangle [] { new (70, 80, 50, 40) },
  258. new Rectangle [] { new (70, 110, 50, 10) }
  259. };
  260. yield return new object []
  261. {
  262. new Region (new Rectangle (30, 30, 80, 80)),
  263. new Rectangle []
  264. {
  265. new (45, 45, 200, 200),
  266. new (160, 260, 10, 10),
  267. new (170, 260, 10, 10),
  268. },
  269. new Rectangle [] { new (170, 260, 10, 10) }
  270. };
  271. yield return new object []
  272. {
  273. new Region (),
  274. new Rectangle [] { Rectangle.Empty },
  275. new Rectangle[0]
  276. };
  277. yield return new object []
  278. {
  279. new Region (),
  280. new Rectangle [] { new (1, 2, 3, 4) },
  281. new Rectangle[0]
  282. };
  283. }
  284. [Theory]
  285. [MemberData (nameof (Complement_TestData))]
  286. public void Complement_Region_Success (Region region, Rectangle [] rectangles, Rectangle [] expectedScans)
  287. {
  288. using (region)
  289. {
  290. foreach (Rectangle rect in rectangles)
  291. {
  292. region.Complement (rect);
  293. }
  294. var actualScans = region.GetRegionScans ();
  295. Assert.Equal (expectedScans, actualScans);
  296. }
  297. }
  298. }
  299. #if x
  300. [Fact]
  301. public void Complement_UnionRegion_Success ()
  302. {
  303. using Region region = new (new Rectangle (20, 20, 20, 20));
  304. using Region other = new (new Rectangle (20, 80, 20, 10));
  305. using Matrix matrix = new ();
  306. other.Union (new Rectangle (60, 60, 30, 10));
  307. region.Complement (other);
  308. Assert.Equal (
  309. [
  310. new (60, 60, 30, 10),
  311. new (20, 80, 20, 10)
  312. ],
  313. region.GetRegionScans (matrix));
  314. }
  315. [Fact]
  316. public void Complement_InfiniteAndWithIntersectRegion_Success ()
  317. {
  318. using Region region = new ();
  319. using Matrix matrix = new ();
  320. region.Intersect (new Rectangle (5, 5, -10, -10));
  321. region.Complement (new Rectangle (-5, -5, 12, 12));
  322. Assert.False (region.IsEmpty (s_graphic));
  323. Assert.False (region.IsInfinite (s_graphic));
  324. Assert.Equal (
  325. [
  326. new (5, -5, 2, 10),
  327. new (-5, 5, 12, 2)
  328. ],
  329. region.GetRegionScans (matrix));
  330. }
  331. [Fact]
  332. public void Complement_InfiniteRegion_Success ()
  333. {
  334. using Region region = new (new Rectangle (1, 2, 3, 4));
  335. using Matrix matrix = new ();
  336. using Region other = new ();
  337. region.Complement (other);
  338. Assert.Equal (
  339. [
  340. new (-4194304, -4194304, 8388608, 4194306),
  341. new (-4194304, 2, 4194305, 4),
  342. new (4, 2, 4194300, 4),
  343. new (-4194304, 6, 8388608, 4194298)
  344. ],
  345. region.GetRegionScans (matrix));
  346. }
  347. [Fact]
  348. public void Complement_NullRegion_ThrowsArgumentNullException ()
  349. {
  350. using Region region = new ();
  351. Assert.Throws<ArgumentNullException> ("region", () => region.Complement ((Region)null));
  352. }
  353. [Fact]
  354. public void Complement_SameRegion_ThrowsInvalidOperationException ()
  355. {
  356. using Region region = new ();
  357. Assert.Throws<InvalidOperationException> (() => region.Complement (region));
  358. }
  359. [Theory]
  360. [MemberData (nameof (Complement_TestData))]
  361. public void Complement_Rectangle_Success (Region region, RectangleF [] rectangles, RectangleF [] expectedScans)
  362. {
  363. using (region)
  364. {
  365. foreach (RectangleF rect in rectangles)
  366. {
  367. region.Complement (new Rectangle ((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height));
  368. }
  369. using Matrix matrix = new ();
  370. Assert.Equal (expectedScans, region.GetRegionScans (matrix));
  371. }
  372. }
  373. [Theory]
  374. [MemberData (nameof (Complement_TestData))]
  375. public void Complement_RectangleF_Success (Region region, RectangleF [] rectangles, RectangleF [] expectedScans)
  376. {
  377. using (region)
  378. {
  379. foreach (RectangleF rect in rectangles)
  380. {
  381. region.Complement (rect);
  382. }
  383. using Matrix matrix = new ();
  384. Assert.Equal (expectedScans, region.GetRegionScans (matrix));
  385. }
  386. }
  387. [Theory]
  388. [MemberData (nameof (Complement_TestData))]
  389. public void Complement_GraphicsPath_Success (Region region, RectangleF [] rectangles, RectangleF [] expectedScans)
  390. {
  391. using (region)
  392. {
  393. foreach (RectangleF rect in rectangles)
  394. {
  395. using GraphicsPath path = new ();
  396. path.AddRectangle (rect);
  397. region.Complement (path);
  398. }
  399. using Matrix matrix = new ();
  400. Assert.Equal (expectedScans, region.GetRegionScans (matrix));
  401. }
  402. }
  403. [Fact]
  404. public void Complement_GraphicsPathWithMultipleRectangles_Success ()
  405. {
  406. Rectangle rect1 = new (20, 30, 60, 80);
  407. Rectangle rect2 = new (50, 40, 60, 80);
  408. using Graphics graphics = Graphics.FromImage (new Bitmap (600, 800));
  409. using Region region1 = new (rect1);
  410. using Region region2 = new (rect2);
  411. using Matrix matrix = new ();
  412. graphics.DrawRectangle (Pens.Green, rect1);
  413. graphics.DrawRectangle (Pens.Red, rect2);
  414. region1.Complement (region2);
  415. graphics.FillRegion (Brushes.Blue, region1);
  416. graphics.DrawRectangles (Pens.Yellow, region1.GetRegionScans (matrix));
  417. Assert.Equal (
  418. [
  419. new (80, 40, 30, 70),
  420. new (50, 110, 60, 10)
  421. ],
  422. region1.GetRegionScans (matrix));
  423. }
  424. public static IEnumerable<object []> Equals_TestData ()
  425. {
  426. static Region Empty ()
  427. {
  428. Region emptyRegion = new ();
  429. emptyRegion.MakeEmpty ();
  430. return emptyRegion;
  431. }
  432. Region createdRegion = new ();
  433. yield return new object [] { createdRegion, createdRegion, true };
  434. yield return new object [] { new Region (), new Region (), true };
  435. yield return new object [] { new Region (), Empty (), false };
  436. yield return new object [] { new Region (), new Region (new Rectangle (1, 2, 3, 4)), false };
  437. yield return new object [] { Empty (), Empty (), true };
  438. yield return new object [] { Empty (), new Region (new Rectangle (0, 0, 0, 0)), true };
  439. yield return new object [] { Empty (), new Region (new Rectangle (1, 2, 3, 3)), false };
  440. yield return new object [] { new Region (new Rectangle (1, 2, 3, 4)), new Region (new Rectangle (1, 2, 3, 4)), true };
  441. yield return new object [] { new Region (new Rectangle (1, 2, 3, 4)), new Region (new RectangleF (1, 2, 3, 4)), true };
  442. yield return new object [] { new Region (new Rectangle (1, 2, 3, 4)), new Region (new Rectangle (2, 2, 3, 4)), false };
  443. yield return new object [] { new Region (new Rectangle (1, 2, 3, 4)), new Region (new Rectangle (1, 3, 3, 4)), false };
  444. yield return new object [] { new Region (new Rectangle (1, 2, 3, 4)), new Region (new Rectangle (1, 2, 4, 4)), false };
  445. yield return new object [] { new Region (new Rectangle (1, 2, 3, 4)), new Region (new Rectangle (1, 2, 3, 5)), false };
  446. GraphicsPath graphics1 = new ();
  447. graphics1.AddRectangle (new Rectangle (1, 2, 3, 4));
  448. GraphicsPath graphics2 = new ();
  449. graphics2.AddRectangle (new Rectangle (1, 2, 3, 4));
  450. GraphicsPath graphics3 = new ();
  451. graphics3.AddRectangle (new Rectangle (2, 2, 3, 4));
  452. GraphicsPath graphics4 = new ();
  453. graphics4.AddRectangle (new Rectangle (1, 3, 3, 4));
  454. GraphicsPath graphics5 = new ();
  455. graphics5.AddRectangle (new Rectangle (1, 2, 4, 4));
  456. GraphicsPath graphics6 = new ();
  457. graphics6.AddRectangle (new Rectangle (1, 2, 3, 5));
  458. yield return new object [] { new Region (graphics1), new Region (graphics1), true };
  459. yield return new object [] { new Region (graphics1), new Region (graphics2), true };
  460. yield return new object [] { new Region (graphics1), new Region (graphics3), false };
  461. yield return new object [] { new Region (graphics1), new Region (graphics4), false };
  462. yield return new object [] { new Region (graphics1), new Region (graphics5), false };
  463. yield return new object [] { new Region (graphics1), new Region (graphics6), false };
  464. }
  465. [Theory]
  466. [MemberData (nameof (Equals_TestData))]
  467. public void Equals_Valid_ReturnsExpected (Region region, Region other, bool expected)
  468. {
  469. using (region)
  470. using (other)
  471. {
  472. Assert.Equal (expected, region.Equals (other, s_graphic));
  473. }
  474. }
  475. [Fact]
  476. public void Equals_NullRegion_ThrowsArgumentNullException ()
  477. {
  478. using Region region = new ();
  479. Assert.Throws<ArgumentNullException> ("region", () => region.Equals (null, s_graphic));
  480. }
  481. [Fact]
  482. public void Equals_NullGraphics_ThrowsArgumentNullException ()
  483. {
  484. using Region region = new ();
  485. Assert.Throws<ArgumentNullException> ("g", () => region.Equals (region, null));
  486. }
  487. [Fact]
  488. public void Equals_DisposedGraphics_ThrowsArgumentException ()
  489. {
  490. using Region region = new ();
  491. using Region other = new ();
  492. using Bitmap image = new (10, 10);
  493. var graphics = Graphics.FromImage (image);
  494. graphics.Dispose ();
  495. Assert.Throws<ArgumentException> (null, () => region.Equals (region, graphics));
  496. }
  497. [Fact]
  498. public void Equals_Disposed_ThrowsArgumentException ()
  499. {
  500. Region disposedRegion = CreateDisposedRegion ();
  501. Assert.Throws<ArgumentException> (null, () => disposedRegion.Equals (new Region (), s_graphic));
  502. Assert.Throws<ArgumentException> (null, () => new Region ().Equals (disposedRegion, s_graphic));
  503. }
  504. public static IEnumerable<object []> Exclude_TestData ()
  505. {
  506. yield return new object []
  507. {
  508. new Region (new Rectangle (500, 30, 60, 80)),
  509. new RectangleF [] { new (500, 30, 60, 80) },
  510. new RectangleF[0]
  511. };
  512. yield return new object []
  513. {
  514. new Region (new Rectangle (500, 30, 60, 80)),
  515. new RectangleF [] { RectangleF.Empty },
  516. new RectangleF [] { new (500, 30, 60, 80) }
  517. };
  518. yield return new object []
  519. {
  520. new Region (),
  521. new RectangleF [] { new (520, 40, 60, 80) },
  522. new RectangleF []
  523. {
  524. new (-4194304, -4194304, 8388608, 4194344),
  525. new (-4194304, 40, 4194824, 80),
  526. new (580, 40, 4193724, 80),
  527. new (-4194304, 120, 8388608, 4194184)
  528. }
  529. };
  530. yield return new object []
  531. {
  532. new Region (),
  533. new RectangleF [] { RectangleF.Empty },
  534. new RectangleF [] { new Rectangle (-4194304, -4194304, 8388608, 8388608) }
  535. };
  536. // Intersecting from the right.
  537. yield return new object []
  538. {
  539. new Region (new Rectangle (10, 10, 100, 100)),
  540. new RectangleF [] { new (40, 60, 100, 20) },
  541. new RectangleF []
  542. {
  543. new (10, 10, 100, 50),
  544. new (10, 60, 30, 20),
  545. new (10, 80, 100, 30)
  546. }
  547. };
  548. // Intersecting from the left.
  549. yield return new object []
  550. {
  551. new Region (new Rectangle (70, 10, 100, 100)),
  552. new RectangleF [] { new (40, 60, 100, 20) },
  553. new RectangleF []
  554. {
  555. new (70, 10, 100, 50),
  556. new (140, 60, 30, 20),
  557. new (70, 80, 100, 30)
  558. }
  559. };
  560. // Intersecting from the top.
  561. yield return new object []
  562. {
  563. new Region (new Rectangle (40, 100, 100, 100)),
  564. new RectangleF [] { new (70, 80, 50, 40) },
  565. new RectangleF []
  566. {
  567. new (40, 100, 30, 20),
  568. new (120, 100, 20, 20),
  569. new (40, 120, 100, 80)
  570. }
  571. };
  572. // Intersecting from the bottom.
  573. yield return new object []
  574. {
  575. new Region (new Rectangle (40, 10, 100, 100)),
  576. new RectangleF [] { new (70, 80, 50, 40) },
  577. new RectangleF []
  578. {
  579. new (40, 10, 100, 70),
  580. new (40, 80, 30, 30),
  581. new (120, 80, 20, 30)
  582. }
  583. };
  584. // Multiple regions.
  585. yield return new object []
  586. {
  587. new Region (new Rectangle (30, 30, 80, 80)),
  588. new RectangleF []
  589. {
  590. new (45, 45, 200, 200),
  591. new (160, 260, 10, 10),
  592. new (170, 260, 10, 10)
  593. },
  594. new RectangleF []
  595. {
  596. new (30, 30, 80, 15),
  597. new (30, 45, 15, 65)
  598. }
  599. };
  600. // Intersecting from the top with a larger rect.
  601. yield return new object []
  602. {
  603. new Region (new Rectangle (50, 100, 100, 100)),
  604. new RectangleF [] { new (30, 70, 150, 40) },
  605. new RectangleF [] { new (50, 110, 100, 90) }
  606. };
  607. // Intersecting from the right with a larger rect.
  608. yield return new object []
  609. {
  610. new Region (new Rectangle (70, 60, 100, 70)),
  611. new RectangleF [] { new (40, 10, 100, 150) },
  612. new RectangleF [] { new (140, 60, 30, 70) }
  613. };
  614. // Intersecting from the left with a larger rect.
  615. yield return new object []
  616. {
  617. new Region (new Rectangle (70, 60, 100, 70)),
  618. new RectangleF [] { new (100, 10, 100, 150) },
  619. new RectangleF [] { new (70, 60, 30, 70) }
  620. };
  621. // Intersecting from the bottom with a larger rect.
  622. yield return new object []
  623. {
  624. new Region (new Rectangle (20, 20, 100, 100)),
  625. new RectangleF [] { new (10, 80, 140, 150) },
  626. new RectangleF [] { new (20, 20, 100, 60) }
  627. };
  628. yield return new object []
  629. {
  630. new Region (new Rectangle (130, 30, 60, 80)),
  631. new RectangleF [] { new (170, 40, 60, 80) },
  632. new RectangleF []
  633. {
  634. new (130, 30, 60, 10),
  635. new (130, 40, 40, 70)
  636. }
  637. };
  638. }
  639. [Theory]
  640. [MemberData (nameof (Exclude_TestData))]
  641. public void Exclude_Region_Success (Region region, RectangleF [] rectangles, RectangleF [] expectedScans)
  642. {
  643. using (region)
  644. {
  645. foreach (RectangleF rect in rectangles)
  646. {
  647. using Region other = new (rect);
  648. region.Exclude (other);
  649. }
  650. using Matrix matrix = new ();
  651. Assert.Equal (expectedScans, region.GetRegionScans (matrix));
  652. }
  653. }
  654. [Fact]
  655. public void Exclude_UnionRegion_Success ()
  656. {
  657. using Region region = new (new RectangleF (20, 20, 20, 20));
  658. using Region union = new (new RectangleF (20, 80, 20, 10));
  659. using Matrix matrix = new ();
  660. union.Union (new RectangleF (60, 60, 30, 10));
  661. region.Exclude (union);
  662. Assert.Equal ([new (20, 20, 20, 20)], region.GetRegionScans (matrix));
  663. }
  664. [Fact]
  665. public void Exclude_InfiniteRegion_Success ()
  666. {
  667. using Region region = new (new Rectangle (1, 2, 3, 4));
  668. using Region other = new ();
  669. using Matrix matrix = new ();
  670. region.Exclude (other);
  671. Assert.Equal ([], region.GetRegionScans (matrix));
  672. }
  673. [Fact]
  674. public void Exclude_NullRegion_ThrowsArgumentNullException ()
  675. {
  676. using Region region = new ();
  677. Assert.Throws<ArgumentNullException> ("region", () => region.Exclude ((Region)null));
  678. }
  679. [Fact]
  680. public void Exclude_DisposedRegion_ThrowsArgumentException ()
  681. {
  682. Assert.Throws<ArgumentException> (null, () => new Region ().Exclude (CreateDisposedRegion ()));
  683. }
  684. [Fact]
  685. public void Exclude_SameRegion_ThrowsInvalidOperationException ()
  686. {
  687. using Region region = new ();
  688. Assert.Throws<InvalidOperationException> (() => region.Exclude (region));
  689. }
  690. [Theory]
  691. [MemberData (nameof (Exclude_TestData))]
  692. public void Exclude_Rectangle_Success (Region region, RectangleF [] rectangles, RectangleF [] expectedScans)
  693. {
  694. using (region)
  695. {
  696. foreach (RectangleF rect in rectangles)
  697. {
  698. region.Exclude (new Rectangle ((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height));
  699. }
  700. using Matrix matrix = new ();
  701. Assert.Equal (expectedScans, region.GetRegionScans (matrix));
  702. }
  703. }
  704. [Theory]
  705. [MemberData (nameof (Exclude_TestData))]
  706. public void Exclude_RectangleF_Success (Region region, RectangleF [] rectangles, RectangleF [] expectedScans)
  707. {
  708. using (region)
  709. {
  710. foreach (RectangleF rect in rectangles)
  711. {
  712. region.Exclude (rect);
  713. }
  714. using Matrix matrix = new ();
  715. Assert.Equal (expectedScans, region.GetRegionScans (matrix));
  716. }
  717. }
  718. [Theory]
  719. [MemberData (nameof (Exclude_TestData))]
  720. public void Exclude_GraphicsPath_Success (Region region, RectangleF [] rectangles, RectangleF [] expectedScans)
  721. {
  722. using (region)
  723. {
  724. foreach (RectangleF rect in rectangles)
  725. {
  726. using GraphicsPath path = new ();
  727. path.AddRectangle (rect);
  728. region.Exclude (path);
  729. }
  730. using Matrix matrix = new ();
  731. Assert.Equal (expectedScans, region.GetRegionScans (matrix));
  732. }
  733. }
  734. [Fact]
  735. public void Exclude_EmptyPathWithInfiniteRegion_MakesInfinite ()
  736. {
  737. using Region region = new ();
  738. using GraphicsPath graphicsPath = new ();
  739. region.Exclude (graphicsPath);
  740. Assert.True (region.IsInfinite (s_graphic));
  741. }
  742. [Fact]
  743. public void Exclude_NullGraphicsPath_ThrowsArgumentNullException ()
  744. {
  745. using Region region = new ();
  746. Assert.Throws<ArgumentNullException> ("path", () => region.Exclude ((GraphicsPath)null));
  747. }
  748. [Fact]
  749. public void Exclude_Disposed_ThrowsArgumentException ()
  750. {
  751. Region disposedRegion = CreateDisposedRegion ();
  752. using GraphicsPath graphicsPath = new ();
  753. using Region other = new ();
  754. Assert.Throws<ArgumentException> (null, () => disposedRegion.Exclude (graphicsPath));
  755. Assert.Throws<ArgumentException> (null, () => disposedRegion.Exclude (new Rectangle ()));
  756. Assert.Throws<ArgumentException> (null, () => disposedRegion.Exclude (new RectangleF ()));
  757. Assert.Throws<ArgumentException> (null, () => disposedRegion.Exclude (other));
  758. }
  759. [Fact]
  760. public void FromHrgn_ValidHrgn_ReturnsExpected ()
  761. {
  762. using Region region = new (new Rectangle (1, 2, 3, 4));
  763. IntPtr handle1 = region.GetHrgn (s_graphic);
  764. IntPtr handle2 = region.GetHrgn (s_graphic);
  765. Assert.NotEqual (IntPtr.Zero, handle1);
  766. Assert.NotEqual (handle1, handle2);
  767. Region newRegion = Region.FromHrgn (handle1);
  768. IntPtr handle3 = newRegion.GetHrgn (s_graphic);
  769. Assert.NotEqual (handle3, handle1);
  770. Assert.Equal (new RectangleF (1, 2, 3, 4), newRegion.GetBounds (s_graphic));
  771. region.ReleaseHrgn (handle1);
  772. region.ReleaseHrgn (handle2);
  773. newRegion.ReleaseHrgn (handle3);
  774. }
  775. [Fact]
  776. public void FromHrgn_ZeroHrgn_ThrowsArgumentException () { Assert.Throws<ArgumentException> (null, () => Region.FromHrgn (IntPtr.Zero)); }
  777. [Fact]
  778. public void GetHrgn_Infinite_ReturnsZero ()
  779. {
  780. using Region region = new (new Rectangle (1, 2, 3, 4));
  781. IntPtr handle = region.GetHrgn (s_graphic);
  782. Assert.NotEqual (IntPtr.Zero, handle);
  783. region.ReleaseHrgn (handle);
  784. region.MakeInfinite ();
  785. Assert.Equal (IntPtr.Zero, region.GetHrgn (s_graphic));
  786. }
  787. [Fact]
  788. public void GetHrgn_Empty_ReturnsNonZero ()
  789. {
  790. using Region region = new ();
  791. Assert.Equal (IntPtr.Zero, region.GetHrgn (s_graphic));
  792. region.MakeEmpty ();
  793. IntPtr handle = region.GetHrgn (s_graphic);
  794. Assert.NotEqual (IntPtr.Zero, handle);
  795. region.ReleaseHrgn (handle);
  796. }
  797. [Fact]
  798. public void GetHrgn_NullGraphics_ThrowsArgumentNullException ()
  799. {
  800. using Region region = new ();
  801. Assert.Throws<ArgumentNullException> ("g", () => region.GetHrgn (null));
  802. }
  803. [Fact]
  804. public void GetHrgn_Disposed_ThrowsArgumentException ()
  805. {
  806. Assert.Throws<ArgumentException> (null, () => CreateDisposedRegion ().GetHrgn (s_graphic));
  807. }
  808. [Fact]
  809. public void ReleaseHrgn_ZeroHandle_ThrowsArgumentNullException ()
  810. {
  811. using Region region = new ();
  812. Assert.Throws<ArgumentNullException> ("regionHandle", () => region.ReleaseHrgn (IntPtr.Zero));
  813. }
  814. [Fact]
  815. public void GetBounds_NullGraphics_ThrowsArgumentNullException ()
  816. {
  817. using Region region = new ();
  818. Assert.Throws<ArgumentNullException> ("g", () => region.GetBounds (null));
  819. }
  820. [Fact]
  821. public void GetBounds_DisposedGraphics_ThrowsArgumentException ()
  822. {
  823. using Region region = new ();
  824. using Bitmap image = new (10, 10);
  825. var graphics = Graphics.FromImage (image);
  826. graphics.Dispose ();
  827. Assert.Throws<ArgumentException> (null, () => region.GetBounds (graphics));
  828. }
  829. [Fact]
  830. public void GetBounds_Disposed_ThrowsArgumentException ()
  831. {
  832. Assert.Throws<ArgumentException> (null, () => CreateDisposedRegion ().GetBounds (s_graphic));
  833. }
  834. [Fact]
  835. public void GetRegionData_Disposed_ThrowsArgumentException ()
  836. {
  837. Assert.Throws<ArgumentException> (null, () => CreateDisposedRegion ().GetRegionData ());
  838. }
  839. [Fact]
  840. public void GetRegionScans_CustomMatrix_TransformsRegionScans ()
  841. {
  842. using Matrix matrix = new ();
  843. using Region region = new (new Rectangle (1, 2, 3, 4));
  844. using Matrix emptyMatrix = new ();
  845. matrix.Translate (10, 11);
  846. matrix.Scale (5, 6);
  847. Assert.Equal ([new (1, 2, 3, 4)], region.GetRegionScans (emptyMatrix));
  848. Assert.Equal ([new (15, 23, 15, 24)], region.GetRegionScans (matrix));
  849. }
  850. [Fact]
  851. public void GetRegionScans_NullMatrix_ThrowsArgumentNullException ()
  852. {
  853. using Region region = new ();
  854. Assert.Throws<ArgumentNullException> ("matrix", () => region.GetRegionScans (null));
  855. }
  856. [Fact]
  857. public void GetRegionScans_Disposed_ThrowsArgumentException ()
  858. {
  859. using Matrix matrix = new ();
  860. Assert.Throws<ArgumentException> (null, () => CreateDisposedRegion ().GetRegionScans (matrix));
  861. }
  862. [Fact]
  863. public void GetRegionScans_DisposedMatrix_ThrowsArgumentException ()
  864. {
  865. using Region region = new ();
  866. Matrix matrix = new ();
  867. matrix.Dispose ();
  868. Assert.Throws<ArgumentException> (null, () => region.GetRegionScans (matrix));
  869. }
  870. [Fact]
  871. public void Intersect_SmallerRect_Success ()
  872. {
  873. using Region clipRegion = new ();
  874. using Matrix matrix = new ();
  875. Rectangle smaller = new (5, 5, -10, -10);
  876. clipRegion.Intersect (smaller);
  877. Assert.False (clipRegion.IsEmpty (s_graphic));
  878. Assert.False (clipRegion.IsInfinite (s_graphic));
  879. RectangleF [] rects = clipRegion.GetRegionScans (matrix);
  880. Assert.Equal (1, rects.Length);
  881. Assert.Equal (new RectangleF (-5, -5, 10, 10), rects [0]);
  882. }
  883. public static IEnumerable<object []> Intersect_TestData ()
  884. {
  885. yield return new object []
  886. {
  887. new Region (new Rectangle (500, 30, 60, 80)),
  888. new RectangleF [] { new (500, 30, 60, 80) },
  889. new RectangleF [] { new (500, 30, 60, 80) }
  890. };
  891. yield return new object []
  892. {
  893. new Region (new Rectangle (0, 0, 0, 0)),
  894. new RectangleF [] { new (500, 30, 60, 80) },
  895. new RectangleF[0]
  896. };
  897. yield return new object []
  898. {
  899. new Region (new Rectangle (500, 30, 60, 80)),
  900. new RectangleF [] { RectangleF.Empty },
  901. new RectangleF[0]
  902. };
  903. yield return new object []
  904. {
  905. new Region (),
  906. new RectangleF [] { new (520, 40, 60, 80) },
  907. new RectangleF [] { new Rectangle (520, 40, 60, 80) }
  908. };
  909. yield return new object []
  910. {
  911. new Region (),
  912. new RectangleF [] { RectangleF.Empty },
  913. new RectangleF[0]
  914. };
  915. yield return new object []
  916. {
  917. new Region (new RectangleF (260, 30, 60, 80)),
  918. new RectangleF [] { new (290, 40, 60, 90) },
  919. new RectangleF [] { new (290, 40, 30, 70) }
  920. };
  921. yield return new object []
  922. {
  923. new Region (new RectangleF (20, 330, 40, 50)),
  924. new RectangleF []
  925. {
  926. new (50, 340, 40, 50),
  927. new (70, 360, 30, 50),
  928. new (80, 400, 30, 10)
  929. },
  930. new RectangleF[0]
  931. };
  932. }
  933. [Theory]
  934. [MemberData (nameof (Intersect_TestData))]
  935. public void Intersect_Region_Success (Region region, RectangleF [] rectangles, RectangleF [] expectedScans)
  936. {
  937. using (region)
  938. {
  939. foreach (RectangleF rect in rectangles)
  940. {
  941. using Region rectangleRegion = new (rect);
  942. region.Intersect (rectangleRegion);
  943. }
  944. using Matrix matrix = new ();
  945. Assert.Equal (expectedScans, region.GetRegionScans (matrix));
  946. }
  947. }
  948. [Fact]
  949. public void Intersect_InfiniteRegion_Success ()
  950. {
  951. using Region region = new (new Rectangle (1, 2, 3, 4));
  952. using Matrix matrix = new ();
  953. using Region infiniteRegion = new ();
  954. region.Intersect (infiniteRegion);
  955. Assert.Equal ([new Rectangle (1, 2, 3, 4)], region.GetRegionScans (matrix));
  956. }
  957. [Fact]
  958. public void Intersect_NullRegion_ThrowsArgumentNullException ()
  959. {
  960. using Region region = new ();
  961. Assert.Throws<ArgumentNullException> ("region", () => region.Intersect ((Region)null));
  962. }
  963. [Fact]
  964. public void Intersect_DisposedRegion_ThrowsArgumentException ()
  965. {
  966. Assert.Throws<ArgumentException> (null, () => new Region ().Intersect (CreateDisposedRegion ()));
  967. }
  968. [Fact]
  969. public void Intersect_SameRegion_ThrowsInvalidOperationException ()
  970. {
  971. using Region region = new ();
  972. Assert.Throws<InvalidOperationException> (() => region.Intersect (region));
  973. }
  974. [Theory]
  975. [MemberData (nameof (Intersect_TestData))]
  976. public void Intersect_Rectangle_Success (Region region, RectangleF [] rectangles, RectangleF [] expectedScans)
  977. {
  978. using (region)
  979. {
  980. foreach (RectangleF rect in rectangles)
  981. {
  982. region.Intersect (new Rectangle ((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height));
  983. }
  984. using Matrix matrix = new ();
  985. Assert.Equal (expectedScans, region.GetRegionScans (matrix));
  986. }
  987. }
  988. [Fact]
  989. public void Intersect_InfiniteRegionWithSmallerRectangle_Success ()
  990. {
  991. using Region region = new ();
  992. using Matrix matrix = new ();
  993. region.Intersect (new Rectangle (5, 5, -10, -10));
  994. Assert.False (region.IsEmpty (s_graphic));
  995. Assert.False (region.IsInfinite (s_graphic));
  996. Assert.Equal ([new (-5, -5, 10, 10)], region.GetRegionScans (matrix));
  997. }
  998. [Theory]
  999. [MemberData (nameof (Intersect_TestData))]
  1000. public void Intersect_RectangleF_Success (Region region, RectangleF [] rectangles, RectangleF [] expectedScans)
  1001. {
  1002. using (region)
  1003. {
  1004. foreach (RectangleF rect in rectangles)
  1005. {
  1006. region.Intersect (rect);
  1007. }
  1008. using Matrix matrix = new ();
  1009. Assert.Equal (expectedScans, region.GetRegionScans (matrix));
  1010. }
  1011. }
  1012. [Fact]
  1013. public void Intersect_InfiniteRegionWithSmallerRectangleF_Success ()
  1014. {
  1015. using Region region = new ();
  1016. using Matrix matrix = new ();
  1017. region.Intersect (new RectangleF (5, 5, -10, -10));
  1018. Assert.False (region.IsEmpty (s_graphic));
  1019. Assert.False (region.IsInfinite (s_graphic));
  1020. Assert.Equal ([new (-5, -5, 10, 10)], region.GetRegionScans (matrix));
  1021. }
  1022. [Theory]
  1023. [MemberData (nameof (Intersect_TestData))]
  1024. public void Intersect_GraphicsPath_Success (Region region, RectangleF [] rectangles, RectangleF [] expectedScans)
  1025. {
  1026. using (region)
  1027. {
  1028. foreach (RectangleF rect in rectangles)
  1029. {
  1030. using GraphicsPath path = new ();
  1031. path.AddRectangle (rect);
  1032. region.Intersect (path);
  1033. }
  1034. using Matrix matrix = new ();
  1035. Assert.Equal (expectedScans, region.GetRegionScans (matrix));
  1036. }
  1037. }
  1038. [Fact]
  1039. public void Intersect_EmptyPathWithInfiniteRegion_MakesEmpty ()
  1040. {
  1041. using Region region = new ();
  1042. using GraphicsPath graphicsPath = new ();
  1043. region.Intersect (graphicsPath);
  1044. Assert.True (region.IsEmpty (s_graphic));
  1045. }
  1046. [Fact]
  1047. public void Intersect_NullGraphicsPath_ThrowsArgumentNullException ()
  1048. {
  1049. using Region region = new ();
  1050. Assert.Throws<ArgumentNullException> ("path", () => region.Intersect ((GraphicsPath)null));
  1051. }
  1052. [Fact]
  1053. public void Intersect_Disposed_ThrowsArgumentException ()
  1054. {
  1055. Region disposedRegion = CreateDisposedRegion ();
  1056. using GraphicsPath graphicsPath = new ();
  1057. using Region other = new ();
  1058. Assert.Throws<ArgumentException> (null, () => disposedRegion.Intersect (graphicsPath));
  1059. Assert.Throws<ArgumentException> (null, () => disposedRegion.Intersect (new Rectangle ()));
  1060. Assert.Throws<ArgumentException> (null, () => disposedRegion.Intersect (new RectangleF ()));
  1061. Assert.Throws<ArgumentException> (null, () => disposedRegion.Intersect (other));
  1062. }
  1063. [Fact]
  1064. public void IsEmpty_NullGraphics_ThrowsArgumentNullException ()
  1065. {
  1066. using Region region = new ();
  1067. Assert.Throws<ArgumentNullException> ("g", () => region.IsEmpty (null));
  1068. }
  1069. [Fact]
  1070. public void IsEmpty_Disposed_ThrowsArgumentException ()
  1071. {
  1072. Assert.Throws<ArgumentException> (null, () => CreateDisposedRegion ().IsEmpty (s_graphic));
  1073. }
  1074. [Fact]
  1075. public void IsInfinite_NullGraphics_ThrowsArgumentNullException ()
  1076. {
  1077. using Region region = new ();
  1078. Assert.Throws<ArgumentNullException> ("g", () => region.IsInfinite (null));
  1079. }
  1080. [Fact]
  1081. public void IsInfinite_DisposedGraphics_ThrowsArgumentException ()
  1082. {
  1083. using Region region = new ();
  1084. using Bitmap image = new (10, 10);
  1085. var graphics = Graphics.FromImage (image);
  1086. graphics.Dispose ();
  1087. Assert.Throws<ArgumentException> (null, () => region.IsInfinite (graphics));
  1088. }
  1089. [Fact]
  1090. public void IsInfinite_Disposed_ThrowsArgumentException ()
  1091. {
  1092. Assert.Throws<ArgumentException> (null, () => CreateDisposedRegion ().IsInfinite (s_graphic));
  1093. }
  1094. public static IEnumerable<object []> IsVisible_Rectangle_TestData ()
  1095. {
  1096. Region infiniteExclude = new ();
  1097. infiniteExclude.Exclude (new Rectangle (387, 292, 189, 133));
  1098. infiniteExclude.Exclude (new Rectangle (387, 66, 189, 133));
  1099. yield return new object [] { infiniteExclude, new Rectangle (66, 292, 189, 133), true };
  1100. yield return new object [] { new Region (), Rectangle.Empty, false };
  1101. yield return new object [] { new Region (new Rectangle (0, 0, 10, 10)), new Rectangle (0, 0, 0, 1), false };
  1102. yield return new object [] { new Region (new Rectangle (500, 30, 60, 80)), new Rectangle (500, 30, 60, 80), true };
  1103. yield return new object [] { new Region (new Rectangle (500, 30, 60, 80)), new Rectangle (520, 40, 60, 80), true };
  1104. yield return new object [] { new Region (new Rectangle (1, 1, 2, 1)), new Rectangle (1, 1, 2, 1), true };
  1105. yield return new object [] { new Region (new Rectangle (1, 1, 2, 1)), new Rectangle (1, 1, 2, 2), true };
  1106. yield return new object [] { new Region (new Rectangle (1, 1, 2, 1)), new Rectangle (1, 1, 10, 10), true };
  1107. yield return new object [] { new Region (new Rectangle (1, 1, 2, 1)), new Rectangle (1, 1, 1, 1), true };
  1108. yield return new object [] { new Region (new Rectangle (1, 1, 2, 1)), new Rectangle (2, 2, 1, 1), false };
  1109. yield return new object [] { new Region (new Rectangle (1, 1, 2, 1)), new Rectangle (0, 0, 1, 1), false };
  1110. yield return new object [] { new Region (new Rectangle (1, 1, 2, 1)), new Rectangle (3, 3, 1, 1), false };
  1111. }
  1112. [Theory]
  1113. [MemberData (nameof (IsVisible_Rectangle_TestData))]
  1114. public void IsVisible_Rectangle_ReturnsExpected (Region region, Rectangle rectangle, bool expected)
  1115. {
  1116. using (region)
  1117. using (Bitmap image = new (10, 10))
  1118. {
  1119. var disposedGraphics = Graphics.FromImage (image);
  1120. disposedGraphics.Dispose ();
  1121. Assert.Equal (expected, region.IsVisible (rectangle));
  1122. Assert.Equal (expected, region.IsVisible ((RectangleF)rectangle));
  1123. Assert.Equal (expected, region.IsVisible (rectangle, s_graphic));
  1124. Assert.Equal (expected, region.IsVisible (rectangle, disposedGraphics));
  1125. Assert.Equal (expected, region.IsVisible (rectangle, null));
  1126. Assert.Equal (expected, region.IsVisible ((RectangleF)rectangle, s_graphic));
  1127. Assert.Equal (expected, region.IsVisible ((RectangleF)rectangle, disposedGraphics));
  1128. Assert.Equal (expected, region.IsVisible ((RectangleF)rectangle, null));
  1129. Assert.Equal (expected, region.IsVisible (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height));
  1130. Assert.Equal (expected, region.IsVisible ((float)rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height));
  1131. Assert.Equal (expected, region.IsVisible (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height, s_graphic));
  1132. Assert.Equal (expected, region.IsVisible (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height, disposedGraphics));
  1133. Assert.Equal (expected, region.IsVisible (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height, null));
  1134. Assert.Equal (expected, region.IsVisible ((float)rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height, s_graphic));
  1135. Assert.Equal (expected, region.IsVisible ((float)rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height, disposedGraphics));
  1136. Assert.Equal (expected, region.IsVisible ((float)rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height, null));
  1137. }
  1138. }
  1139. public static IEnumerable<object []> IsVisible_Point_TestData ()
  1140. {
  1141. Region infiniteExclude = new ();
  1142. infiniteExclude.Exclude (new Rectangle (387, 292, 189, 133));
  1143. infiniteExclude.Exclude (new Rectangle (387, 66, 189, 133));
  1144. yield return new object [] { infiniteExclude, new Point (66, 292), true };
  1145. yield return new object [] { new Region (), Point.Empty, true };
  1146. yield return new object [] { new Region (new Rectangle (500, 30, 60, 80)), new Point (500, 29), false };
  1147. yield return new object [] { new Region (new Rectangle (500, 30, 60, 80)), new Point (500, 30), true };
  1148. yield return new object [] { new Region (new Rectangle (1, 1, 2, 1)), new Point (0, 1), false };
  1149. yield return new object [] { new Region (new Rectangle (1, 1, 2, 1)), new Point (1, 0), false };
  1150. yield return new object [] { new Region (new Rectangle (1, 1, 2, 1)), new Point (2, 0), false };
  1151. yield return new object [] { new Region (new Rectangle (1, 1, 2, 1)), new Point (3, 0), false };
  1152. yield return new object [] { new Region (new Rectangle (1, 1, 2, 1)), new Point (1, 1), true };
  1153. yield return new object [] { new Region (new Rectangle (1, 1, 2, 1)), new Point (2, 1), true };
  1154. yield return new object [] { new Region (new Rectangle (1, 1, 2, 1)), new Point (3, 1), false };
  1155. yield return new object [] { new Region (new Rectangle (1, 1, 2, 1)), new Point (0, 2), false };
  1156. yield return new object [] { new Region (new Rectangle (1, 1, 2, 1)), new Point (2, 2), false };
  1157. yield return new object [] { new Region (new Rectangle (1, 1, 2, 1)), new Point (3, 2), false };
  1158. }
  1159. [Theory]
  1160. [MemberData (nameof (IsVisible_Point_TestData))]
  1161. public void IsVisible_Point_ReturnsExpected (Region region, Point point, bool expected)
  1162. {
  1163. using (region)
  1164. using (Bitmap image = new (10, 10))
  1165. {
  1166. var disposedGraphics = Graphics.FromImage (image);
  1167. disposedGraphics.Dispose ();
  1168. Assert.Equal (expected, region.IsVisible (point));
  1169. Assert.Equal (expected, region.IsVisible ((PointF)point));
  1170. Assert.Equal (expected, region.IsVisible (point, s_graphic));
  1171. Assert.Equal (expected, region.IsVisible (point, disposedGraphics));
  1172. Assert.Equal (expected, region.IsVisible (point, null));
  1173. Assert.Equal (expected, region.IsVisible ((PointF)point, s_graphic));
  1174. Assert.Equal (expected, region.IsVisible ((PointF)point, disposedGraphics));
  1175. Assert.Equal (expected, region.IsVisible ((PointF)point, null));
  1176. Assert.Equal (expected, region.IsVisible (point.X, point.Y));
  1177. Assert.Equal (expected, region.IsVisible (point.X, point.Y, s_graphic));
  1178. Assert.Equal (expected, region.IsVisible (point.X, point.Y, disposedGraphics));
  1179. Assert.Equal (expected, region.IsVisible (point.X, point.Y, null));
  1180. Assert.Equal (expected, region.IsVisible (point.X, point.Y, s_graphic));
  1181. Assert.Equal (expected, region.IsVisible (point.X, point.Y, disposedGraphics));
  1182. Assert.Equal (expected, region.IsVisible (point.X, point.Y, null));
  1183. Assert.Equal (expected, region.IsVisible ((float)point.X, point.Y, s_graphic));
  1184. Assert.Equal (expected, region.IsVisible ((float)point.X, point.Y, disposedGraphics));
  1185. Assert.Equal (expected, region.IsVisible ((float)point.X, point.Y, null));
  1186. }
  1187. }
  1188. [Fact]
  1189. public void IsVisible_Disposed_ThrowsArgumentException ()
  1190. {
  1191. Region disposedRegion = CreateDisposedRegion ();
  1192. Assert.Throws<ArgumentException> (null, () => disposedRegion.IsVisible (1f, 2f));
  1193. Assert.Throws<ArgumentException> (null, () => disposedRegion.IsVisible (new PointF (1, 2)));
  1194. Assert.Throws<ArgumentException> (null, () => disposedRegion.IsVisible (new Point (1, 2)));
  1195. Assert.Throws<ArgumentException> (null, () => disposedRegion.IsVisible (1f, 2f, s_graphic));
  1196. Assert.Throws<ArgumentException> (null, () => disposedRegion.IsVisible (new PointF (1, 2), s_graphic));
  1197. Assert.Throws<ArgumentException> (null, () => disposedRegion.IsVisible (new Point (1, 2), s_graphic));
  1198. Assert.Throws<ArgumentException> (null, () => disposedRegion.IsVisible (1f, 2f, 3f, 4f));
  1199. Assert.Throws<ArgumentException> (null, () => disposedRegion.IsVisible (new Rectangle (1, 2, 3, 4)));
  1200. Assert.Throws<ArgumentException> (null, () => disposedRegion.IsVisible (new RectangleF (1, 2, 3, 4)));
  1201. Assert.Throws<ArgumentException> (null, () => disposedRegion.IsVisible (1f, 2f, 3f, 4f, s_graphic));
  1202. Assert.Throws<ArgumentException> (null, () => disposedRegion.IsVisible (new Rectangle (1, 2, 3, 4), s_graphic));
  1203. Assert.Throws<ArgumentException> (null, () => disposedRegion.IsVisible (new RectangleF (1, 2, 3, 4), s_graphic));
  1204. Assert.Throws<ArgumentException> (null, () => disposedRegion.IsVisible (1, 2, s_graphic));
  1205. Assert.Throws<ArgumentException> (null, () => disposedRegion.IsVisible (1, 2, 3, 4));
  1206. Assert.Throws<ArgumentException> (null, () => disposedRegion.IsVisible (1, 2, 3, 4, s_graphic));
  1207. }
  1208. [Theory]
  1209. [MemberData (nameof (Region_TestData))]
  1210. public void MakeEmpty_NonEmpty_Success (Region region)
  1211. {
  1212. using (region)
  1213. {
  1214. region.MakeEmpty ();
  1215. Assert.True (region.IsEmpty (s_graphic));
  1216. Assert.False (region.IsInfinite (s_graphic));
  1217. Assert.Equal (RectangleF.Empty, region.GetBounds (s_graphic));
  1218. using (Matrix matrix = new ())
  1219. {
  1220. Assert.Empty (region.GetRegionScans (matrix));
  1221. }
  1222. region.MakeEmpty ();
  1223. Assert.True (region.IsEmpty (s_graphic));
  1224. }
  1225. }
  1226. [Fact]
  1227. public void MakeEmpty_Disposed_ThrowsArgumentException () { Assert.Throws<ArgumentException> (null, () => CreateDisposedRegion ().MakeEmpty ()); }
  1228. [Theory]
  1229. [MemberData (nameof (Region_TestData))]
  1230. public void MakeInfinite_NonInfinity_Success (Region region)
  1231. {
  1232. using (region)
  1233. {
  1234. region.MakeInfinite ();
  1235. Assert.False (region.IsEmpty (s_graphic));
  1236. Assert.True (region.IsInfinite (s_graphic));
  1237. Assert.Equal (new RectangleF (-4194304, -4194304, 8388608, 8388608), region.GetBounds (s_graphic));
  1238. region.MakeInfinite ();
  1239. Assert.False (region.IsEmpty (s_graphic));
  1240. Assert.True (region.IsInfinite (s_graphic));
  1241. }
  1242. }
  1243. [Fact]
  1244. public void MakeInfinite_Disposed_ThrowsArgumentException ()
  1245. {
  1246. Assert.Throws<ArgumentException> (null, () => CreateDisposedRegion ().MakeInfinite ());
  1247. }
  1248. public static IEnumerable<object []> Union_TestData ()
  1249. {
  1250. yield return new object []
  1251. {
  1252. new Region (new Rectangle (500, 30, 60, 80)),
  1253. new RectangleF [] { new (500, 30, 60, 80) },
  1254. new RectangleF [] { new (500, 30, 60, 80) }
  1255. };
  1256. yield return new object []
  1257. {
  1258. new Region (new Rectangle (500, 30, 60, 80)),
  1259. new RectangleF [] { RectangleF.Empty },
  1260. new RectangleF [] { new (500, 30, 60, 80) }
  1261. };
  1262. yield return new object []
  1263. {
  1264. new Region (new Rectangle (500, 30, 60, 80)),
  1265. new RectangleF [] { new (520, 30, 60, 80) },
  1266. new RectangleF [] { new (500, 30, 80, 80) }
  1267. };
  1268. yield return new object []
  1269. {
  1270. new Region (new Rectangle (500, 30, 60, 80)),
  1271. new RectangleF [] { new (520, 40, 60, 80) },
  1272. new RectangleF []
  1273. {
  1274. new (500, 30, 60, 10),
  1275. new (500, 40, 80, 70),
  1276. new (520, 110, 60, 10),
  1277. }
  1278. };
  1279. yield return new object []
  1280. {
  1281. new Region (),
  1282. new RectangleF [] { new (520, 40, 60, 80) },
  1283. new RectangleF [] { new Rectangle (-4194304, -4194304, 8388608, 8388608) }
  1284. };
  1285. yield return new object []
  1286. {
  1287. new Region (),
  1288. new RectangleF [] { RectangleF.Empty },
  1289. new RectangleF [] { new Rectangle (-4194304, -4194304, 8388608, 8388608) }
  1290. };
  1291. // No intersecting rects.
  1292. yield return new object []
  1293. {
  1294. new Region (new Rectangle (20, 20, 20, 20)),
  1295. new RectangleF []
  1296. {
  1297. new (20, 80, 20, 10),
  1298. new (60, 60, 30, 10)
  1299. },
  1300. new RectangleF []
  1301. {
  1302. new (20, 20, 20, 20),
  1303. new (60, 60, 30, 10),
  1304. new (20, 80, 20, 10)
  1305. }
  1306. };
  1307. yield return new object []
  1308. {
  1309. new Region (new Rectangle (20, 180, 40, 50)),
  1310. new RectangleF []
  1311. {
  1312. new (50, 190, 40, 50),
  1313. new (70, 210, 30, 50)
  1314. },
  1315. new RectangleF []
  1316. {
  1317. new (20, 180, 40, 10),
  1318. new (20, 190, 70, 20),
  1319. new (20, 210, 80, 20),
  1320. new (50, 230, 50, 10),
  1321. new (70, 240, 30, 20)
  1322. }
  1323. };
  1324. yield return new object []
  1325. {
  1326. new Region (new Rectangle (20, 330, 40, 50)),
  1327. new RectangleF []
  1328. {
  1329. new (50, 340, 40, 50),
  1330. new (70, 360, 30, 50),
  1331. new (80, 400, 30, 10)
  1332. },
  1333. new RectangleF []
  1334. {
  1335. new (20, 330, 40, 10),
  1336. new (20, 340, 70, 20),
  1337. new (20, 360, 80, 20),
  1338. new (50, 380, 50, 10),
  1339. new (70, 390, 30, 10),
  1340. new (70, 400, 40, 10)
  1341. }
  1342. };
  1343. yield return new object []
  1344. {
  1345. new Region (new Rectangle (10, 20, 50, 50)),
  1346. new RectangleF []
  1347. {
  1348. new (100, 100, 60, 60),
  1349. new (200, 200, 80, 80)
  1350. },
  1351. new RectangleF []
  1352. {
  1353. new (10, 20, 50, 50),
  1354. new (100, 100, 60, 60),
  1355. new (200, 200, 80, 80)
  1356. }
  1357. };
  1358. // Intersecting from the right.
  1359. yield return new object []
  1360. {
  1361. new Region (new Rectangle (10, 10, 100, 100)),
  1362. new RectangleF [] { new (40, 60, 100, 20) },
  1363. new RectangleF []
  1364. {
  1365. new (10, 10, 100, 50),
  1366. new (10, 60, 130, 20),
  1367. new (10, 80, 100, 30)
  1368. }
  1369. };
  1370. // Intersecting from the left.
  1371. yield return new object []
  1372. {
  1373. new Region (new Rectangle (70, 10, 100, 100)),
  1374. new RectangleF [] { new (40, 60, 100, 20) },
  1375. new RectangleF []
  1376. {
  1377. new (70, 10, 100, 50),
  1378. new (40, 60, 130, 20),
  1379. new (70, 80, 100, 30)
  1380. }
  1381. };
  1382. // Intersecting from the top.
  1383. yield return new object []
  1384. {
  1385. new Region (new Rectangle (40, 100, 100, 100)),
  1386. new RectangleF [] { new (70, 80, 50, 40) },
  1387. new RectangleF []
  1388. {
  1389. new (70, 80, 50, 20),
  1390. new (40, 100, 100, 100)
  1391. }
  1392. };
  1393. // Intersecting from the bottom.
  1394. yield return new object []
  1395. {
  1396. new Region (new Rectangle (40, 10, 100, 100)),
  1397. new RectangleF [] { new (70, 80, 50, 40) },
  1398. new RectangleF []
  1399. {
  1400. new (40, 10, 100, 100),
  1401. new (70, 110, 50, 10)
  1402. }
  1403. };
  1404. // Multiple regions separated by 0 pixels.
  1405. yield return new object []
  1406. {
  1407. new Region (new Rectangle (30, 30, 80, 80)),
  1408. new RectangleF []
  1409. {
  1410. new (45, 45, 200, 200),
  1411. new (160, 260, 10, 10),
  1412. new (170, 260, 10, 10)
  1413. },
  1414. new RectangleF []
  1415. {
  1416. new (30, 30, 80, 15),
  1417. new (30, 45, 215, 65),
  1418. new (45, 110, 200, 135),
  1419. new (160, 260, 20, 10)
  1420. }
  1421. };
  1422. }
  1423. [Theory]
  1424. [MemberData (nameof (Union_TestData))]
  1425. public void Union_Region_Success (Region region, RectangleF [] rectangles, RectangleF [] expectedScans)
  1426. {
  1427. using (region)
  1428. {
  1429. foreach (RectangleF rect in rectangles)
  1430. {
  1431. using Region other = new (rect);
  1432. region.Union (other);
  1433. }
  1434. using Matrix matrix = new ();
  1435. Assert.Equal (expectedScans, region.GetRegionScans (matrix));
  1436. }
  1437. }
  1438. [Fact]
  1439. public void Union_InfiniteRegion_Success ()
  1440. {
  1441. using Region region = new (new Rectangle (1, 2, 3, 4));
  1442. using Region other = new ();
  1443. using Matrix matrix = new ();
  1444. region.Union (other);
  1445. Assert.Equal ([new Rectangle (-4194304, -4194304, 8388608, 8388608)], region.GetRegionScans (matrix));
  1446. }
  1447. [Fact]
  1448. public void Union_NullRegion_ThrowsArgumentNullException ()
  1449. {
  1450. using Region region = new ();
  1451. Assert.Throws<ArgumentNullException> ("region", () => region.Union ((Region)null));
  1452. }
  1453. [Fact]
  1454. public void Union_DisposedRegion_ThrowsArgumentException ()
  1455. {
  1456. using Region region = new ();
  1457. Assert.Throws<ArgumentException> (null, () => region.Union (CreateDisposedRegion ()));
  1458. }
  1459. [Fact]
  1460. public void Union_SameRegion_ThrowsInvalidOperationException ()
  1461. {
  1462. using Region region = new ();
  1463. Assert.Throws<InvalidOperationException> (() => region.Union (region));
  1464. }
  1465. [Theory]
  1466. [MemberData (nameof (Union_TestData))]
  1467. public void Union_Rectangle_Success (Region region, RectangleF [] rectangles, RectangleF [] expectedScans)
  1468. {
  1469. using (region)
  1470. {
  1471. foreach (RectangleF rect in rectangles)
  1472. {
  1473. region.Union (new Rectangle ((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height));
  1474. }
  1475. using Matrix matrix = new ();
  1476. Assert.Equal (expectedScans, region.GetRegionScans (matrix));
  1477. }
  1478. }
  1479. [Theory]
  1480. [MemberData (nameof (Union_TestData))]
  1481. public void Union_RectangleF_Success (Region region, RectangleF [] rectangles, RectangleF [] expectedScans)
  1482. {
  1483. using (region)
  1484. {
  1485. foreach (RectangleF rect in rectangles)
  1486. {
  1487. region.Union (rect);
  1488. }
  1489. using Matrix matrix = new ();
  1490. Assert.Equal (expectedScans, region.GetRegionScans (matrix));
  1491. }
  1492. }
  1493. [Theory]
  1494. [MemberData (nameof (Union_TestData))]
  1495. public void Union_GraphicsPath_Success (Region region, RectangleF [] rectangles, RectangleF [] expectedScans)
  1496. {
  1497. using (region)
  1498. {
  1499. foreach (RectangleF rect in rectangles)
  1500. {
  1501. using GraphicsPath path = new ();
  1502. path.AddRectangle (rect);
  1503. region.Union (path);
  1504. }
  1505. using Matrix matrix = new ();
  1506. Assert.Equal (expectedScans, region.GetRegionScans (matrix));
  1507. }
  1508. }
  1509. [Fact]
  1510. public void Union_EmptyPathWithInfiniteRegion_MakesInfinite ()
  1511. {
  1512. using Region region = new ();
  1513. using GraphicsPath graphicsPath = new ();
  1514. region.Union (graphicsPath);
  1515. Assert.True (region.IsInfinite (s_graphic));
  1516. }
  1517. [Fact]
  1518. public void Union_NullGraphicsPath_ThrowsArgumentNullException ()
  1519. {
  1520. using Region region = new ();
  1521. Assert.Throws<ArgumentNullException> ("path", () => region.Union ((GraphicsPath)null));
  1522. }
  1523. [Fact]
  1524. public void Union_Disposed_ThrowsArgumentException ()
  1525. {
  1526. Region disposedRegion = CreateDisposedRegion ();
  1527. using GraphicsPath graphicsPath = new ();
  1528. using Region other = new ();
  1529. Assert.Throws<ArgumentException> (null, () => disposedRegion.Union (graphicsPath));
  1530. Assert.Throws<ArgumentException> (null, () => disposedRegion.Union (new Rectangle ()));
  1531. Assert.Throws<ArgumentException> (null, () => disposedRegion.Union (new RectangleF ()));
  1532. Assert.Throws<ArgumentException> (null, () => disposedRegion.Union (disposedRegion));
  1533. }
  1534. [Fact]
  1535. public void Transform_EmptyMatrix_Nop ()
  1536. {
  1537. using Region region = new (new RectangleF (1, 2, 3, 4));
  1538. using Matrix matrix = new ();
  1539. region.Transform (matrix);
  1540. Assert.Equal ([new (1, 2, 3, 4)], region.GetRegionScans (matrix));
  1541. }
  1542. [Fact]
  1543. public void Transform_CustomMatrix_Success ()
  1544. {
  1545. using Region region = new (new RectangleF (1, 2, 3, 4));
  1546. using Matrix matrix = new ();
  1547. using Matrix emptyMatrix = new ();
  1548. matrix.Translate (10, 11);
  1549. matrix.Scale (5, 6);
  1550. region.Transform (matrix);
  1551. Assert.Equal ([new (15, 23, 15, 24)], region.GetRegionScans (emptyMatrix));
  1552. }
  1553. [Theory]
  1554. [InlineData (0, 0, 0)]
  1555. [InlineData (2, 2, 0)]
  1556. [InlineData (0.5, 0.5, 0)]
  1557. [InlineData (1, 1, 45)]
  1558. public void Transform_Infinity_Nop (float scaleX, float scaleY, int angle)
  1559. {
  1560. using Region region = new ();
  1561. using Matrix matrix = new ();
  1562. using Matrix emptyMatrix = new ();
  1563. matrix.Translate (10, 11);
  1564. matrix.Scale (scaleX, scaleY);
  1565. matrix.Rotate (angle);
  1566. region.Transform (matrix);
  1567. Assert.True (region.IsInfinite (s_graphic));
  1568. Assert.Equal ([new (-4194304, -4194304, 8388608, 8388608)], region.GetRegionScans (emptyMatrix));
  1569. }
  1570. [Fact]
  1571. public void Transform_InfinityIntersectScale_Success ()
  1572. {
  1573. using Region region = new ();
  1574. using Matrix matrix = new ();
  1575. using Matrix emptyMatrix = new ();
  1576. matrix.Scale (2, 0.5f);
  1577. region.Intersect (new Rectangle (-10, -10, 20, 20));
  1578. region.Transform (matrix);
  1579. Assert.False (region.IsInfinite (s_graphic));
  1580. Assert.Equal ([new (-20, -5, 40, 10)], region.GetRegionScans (emptyMatrix));
  1581. }
  1582. [Fact]
  1583. public void Transform_InfinityIntersectTransform_Success ()
  1584. {
  1585. using Region region = new ();
  1586. using Matrix matrix = new (2, 0, 0, 0.5f, 10, 10);
  1587. using Matrix emptyMatrix = new ();
  1588. region.Intersect (new Rectangle (-10, -10, 20, 20));
  1589. region.Transform (matrix);
  1590. Assert.False (region.IsInfinite (s_graphic));
  1591. Assert.Equal ([new (-10, 5, 40, 10)], region.GetRegionScans (emptyMatrix));
  1592. }
  1593. [Fact]
  1594. public void Transform_NullMatrix_ThrowsArgumentNullException ()
  1595. {
  1596. using Region region = new ();
  1597. Assert.Throws<ArgumentNullException> ("matrix", () => region.Transform (null));
  1598. }
  1599. [Fact]
  1600. public void Transform_Disposed_ThrowsArgumentException ()
  1601. {
  1602. using Matrix matrix = new ();
  1603. Assert.Throws<ArgumentException> (null, () => CreateDisposedRegion ().Transform (matrix));
  1604. }
  1605. [Theory]
  1606. [InlineData (0, 0)]
  1607. [InlineData (2, 3)]
  1608. [InlineData (-2, -3)]
  1609. public void Translate_Int_Success (float dx, float dy)
  1610. {
  1611. using Region region = new (new RectangleF (1, 2, 3, 4));
  1612. using Matrix matrix = new ();
  1613. region.Translate (dx, dy);
  1614. Assert.Equal ([new (1 + dx, 2 + dy, 3, 4)], region.GetRegionScans (matrix));
  1615. }
  1616. [Fact]
  1617. public void Translate_IntInfinityIntersect_Success ()
  1618. {
  1619. using Region region = new ();
  1620. using Matrix matrix = new ();
  1621. region.Intersect (new Rectangle (-10, -10, 20, 20));
  1622. region.Translate (10, 10);
  1623. Assert.False (region.IsInfinite (s_graphic));
  1624. Assert.Equal ([new (0, 0, 20, 20)], region.GetRegionScans (matrix));
  1625. }
  1626. [Theory]
  1627. [InlineData (0, 0)]
  1628. [InlineData (2, 3)]
  1629. public void Translate_Float_Success (int dx, int dy)
  1630. {
  1631. using Region region = new (new RectangleF (1, 2, 3, 4));
  1632. using Matrix matrix = new ();
  1633. region.Translate (dx, dy);
  1634. Assert.Equal ([new (1 + dx, 2 + dy, 3, 4)], region.GetRegionScans (matrix));
  1635. }
  1636. [Fact]
  1637. public void Translate_FloatInfinityIntersect_Success ()
  1638. {
  1639. using Region region = new ();
  1640. using Matrix matrix = new ();
  1641. region.Intersect (new Rectangle (-10, -10, 20, 20));
  1642. region.Translate (10f, 10f);
  1643. Assert.False (region.IsInfinite (s_graphic));
  1644. Assert.Equal ([new (0, 0, 20, 20)], region.GetRegionScans (matrix));
  1645. }
  1646. [Fact]
  1647. public void Translate_Infinity_Nop ()
  1648. {
  1649. using Region region = new ();
  1650. using Matrix matrix = new ();
  1651. region.Translate (10, 10);
  1652. region.Translate (10f, 10f);
  1653. Assert.True (region.IsInfinite (s_graphic));
  1654. Assert.Equal ([new (-4194304, -4194304, 8388608, 8388608)], region.GetRegionScans (matrix));
  1655. }
  1656. [Theory]
  1657. [InlineData (float.MaxValue)]
  1658. [InlineData (float.MinValue)]
  1659. [InlineData (float.NaN)]
  1660. [InlineData (float.PositiveInfinity)]
  1661. [InlineData (float.NegativeInfinity)]
  1662. public void Translate_InvalidFloatValue_EmptiesRegion (float f)
  1663. {
  1664. using Region region = new (new RectangleF (1, 2, 3, 4));
  1665. using Matrix matrix = new ();
  1666. region.Translate (f, 0);
  1667. Assert.True (region.IsEmpty (s_graphic));
  1668. Assert.False (region.IsInfinite (s_graphic));
  1669. Assert.Empty (region.GetRegionScans (matrix));
  1670. }
  1671. [Fact]
  1672. public void Translate_Disposed_ThrowsArgumentException ()
  1673. {
  1674. Region disposedRegion = CreateDisposedRegion ();
  1675. Assert.Throws<ArgumentException> (null, () => disposedRegion.Translate (1, 2));
  1676. Assert.Throws<ArgumentException> (null, () => disposedRegion.Translate (1f, 2f));
  1677. }
  1678. public static IEnumerable<object []> Xor_TestData ()
  1679. {
  1680. yield return new object []
  1681. {
  1682. new Region (new RectangleF (500, 30, 60, 80)),
  1683. new RectangleF [] { new (500, 30, 60, 80) },
  1684. new RectangleF[0]
  1685. };
  1686. yield return new object []
  1687. {
  1688. new Region (new RectangleF (500, 30, 60, 80)),
  1689. new RectangleF [] { RectangleF.Empty },
  1690. new RectangleF [] { new (500, 30, 60, 80) }
  1691. };
  1692. yield return new object []
  1693. {
  1694. new Region (new RectangleF (0, 0, 0, 0)),
  1695. new RectangleF [] { new (500, 30, 60, 80) },
  1696. new RectangleF [] { new (500, 30, 60, 80) }
  1697. };
  1698. yield return new object []
  1699. {
  1700. new Region (),
  1701. new RectangleF [] { new (520, 40, 60, 80) },
  1702. new RectangleF []
  1703. {
  1704. new (-4194304, -4194304, 8388608, 4194344),
  1705. new (-4194304, 40, 4194824, 80),
  1706. new (580, 40, 4193724, 80),
  1707. new (-4194304, 120, 8388608, 4194184)
  1708. }
  1709. };
  1710. yield return new object []
  1711. {
  1712. new Region (),
  1713. new RectangleF [] { RectangleF.Empty },
  1714. new RectangleF [] { new Rectangle (-4194304, -4194304, 8388608, 8388608) }
  1715. };
  1716. yield return new object []
  1717. {
  1718. new Region (new RectangleF (380, 30, 60, 80)),
  1719. new RectangleF [] { new (410, 40, 60, 80) },
  1720. new RectangleF []
  1721. {
  1722. new (380, 30, 60, 10),
  1723. new (380, 40, 30, 70),
  1724. new (440, 40, 30, 70),
  1725. new (410, 110, 60, 10)
  1726. }
  1727. };
  1728. }
  1729. [Theory]
  1730. [MemberData (nameof (Xor_TestData))]
  1731. public void Xor_Region_Success (Region region, RectangleF [] rectangles, RectangleF [] expectedScans)
  1732. {
  1733. using (region)
  1734. {
  1735. foreach (RectangleF rect in rectangles)
  1736. {
  1737. using Region other = new (rect);
  1738. region.Xor (other);
  1739. }
  1740. using Matrix matrix = new ();
  1741. Assert.Equal (expectedScans, region.GetRegionScans (matrix));
  1742. }
  1743. }
  1744. [Fact]
  1745. public void Xor_InfiniteRegion_Success ()
  1746. {
  1747. using Region region = new (new Rectangle (1, 2, 3, 4));
  1748. using Region other = new ();
  1749. using Matrix matrix = new ();
  1750. region.Xor (other);
  1751. Assert.Equal (
  1752. [
  1753. new (-4194304, -4194304, 8388608, 4194306),
  1754. new (-4194304, 2, 4194305, 4),
  1755. new (4, 2, 4194300, 4),
  1756. new (-4194304, 6, 8388608, 4194298)
  1757. ],
  1758. region.GetRegionScans (matrix));
  1759. }
  1760. [Fact]
  1761. public void Xor_NullRegion_ThrowsArgumentNullException ()
  1762. {
  1763. using Region region = new ();
  1764. Assert.Throws<ArgumentNullException> ("region", () => region.Xor ((Region)null));
  1765. }
  1766. [Fact]
  1767. public void Xor_DisposedRegion_ThrowsArgumentException ()
  1768. {
  1769. using Region region = new ();
  1770. Assert.Throws<ArgumentException> (null, () => region.Xor (CreateDisposedRegion ()));
  1771. }
  1772. [Fact]
  1773. public void Xor_SameRegion_ThrowsInvalidOperationException ()
  1774. {
  1775. using Region region = new ();
  1776. Assert.Throws<InvalidOperationException> (() => region.Xor (region));
  1777. }
  1778. [Theory]
  1779. [MemberData (nameof (Xor_TestData))]
  1780. public void Xor_Rectangle_Success (Region region, RectangleF [] rectangles, RectangleF [] expectedScans)
  1781. {
  1782. using (region)
  1783. {
  1784. foreach (RectangleF rect in rectangles)
  1785. {
  1786. region.Xor (new Rectangle ((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height));
  1787. }
  1788. using Matrix matrix = new ();
  1789. Assert.Equal (expectedScans, region.GetRegionScans (matrix));
  1790. }
  1791. }
  1792. [Theory]
  1793. [MemberData (nameof (Xor_TestData))]
  1794. public void Xor_RectangleF_Success (Region region, RectangleF [] rectangles, RectangleF [] expectedScans)
  1795. {
  1796. using (region)
  1797. {
  1798. foreach (RectangleF rect in rectangles)
  1799. {
  1800. region.Xor (rect);
  1801. }
  1802. using Matrix matrix = new ();
  1803. Assert.Equal (expectedScans, region.GetRegionScans (matrix));
  1804. }
  1805. }
  1806. [Theory]
  1807. [MemberData (nameof (Xor_TestData))]
  1808. public void Xor_GraphicsPath_Success (Region region, RectangleF [] rectangles, RectangleF [] expectedScans)
  1809. {
  1810. using (region)
  1811. {
  1812. foreach (RectangleF rect in rectangles)
  1813. {
  1814. using GraphicsPath path = new ();
  1815. path.AddRectangle (rect);
  1816. region.Xor (path);
  1817. }
  1818. using Matrix matrix = new ();
  1819. Assert.Equal (expectedScans, region.GetRegionScans (matrix));
  1820. }
  1821. }
  1822. [Fact]
  1823. public void Xor_EmptyPathWithInfiniteRegion_MakesInfinite ()
  1824. {
  1825. using Region region = new ();
  1826. using GraphicsPath graphicsPath = new ();
  1827. region.Xor (graphicsPath);
  1828. Assert.True (region.IsInfinite (s_graphic));
  1829. }
  1830. [Fact]
  1831. public void Xor_NullGraphicsPath_ThrowsArgumentNullException ()
  1832. {
  1833. using Region region = new ();
  1834. Assert.Throws<ArgumentNullException> ("path", () => region.Xor ((GraphicsPath)null));
  1835. }
  1836. [Fact]
  1837. public void Xor_Disposed_ThrowsArgumentException ()
  1838. {
  1839. Region disposedRegion = CreateDisposedRegion ();
  1840. using GraphicsPath graphicsPath = new ();
  1841. using Region other = new ();
  1842. Assert.Throws<ArgumentException> (null, () => disposedRegion.Xor (graphicsPath));
  1843. Assert.Throws<ArgumentException> (null, () => disposedRegion.Xor (new Rectangle ()));
  1844. Assert.Throws<ArgumentException> (null, () => disposedRegion.Xor (new RectangleF ()));
  1845. Assert.Throws<ArgumentException> (null, () => disposedRegion.Xor (other));
  1846. }
  1847. }
  1848. #endif