point dotneato_closest(splines * spl, point p) { int i, j, k, besti, bestj; double bestdist2, d2, dlow2, dhigh2; /* squares of distances */ double low, high, t; pointf c[4], pt2, pt; point rv; bezier bz; besti = bestj = -1; bestdist2 = 1e+38; P2PF(p, pt); for (i = 0; i < spl->size; i++) { bz = spl->list[i]; for (j = 0; j < bz.size; j++) { pointf b; b.x = bz.list[j].x; b.y = bz.list[j].y; d2 = DIST2(b, pt); if ((bestj == -1) || (d2 < bestdist2)) { besti = i; bestj = j; bestdist2 = d2; } } } bz = spl->list[besti]; j = bestj / 3; if (j >= spl->size) j--; for (k = 0; k < 4; k++) { c[k].x = bz.list[j + k].x; c[k].y = bz.list[j + k].y; } low = 0.0; high = 1.0; dlow2 = DIST2(c[0], pt); dhigh2 = DIST2(c[3], pt); do { t = (low + high) / 2.0; pt2 = Bezier(c, 3, t, NULL, NULL); if (fabs(dlow2 - dhigh2) < 1.0) break; if (fabs(high - low) < .00001) break; if (dlow2 < dhigh2) { high = t; dhigh2 = DIST2(pt2, pt); } else { low = t; dlow2 = DIST2(pt2, pt); } } while (1); PF2P(pt2, rv); return rv; }
static void emit_html_img(GVJ_t * job, htmlimg_t * cp, htmlenv_t * env) { pointf A[4]; box bb = cp->box; bb.LL.x += env->p.x; bb.LL.y += env->p.y; bb.UR.x += env->p.x; bb.UR.y += env->p.y; P2PF(bb.UR, A[0]); P2PF(bb.LL, A[2]); A[1].x = A[2].x; A[1].y = A[0].y; A[3].x = A[0].x; A[3].y = A[2].y; gvrender_usershape(job, cp->src, A, 4, true); }