/* Rotate a matrix, possibly in place. The angle is in degrees. */ int gs_matrix_rotate(const gs_matrix * pm, floatp ang, gs_matrix * pmr) { double mxx, mxy; gs_sincos_t sincos; gs_sincos_degrees(ang, &sincos); mxx = pm->xx, mxy = pm->xy; pmr->xx = sincos.cos * mxx + sincos.sin * pm->yx; pmr->xy = sincos.cos * mxy + sincos.sin * pm->yy; pmr->yx = sincos.cos * pm->yx - sincos.sin * mxx; pmr->yy = sincos.cos * pm->yy - sincos.sin * mxy; if (pmr != pm) { pmr->tx = pm->tx; pmr->ty = pm->ty; } return 0; }
static int gs_imager_arc_add(gx_path * ppath, gs_imager_state * pis, bool clockwise, floatp axc, floatp ayc, floatp arad, floatp aang1, floatp aang2, bool add_line, gs_point *p3) { double ar = arad; double ang1 = aang1, ang2 = aang2, anext; double ang1r; /* reduced angle */ arc_curve_params_t arc; int code; arc.ppath = ppath; arc.pis = pis; arc.center.x = axc; arc.center.y = ayc; if (ar < 0) { ang1 += 180; ang2 += 180; ar = -ar; } arc.radius = ar; arc.action = (add_line ? arc_lineto : arc_moveto); arc.notes = sn_none; arc.fast_quadrant = 0; ang1r = fmod(ang1, 360); gs_sincos_degrees(ang1r, &arc.sincos); arc.p3.x = axc + ar * arc.sincos.cos; arc.p3.y = ayc + ar * arc.sincos.sin; if (clockwise) { while (ang1 < ang2) ang2 -= 360; if (ang2 < 0) { double adjust = ceil(-ang2 / 360) * 360; ang1 += adjust, ang2 += adjust; } arc.angle = ang1; if (ang1 == ang2) goto last; /* Do the first part, up to a multiple of 90 degrees. */ if (!arc.sincos.orthogonal) { anext = floor(arc.angle / 90) * 90; if (anext < ang2) goto last; code = next_arc_curve(&arc, anext); if (code < 0) return code; arc.action = arc_nothing; arc.notes = sn_not_first; } /* Do multiples of 90 degrees. Invariant: ang1 >= ang2 >= 0. */ while ((anext = arc.angle - 90) >= ang2) { code = next_arc_quadrant(&arc, anext); if (code < 0) return code; arc.action = arc_nothing; arc.notes = sn_not_first; } } else { while (ang2 < ang1) ang2 += 360; if (ang1 < 0) { double adjust = ceil(-ang1 / 360) * 360; ang1 += adjust, ang2 += adjust; } arc.angle = ang1; if (ang1 == ang2) { code = next_arc_curve(&arc, ang2); if (code < 0) return code; *p3 = arc.p3; } /* Do the first part, up to a multiple of 90 degrees. */ if (!arc.sincos.orthogonal) { anext = ceil(arc.angle / 90) * 90; if (anext > ang2) goto last; code = next_arc_curve(&arc, anext); if (code < 0) return code; arc.action = arc_nothing; arc.notes = sn_not_first; } /* Do multiples of 90 degrees. Invariant: 0 <= ang1 <= ang2. */ while ((anext = arc.angle + 90) <= ang2) { code = next_arc_quadrant(&arc, anext); if (code < 0) return code; arc.action = arc_nothing; arc.notes = sn_not_first; } } /* * Do the last curve of the arc, if any. */ if (arc.angle == ang2) { *p3 = arc.p3; return 0; } last: code = next_arc_curve(&arc, ang2); if (code < 0) return code; *p3 = arc.p3; return 0; }