protected void ellipseImpl(float x, float y, float w, float h) {
    if (smooth || (strokeWeight != 1) ||
        fillAlpha || strokeAlpha || ctm.isWarped()) {
      // identical to PGraphics version, but uses POLYGON 
      // for the fill instead of a TRIANGLE_FAN
      float radiusH = w / 2;
      float radiusV = h / 2;

      float centerX = x + radiusH;
      float centerY = y + radiusV;
      
      float sx1 = screenX(x, y);
      float sy1 = screenY(x, y);
      float sx2 = screenX(x+w, y+h);
      float sy2 = screenY(x+w, y+h);
      int accuracy = (int) (TWO_PI * PApplet.dist(sx1, sy1, sx2, sy2) / 8);
      if (accuracy < 4) return;  // don't bother?
      //System.out.println("diameter " + w + " " + h + " -> " + accuracy);

      float inc = (float)SINCOS_LENGTH / accuracy;

      float val = 0;

      if (fill) {
        boolean savedStroke = stroke;
        stroke = false;

        beginShape();
        for (int i = 0; i < accuracy; i++) {
          vertex(centerX + cosLUT[(int) val] * radiusH,
                 centerY + sinLUT[(int) val] * radiusV);
          val += inc;
        }
        endShape(CLOSE);

        stroke = savedStroke;
      }

      if (stroke) {
        boolean savedFill = fill;
        fill = false;

        val = 0;
        beginShape();
        for (int i = 0; i < accuracy; i++) {
          vertex(centerX + cosLUT[(int) val] * radiusH,
                 centerY + sinLUT[(int) val] * radiusV);
          val += inc;
        }
        endShape(CLOSE);

        fill = savedFill;
      }
    } else {
      float hradius = w / 2f;
      float vradius = h / 2f;

      int centerX = (int) (x + hradius + ctm.m02);
      int centerY = (int) (y + vradius + ctm.m12);

      int hradiusi = (int) hradius;
      int vradiusi = (int) vradius;

      if (hradiusi == vradiusi) {
        if (fill) flat_circle_fill(centerX, centerY, hradiusi);
        if (stroke) flat_circle_stroke(centerX, centerY, hradiusi);

      } else {
        if (fill) flat_ellipse_internal(centerX, centerY, hradiusi, vradiusi, true);
        if (stroke) flat_ellipse_internal(centerX, centerY, hradiusi, vradiusi, false);
      }
    }
  }