- /** Creates a concrete vector path transformed through the given matrix. */
- public void addTo(Polygon ret, Affine a) {
- float NUMSTEPS = 5; // FIXME
- ret.x[0] = a.multiply_px(x[0], y[0]);
- ret.y[0] = a.multiply_py(x[0], y[0]);
-
- for(int i=0; i<numvertices; i++) {
- if (type[i] == TYPE_LINETO) {
- float rx = x[i+1];
- float ry = y[i+1];
- ret.add(a.multiply_px(rx, ry), a.multiply_py(rx, ry));
-
- } else if (type[i] == TYPE_MOVETO) {
- float rx = x[i+1];
- float ry = y[i+1];
- ret.newcontour();
- ret.add(a.multiply_px(rx, ry), a.multiply_py(rx, ry));
-
- } else if (type[i] == TYPE_ARCTO) {
- float rx = c1x[i];
- float ry = c1y[i];
- float phi = c2x[i];
- float fa = ((int)c2y[i]) >> 1;
- float fs = ((int)c2y[i]) & 1;
- float x1 = x[i];
- float y1 = y[i];
- float x2 = x[i+1];
- float y2 = y[i+1];
-
- // F.6.5: given x1,y1,x2,y2,fa,fs, compute cx,cy,theta1,dtheta
- float x1_ = (float)Math.cos(phi) * (x1 - x2) / 2 + (float)Math.sin(phi) * (y1 - y2) / 2;
- float y1_ = -1 * (float)Math.sin(phi) * (x1 - x2) / 2 + (float)Math.cos(phi) * (y1 - y2) / 2;
- float tmp = (float)Math.sqrt((rx * rx * ry * ry - rx * rx * y1_ * y1_ - ry * ry * x1_ * x1_) /
- (rx * rx * y1_ * y1_ + ry * ry * x1_ * x1_));
- float cx_ = (fa == fs ? -1 : 1) * tmp * (rx * y1_ / ry);
- float cy_ = (fa == fs ? -1 : 1) * -1 * tmp * (ry * x1_ / rx);
- float cx = (float)Math.cos(phi) * cx_ - (float)Math.sin(phi) * cy_ + (x1 + x2) / 2;
- float cy = (float)Math.sin(phi) * cx_ + (float)Math.cos(phi) * cy_ + (y1 + y2) / 2;
-
- // F.6.4 Conversion from center to endpoint parameterization
- float ux = 1, uy = 0, vx = (x1_ - cx_) / rx, vy = (y1_ - cy_) / ry;
- float det = ux * vy - uy * vx;
- float theta1 = (det < 0 ? -1 : 1) *
- (float)Math.acos((ux * vx + uy * vy) /
- ((float)Math.sqrt(ux * ux + uy * uy) * (float)Math.sqrt(vx * vx + vy * vy)));
- ux = (x1_ - cx_) / rx; uy = (y1_ - cy_) / ry;
- vx = (-1 * x1_ - cx_) / rx; vy = (-1 * y1_ - cy_) / ry;
- det = ux * vy - uy * vx;
- float dtheta = (det < 0 ? -1 : 1) *
- (float)Math.acos((ux * vx + uy * vy) /
- ((float)Math.sqrt(ux * ux + uy * uy) * (float)Math.sqrt(vx * vx + vy * vy)));
- dtheta = dtheta % (float)(2 * Math.PI);
-
- if (fs == 0 && dtheta > 0) theta1 -= 2 * PI;
- if (fs == 1 && dtheta < 0) theta1 += 2 * PI;
-
- if (fa == 1 && dtheta < 0) dtheta = 2 * PI + dtheta;
- else if (fa == 1 && dtheta > 0) dtheta = -1 * (2 * PI - dtheta);
-
- // FIXME: integrate F.6.6
- // FIXME: isn't quite ending where it should...
-
- // F.6.3: Parameterization alternatives
- float theta = theta1;
- for(int j=0; j<NUMSTEPS; j++) {
- float rasterx = rx * (float)Math.cos(theta) * (float)Math.cos(phi) -
- ry * (float)Math.sin(theta) * (float)Math.sin(phi) + cx;
- float rastery = rx * (float)Math.cos(theta) * (float)Math.sin(phi) +
- ry * (float)Math.cos(phi) * (float)Math.sin(theta) + cy;
- ret.add(a.multiply_px(rasterx, rastery), a.multiply_py(rasterx, rastery));
- theta += dtheta / NUMSTEPS;
- }
-
- } else if (type[i] == TYPE_CUBIC) {
-
- float ax = x[i+1] - 3 * c2x[i] + 3 * c1x[i] - x[i];
- float bx = 3 * c2x[i] - 6 * c1x[i] + 3 * x[i];
- float cx = 3 * c1x[i] - 3 * x[i];
- float dx = x[i];
- float ay = y[i+1] - 3 * c2y[i] + 3 * c1y[i] - y[i];
- float by = 3 * c2y[i] - 6 * c1y[i] + 3 * y[i];
- float cy = 3 * c1y[i] - 3 * y[i];
- float dy = y[i];
-
- float x0 = a.multiply_px(x[i], y[i]);
- float y0 = a.multiply_py(x[i], y[i]);
- float x1 = a.multiply_px(x[i+1], y[i+1]);
- float y1 = a.multiply_py(x[i+1], y[i+1]);
- float steps = (float)Math.sqrt( (x1-x0) * (x1-x0) + (y1-y0) * (y1-y0) );
-
- for(float t=0; t<1; t += 1 / (steps/20)) {
- float rx = ax * t * t * t + bx * t * t + cx * t + dx;
- float ry = ay * t * t * t + by * t * t + cy * t + dy;
- ret.add(a.multiply_px(rx, ry), a.multiply_py(rx, ry));
- }
-
-
- } else if (type[i] == TYPE_QUADRADIC) {
-
- float bx = x[i+1] - 2 * c1x[i] + x[i];
- float cx = 2 * c1x[i] - 2 * x[i];
- float dx = x[i];
- float by = y[i+1] - 2 * c1y[i] + y[i];
- float cy = 2 * c1y[i] - 2 * y[i];
- float dy = y[i];
-
- float x0 = a.multiply_px(x[i], y[i]);
- float y0 = a.multiply_py(x[i], y[i]);
- float x1 = a.multiply_px(x[i+1], y[i+1]);
- float y1 = a.multiply_py(x[i+1], y[i+1]);
- float steps = (float)Math.sqrt( (x1-x0) * (x1-x0) + (y1-y0) * (y1-y0) );
-
- for(float t=0; t<1; t += 1 / (steps/20)) {
- float rx = bx * t * t + cx * t + dx;
- float ry = by * t * t + cy * t + dy;
- ret.add(a.multiply_px(rx, ry), a.multiply_py(rx, ry));
- }
-
- }
- }
- }
-