Advertisement
honey_the_codewitch

rasterize routine

Dec 11th, 2023
592
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.62 KB | None | 0 0
  1. static void svg_rasterize_sorted_edges(NSVGrasterizer* r, float tx, float ty, float scale, svg_cached_paint* cache, svg_fill_rule fillRule) {
  2.     svg_active_edge* active = NULL;
  3.     int y, s;
  4.     int e = 0;
  5.     int maxWeight = (255 / NSVG__SUBSAMPLES);  // weight per vertical scanline
  6.     int xmin, xmax;
  7.  
  8.     for (y = 0; y < r->height; y++) {
  9.         memset(r->scanline, 0, r->width);
  10.         xmin = r->width;
  11.         xmax = 0;
  12.         for (s = 0; s < NSVG__SUBSAMPLES; ++s) {
  13.             // find center of pixel for this scanline
  14.             float scany = (float)(y * NSVG__SUBSAMPLES + s) + 0.5f;
  15.             svg_active_edge** step = &active;
  16.  
  17.             // update all active edges;
  18.             // remove all active edges that terminate before the center of this scanline
  19.             while (*step) {
  20.                 svg_active_edge* z = *step;
  21.                 if (z->ey <= scany) {
  22.                     *step = z->next;  // delete from list
  23.                                       //                    NSVG__assert(z->valid);
  24.                     svg_free_active(r, z);
  25.                 } else {
  26.                     z->x += z->dx;            // advance to position for current scanline
  27.                     step = &((*step)->next);  // advance through list
  28.                 }
  29.             }
  30.  
  31.             // resort the list if needed
  32.             for (;;) {
  33.                 int changed = 0;
  34.                 step = &active;
  35.                 while (*step && (*step)->next) {
  36.                     if ((*step)->x > (*step)->next->x) {
  37.                         svg_active_edge* t = *step;
  38.                         svg_active_edge* q = t->next;
  39.                         t->next = q->next;
  40.                         q->next = t;
  41.                         *step = q;
  42.                         changed = 1;
  43.                     }
  44.                     step = &(*step)->next;
  45.                 }
  46.                 if (!changed) break;
  47.             }
  48.  
  49.             // insert all edges that start before the center of this scanline -- omit ones that also end on this scanline
  50.             while (e < r->nedges && r->edges[e].y0 <= scany) {
  51.                 if (r->edges[e].y1 > scany) {
  52.                     svg_active_edge* z = svg_add_active(r, &r->edges[e], scany);
  53.                     if (z == NULL) break;
  54.                     // find insertion point
  55.                     if (active == NULL) {
  56.                         active = z;
  57.                     } else if (z->x < active->x) {
  58.                         // insert at front
  59.                         z->next = active;
  60.                         active = z;
  61.                     } else {
  62.                         // find thing to insert AFTER
  63.                         svg_active_edge* p = active;
  64.                         while (p->next && p->next->x < z->x)
  65.                             p = p->next;
  66.                         // at this point, p->next->x is NOT < z->x
  67.                         z->next = p->next;
  68.                         p->next = z;
  69.                     }
  70.                 }
  71.                 e++;
  72.             }
  73.  
  74.             // now process all active edges in non-zero fashion
  75.             if (active != NULL)
  76.                 svg_fill_active_edges(r->scanline, r->width, active, maxWeight, &xmin, &xmax, fillRule);
  77.         }
  78.         // Blit
  79.         if (xmin < 0) xmin = 0;
  80.         if (xmax > r->width - 1) xmax = r->width - 1;
  81.         if (xmin <= xmax) {
  82.             svg_scanline_solid(r->bitmap != nullptr ? &r->bitmap[y * r->stride] + xmin * 4 : nullptr, r->readCallback, r->readCallbackState, r->writeCallback, r->writeCallbackState, xmax - xmin + 1, &r->scanline[xmin], xmin, y, tx, ty, scale, cache);
  83.         }
  84.     }
  85. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement