Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- static void svg_rasterize_sorted_edges(NSVGrasterizer* r, float tx, float ty, float scale, svg_cached_paint* cache, svg_fill_rule fillRule) {
- svg_active_edge* active = NULL;
- int y, s;
- int e = 0;
- int maxWeight = (255 / NSVG__SUBSAMPLES); // weight per vertical scanline
- int xmin, xmax;
- for (y = 0; y < r->height; y++) {
- memset(r->scanline, 0, r->width);
- xmin = r->width;
- xmax = 0;
- for (s = 0; s < NSVG__SUBSAMPLES; ++s) {
- // find center of pixel for this scanline
- float scany = (float)(y * NSVG__SUBSAMPLES + s) + 0.5f;
- svg_active_edge** step = &active;
- // update all active edges;
- // remove all active edges that terminate before the center of this scanline
- while (*step) {
- svg_active_edge* z = *step;
- if (z->ey <= scany) {
- *step = z->next; // delete from list
- // NSVG__assert(z->valid);
- svg_free_active(r, z);
- } else {
- z->x += z->dx; // advance to position for current scanline
- step = &((*step)->next); // advance through list
- }
- }
- // resort the list if needed
- for (;;) {
- int changed = 0;
- step = &active;
- while (*step && (*step)->next) {
- if ((*step)->x > (*step)->next->x) {
- svg_active_edge* t = *step;
- svg_active_edge* q = t->next;
- t->next = q->next;
- q->next = t;
- *step = q;
- changed = 1;
- }
- step = &(*step)->next;
- }
- if (!changed) break;
- }
- // insert all edges that start before the center of this scanline -- omit ones that also end on this scanline
- while (e < r->nedges && r->edges[e].y0 <= scany) {
- if (r->edges[e].y1 > scany) {
- svg_active_edge* z = svg_add_active(r, &r->edges[e], scany);
- if (z == NULL) break;
- // find insertion point
- if (active == NULL) {
- active = z;
- } else if (z->x < active->x) {
- // insert at front
- z->next = active;
- active = z;
- } else {
- // find thing to insert AFTER
- svg_active_edge* p = active;
- while (p->next && p->next->x < z->x)
- p = p->next;
- // at this point, p->next->x is NOT < z->x
- z->next = p->next;
- p->next = z;
- }
- }
- e++;
- }
- // now process all active edges in non-zero fashion
- if (active != NULL)
- svg_fill_active_edges(r->scanline, r->width, active, maxWeight, &xmin, &xmax, fillRule);
- }
- // Blit
- if (xmin < 0) xmin = 0;
- if (xmax > r->width - 1) xmax = r->width - 1;
- if (xmin <= xmax) {
- 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);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement