@@ -182,6 +182,7 @@ private static void RasterizeCoreRows(
182182 maxBandRows ,
183183 options . IntersectionRule ,
184184 options . RasterizationMode ,
185+ options . AntialiasThreshold ,
185186 allocator ,
186187 rowHandler ,
187188 ref reusableScratch ) )
@@ -199,6 +200,7 @@ private static void RasterizeCoreRows(
199200 maxBandRows ,
200201 options . IntersectionRule ,
201202 options . RasterizationMode ,
203+ options . AntialiasThreshold ,
202204 allocator ,
203205 rowHandler ,
204206 ref reusableScratch ) ;
@@ -216,6 +218,9 @@ private static void RasterizeCoreRows(
216218 /// <param name="maxBandRows">Maximum rows per reusable scratch band.</param>
217219 /// <param name="intersectionRule">Fill rule.</param>
218220 /// <param name="rasterizationMode">Coverage mode (AA or aliased).</param>
221+ /// <param name="antialiasThreshold">
222+ /// Antialiasing threshold in [0, 1] when <paramref name="rasterizationMode"/> is AA.
223+ /// </param>
219224 /// <param name="allocator">Temporary buffer allocator.</param>
220225 /// <param name="rowHandler">Coverage row callback invoked once per emitted row.</param>
221226 /// <param name="reusableScratch">
@@ -232,6 +237,7 @@ private static void RasterizeSequentialBands(
232237 int maxBandRows ,
233238 IntersectionRule intersectionRule ,
234239 RasterizationMode rasterizationMode ,
240+ float antialiasThreshold ,
235241 MemoryAllocator allocator ,
236242 RasterizerCoverageRowHandler rowHandler ,
237243 ref WorkerScratch ? reusableScratch )
@@ -280,7 +286,7 @@ private static void RasterizeSequentialBands(
280286 continue ;
281287 }
282288
283- Context context = scratch . CreateContext ( currentBandHeight , intersectionRule , rasterizationMode ) ;
289+ Context context = scratch . CreateContext ( currentBandHeight , intersectionRule , rasterizationMode , antialiasThreshold ) ;
284290 context . RasterizeEdgeTable ( sortedEdges . Slice ( start , length ) , bandTop ) ;
285291 context . EmitCoverageRows ( interestTop + bandTop , scratch . Scanline , rowHandler ) ;
286292 context . ResetTouchedRows ( ) ;
@@ -301,6 +307,9 @@ private static void RasterizeSequentialBands(
301307 /// <param name="maxBandRows">Maximum rows per worker scratch context.</param>
302308 /// <param name="intersectionRule">Fill rule.</param>
303309 /// <param name="rasterizationMode">Coverage mode (AA or aliased).</param>
310+ /// <param name="antialiasThreshold">
311+ /// Antialiasing threshold in [0, 1] when <paramref name="rasterizationMode"/> is AA.
312+ /// </param>
304313 /// <param name="allocator">Temporary buffer allocator.</param>
305314 /// <param name="rowHandler">Coverage row callback invoked once per emitted row.</param>
306315 /// <param name="reusableScratch">Caller-managed scratch. Reused when compatible; replaced and updated in place otherwise.</param>
@@ -319,6 +328,7 @@ private static bool TryRasterizeParallel(
319328 int maxBandRows ,
320329 IntersectionRule intersectionRule ,
321330 RasterizationMode rasterizationMode ,
331+ float antialiasThreshold ,
322332 MemoryAllocator allocator ,
323333 RasterizerCoverageRowHandler rowHandler ,
324334 ref WorkerScratch ? reusableScratch )
@@ -344,6 +354,7 @@ private static bool TryRasterizeParallel(
344354 coverStride ,
345355 intersectionRule ,
346356 rasterizationMode ,
357+ antialiasThreshold ,
347358 allocator ,
348359 rowHandler ,
349360 ref reusableScratch ) ;
@@ -398,7 +409,7 @@ private static bool TryRasterizeParallel(
398409 if ( length > 0 )
399410 {
400411 ReadOnlySpan < EdgeData > tileEdges = sortedEdgesMemory . Span . Slice ( start , length ) ;
401- context = worker . CreateContext ( bandHeight , intersectionRule , rasterizationMode ) ;
412+ context = worker . CreateContext ( bandHeight , intersectionRule , rasterizationMode , antialiasThreshold ) ;
402413 context . RasterizeEdgeTable ( tileEdges , bandTop ) ;
403414 hasCoverage = true ;
404415 context . EmitCoverageRows ( interestTop + bandTop , worker . Scanline , rowHandler ) ;
@@ -435,6 +446,9 @@ private static bool TryRasterizeParallel(
435446 /// <param name="coverStride">Cover-area stride in ints.</param>
436447 /// <param name="intersectionRule">Fill rule.</param>
437448 /// <param name="rasterizationMode">Coverage mode (AA or aliased).</param>
449+ /// <param name="antialiasThreshold">
450+ /// Antialiasing threshold in [0, 1] when <paramref name="rasterizationMode"/> is AA.
451+ /// </param>
438452 /// <param name="allocator">Temporary buffer allocator.</param>
439453 /// <param name="rowHandler">Coverage row callback invoked once per emitted row.</param>
440454 /// <param name="reusableScratch">
@@ -450,6 +464,7 @@ private static void RasterizeSingleTileDirect(
450464 int coverStride ,
451465 IntersectionRule intersectionRule ,
452466 RasterizationMode rasterizationMode ,
467+ float antialiasThreshold ,
453468 MemoryAllocator allocator ,
454469 RasterizerCoverageRowHandler rowHandler ,
455470 ref WorkerScratch ? reusableScratch )
@@ -462,7 +477,7 @@ private static void RasterizeSingleTileDirect(
462477 }
463478
464479 WorkerScratch scratch = reusableScratch ;
465- Context context = scratch . CreateContext ( height , intersectionRule , rasterizationMode ) ;
480+ Context context = scratch . CreateContext ( height , intersectionRule , rasterizationMode , antialiasThreshold ) ;
466481 context . RasterizeEdgeTable ( edges , bandTop : 0 ) ;
467482 context . EmitCoverageRows ( interestTop , scratch . Scanline , rowHandler ) ;
468483 context . ResetTouchedRows ( ) ;
@@ -865,6 +880,7 @@ internal ref struct Context
865880 private readonly int coverStride ;
866881 private readonly IntersectionRule intersectionRule ;
867882 private readonly RasterizationMode rasterizationMode ;
883+ private readonly float antialiasThreshold ;
868884 private int touchedRowCount ;
869885
870886 /// <summary>
@@ -884,7 +900,8 @@ public Context(
884900 int wordsPerRow ,
885901 int coverStride ,
886902 IntersectionRule intersectionRule ,
887- RasterizationMode rasterizationMode )
903+ RasterizationMode rasterizationMode ,
904+ float antialiasThreshold )
888905 {
889906 this . bitVectors = bitVectors ;
890907 this . coverArea = coverArea ;
@@ -900,6 +917,7 @@ public Context(
900917 this . coverStride = coverStride ;
901918 this . intersectionRule = intersectionRule ;
902919 this . rasterizationMode = rasterizationMode ;
920+ this . antialiasThreshold = antialiasThreshold ;
903921 this . touchedRowCount = 0 ;
904922 }
905923
@@ -1252,8 +1270,9 @@ private readonly float AreaToCoverage(int area)
12521270
12531271 if ( this . rasterizationMode == RasterizationMode . Aliased )
12541272 {
1255- // Aliased mode quantizes final coverage to hard 0/1 per pixel.
1256- return coverage >= 0.5F ? 1F : 0F ;
1273+ // Aliased mode quantizes final coverage to hard 0/1 per pixel
1274+ // using the configurable threshold from GraphicsOptions.AntialiasThreshold.
1275+ return coverage >= this . antialiasThreshold ? 1F : 0F ;
12571276 }
12581277
12591278 return coverage ;
@@ -2156,7 +2175,7 @@ public static WorkerScratch Create(MemoryAllocator allocator, int wordsPerRow, i
21562175 /// <summary>
21572176 /// Creates a context view over this scratch for the requested band height.
21582177 /// </summary>
2159- public Context CreateContext ( int bandHeight , IntersectionRule intersectionRule , RasterizationMode rasterizationMode )
2178+ public Context CreateContext ( int bandHeight , IntersectionRule intersectionRule , RasterizationMode rasterizationMode , float antialiasThreshold )
21602179 {
21612180 if ( ( uint ) bandHeight > ( uint ) this . tileCapacity )
21622181 {
@@ -2179,7 +2198,8 @@ public Context CreateContext(int bandHeight, IntersectionRule intersectionRule,
21792198 this . wordsPerRow ,
21802199 this . coverStride ,
21812200 intersectionRule ,
2182- rasterizationMode ) ;
2201+ rasterizationMode ,
2202+ antialiasThreshold ) ;
21832203 }
21842204
21852205 /// <summary>
0 commit comments