#ifndef _RASTER_PRIMITIVES_H_
#define _RASTER_PRIMITIVES_H_

#include <sys/cdefs.h>

__BEGIN_DECLS

/****************************************************************************************************************/

struct pixmap;
struct point;
struct rect;
struct region;

/****************************************************************************************************************/
//
// Drawing primitives
//

// Pixels
static __inline void pixmap_plot(struct pixmap *pix, int x, int y, uint pixel) {
  pix->pm_rops.plot(pix, x, y, pixel);
}

static __inline uint pixmap_getpixel(struct pixmap *pix, int x, int y) {
  return pix->pm_rops.getpixel(pix, x, y);
}

uint pixmap_getpixel_mono(struct pixmap *pm, int x, int y);

// Lines
static __inline void pixmap_line(struct pixmap *pix, int x1, int y1, int x2, int y2, uint pixel) {
  return pix->pm_rops.line(pix, x1, y1, x2, y2, pixel);
}

static __inline void pixmap_hline(struct pixmap *pix, int x1, int x2, int y, uint pixel) {
  return pix->pm_rops.line(pix, x1, y, x2, y, pixel);
}

static __inline void pixmap_vline(struct pixmap *pix, int x, int y1, int y2, uint pixel) {
  return pix->pm_rops.line(pix, x, y1, x, y2, pixel);
}

static __inline void pixmap_thick_line(struct pixmap *pix, int x1, int y1, int x2, int y2, uint pixel, uint width) {
  return pix->pm_rops.thick_line(pix, x1, y1, x2, y2, pixel, width);
}

// Rectangles
static __inline void pixmap_cls(struct pixmap *pix, uint pixel) { pix->pm_pops.cls(pix, pixel); }

static __inline void pixmap_box(struct pixmap *pix, int x, int y, int w, int h, uint pixel) {
  pix->pm_rops.box(pix, x, y, w, h, pixel);
}

static __inline void pixmap_box_rectangle(struct pixmap *pix, const struct rect *box, uint pixel) {
  pixmap_box(pix, box->x1, box->y1, box->x2-box->x1+1, box->y2-box->y1+1, pixel);
}

void pixmap_box_region(struct pixmap *pix, const struct region *reg, uint pixel);

// Rectangular fill
static __inline void pixmap_fill(struct pixmap *pix, int x, int y, int w, int h, uint pixel) {
  pix->pm_rops.fill(pix, x, y, w, h, pixel);
}

static __inline void pixmap_fill_rectangle(struct pixmap *pix, const struct rect *box, uint pixel) {
  pixmap_fill(pix, box->x1, box->y1, box->x2-box->x1+1, box->y2-box->y1+1, pixel);
}

void pixmap_fill_region(struct pixmap *pix, const struct region *reg, uint pixel);

// Circles
static __inline void pixmap_circle(struct pixmap *pix, int x0, int y0, int radius, uint pixel) {
  pix->pm_rops.circle(pix, x0, y0, radius, pixel);
}

static __inline void pixmap_fill_circle(struct pixmap *pix, int x0, int y0, int radius, uint pixel) {
  pix->pm_rops.fill_circle(pix, x0, y0, radius, pixel);
}

// Block transfers
void pixmap_blit_rectangle(struct pixmap *src, const struct rect *src_box,
			   struct pixmap *dst, int dst_x, int dst_y);

void pixmap_blit_region(struct pixmap *src, const struct region *src_reg,
			struct pixmap *dst, int dst_x, int dst_y);

void pixmap_blit_single(struct pixmap *src, int src_x, int src_y, int width, int height,
                        struct pixmap *dst, int dst_x, int dst_y);

static inline void pixmap_blit(struct pixmap *src, int src_x, int src_y, int width, int height,
                               struct pixmap *dst, int dst_x, int dst_y) {
  dst->pm_rops.blit(src, src_x, src_y, width, height, dst, dst_x, dst_y);
}

struct pixmap_tile_blit_param {
  // Source area
  struct pixmap *src;
  int sx, sy, sw, sh;

  // Destination area
  struct pixmap *dst;
  int dx, dy, dw, dh;

  // Corner size
  int cow, coh;

  // Debug flags
  uint debug;
};

void pixmap_tile_blit(const struct pixmap_tile_blit_param *bp);

// Dithering
void pixmap_dither(struct pixmap *pix);

/****************************************************************************************************************/
__END_DECLS
#endif
