enum TFPPenType { ptNormal, ptRect, ptPoint, ptHorz, ptVert };

template
class TFPPen: public TDFFunctorBase                     // the DFFunctorBase defines empty ('static virtual') functions that are called by the algorithms
{
    T Pred;                                             // the functor that builds the next (not necessarily final) layer of drawing (usually a pixel drawer)
    int Width;
    TFPPenType Type;
    TPointCollector Points;                             // to store the points in case the brush is relatively big and for performance issues we want to avoid calculating the intermediate coordinates from pixel to pixel

    void GenPoints() {
      TPointCollector pc;
      ScanCirclePoints(0, 0, Width, DFWrapper(pc));
      ScanEllipseShape(pc, DFWrapper(Points));
      }

  public:

    TFPPen(): Width(0) {}
    TFPPen(TFPPenType pt, T pred, int w): Pred(pred) {
      Width = w;
      SetType(pt);
      }

    void SetType(TFPPenType pt) {
      Type = pt;

      switch (pt) {
        case ptPoint:
          GenPoints();
          break;

        default:
          Points.clear();
        }
      }

    void SetWidth(int w) {
      Width = w;

      switch (Type) {
        case ptPoint:
          GenPoints();
          break;

        default:
          Points.clear();
        }
      }

    // the functor method, here we receive the coordinates from the geometric algorithm
    void operator()(int x, int y, int pixelcolor = -1) {
      switch (Type) {
        case ptNormal:
          Pred(x, y, pixelcolor);
          break;

        case ptRect:
          for (int yy = y - Width; yy <= y + Width; yy++)
            for (int xx = x - Width; xx <= x + Width; xx++)
              Pred(xx, yy, pixelcolor);
          break;

        case ptPoint:
          for (FIXPOINT *p = Points.begin(); p != Points.end(); p++)
            Pred(x + p->x, y + p->y, pixelcolor);
          break;

        case ptHorz:
          for (int xx = x - Width; xx <= x + Width; xx++)
            Pred(xx, y, pixelcolor);
          break;

        case ptVert:
          for (int yy = y - Width; yy <= y + Width; yy++)
            Pred(x, yy, pixelcolor);
          break;
        }
      }
};

// generate a pen object with the propert functor type
template
TFPPen Pen(TFPPenType type, T pred, int w)
{
  return TFPPen(type, pred, w);
}

Attila NAGY Last updated: 2018-08-30