summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2013-10-28 23:01:28 (GMT)
committer Michael Drake <tlsa@netsurf-browser.org>2013-10-28 23:01:28 (GMT)
commit5c62d4740b6691ad0cd05863da47ec92e5f0cd7f (patch)
tree2aa83ac3c2b73c587302b23d2db0b01298968984
parent35df6a39826009e8dd7ec9d2724afcdca5789e10 (diff)
downloadlibnsfb-5c62d4740b6691ad0cd05863da47ec92e5f0cd7f.tar.gz
libnsfb-5c62d4740b6691ad0cd05863da47ec92e5f0cd7f.tar.bz2
Add tiled bitmap plotting function.
-rw-r--r--include/libnsfb_plot.h4
-rw-r--r--include/plot.h5
-rw-r--r--src/plot/16bpp.c1
-rw-r--r--src/plot/24bpp.c1
-rw-r--r--src/plot/32bpp-xbgr8888.c1
-rw-r--r--src/plot/32bpp-xrgb8888.c1
-rw-r--r--src/plot/8bpp.c1
-rw-r--r--src/plot/api.c7
-rw-r--r--src/plot/common.c82
9 files changed, 102 insertions, 1 deletions
diff --git a/include/libnsfb_plot.h b/include/libnsfb_plot.h
index b3f86d1..a563e2c 100644
--- a/include/libnsfb_plot.h
+++ b/include/libnsfb_plot.h
@@ -154,6 +154,10 @@ bool nsfb_plot_copy(nsfb_t *srcfb, nsfb_bbox_t *srcbox, nsfb_t *dstfb, nsfb_bbox
*/
bool nsfb_plot_bitmap(nsfb_t *nsfb, const nsfb_bbox_t *loc, const nsfb_colour_t *pixel, int bmp_width, int bmp_height, int bmp_stride, bool alpha);
+/** Plot bitmap.
+ */
+bool nsfb_plot_bitmap_tiles(nsfb_t *nsfb, const nsfb_bbox_t *loc, int tiles_x, int tiles_y, const nsfb_colour_t *pixel, int bmp_width, int bmp_height, int bmp_stride, bool alpha);
+
/** Plot an 8 bit glyph.
*/
bool nsfb_plot_glyph8(nsfb_t *nsfb, nsfb_bbox_t *loc, const uint8_t *pixel, int pitch, nsfb_colour_t c);
diff --git a/include/plot.h b/include/plot.h
index 38bed61..4b1545d 100644
--- a/include/plot.h
+++ b/include/plot.h
@@ -61,6 +61,10 @@ typedef bool (nsfb_plotfn_ellipse_fill_t)(nsfb_t *nsfb, nsfb_bbox_t *ellipse, ns
*/
typedef bool (nsfb_plotfn_bitmap_t)(nsfb_t *nsfb, const nsfb_bbox_t *loc, const nsfb_colour_t *pixel, int bmp_width, int bmp_height, int bmp_stride, bool alpha);
+/** Plot tiled bitmap
+ */
+typedef bool (nsfb_plotfn_bitmap_tiles_t)(nsfb_t *nsfb, const nsfb_bbox_t *loc, int tiles_x, int tiles_y, const nsfb_colour_t *pixel, int bmp_width, int bmp_height, int bmp_stride, bool alpha);
+
/** Copy an area of screen
*
@@ -108,6 +112,7 @@ typedef struct nsfb_plotter_fns_s {
nsfb_plotfn_ellipse_fill_t *ellipse_fill;
nsfb_plotfn_arc_t *arc;
nsfb_plotfn_bitmap_t *bitmap;
+ nsfb_plotfn_bitmap_tiles_t *bitmap_tiles;
nsfb_plotfn_point_t *point;
nsfb_plotfn_copy_t *copy;
nsfb_plotfn_glyph8_t *glyph8;
diff --git a/src/plot/16bpp.c b/src/plot/16bpp.c
index d629944..4f9134f 100644
--- a/src/plot/16bpp.c
+++ b/src/plot/16bpp.c
@@ -114,6 +114,7 @@ const nsfb_plotter_fns_t _nsfb_16bpp_plotters = {
.fill = fill,
.point = point,
.bitmap = bitmap,
+ .bitmap_tiles = bitmap_tiles,
.glyph8 = glyph8,
.glyph1 = glyph1,
.readrect = readrect,
diff --git a/src/plot/24bpp.c b/src/plot/24bpp.c
index 0fa53e9..dc67f04 100644
--- a/src/plot/24bpp.c
+++ b/src/plot/24bpp.c
@@ -430,6 +430,7 @@ const nsfb_plotter_fns_t _nsfb_24bpp_plotters = {
.fill = fill,
.point = point,
.bitmap = bitmap,
+ .bitmap_tiles = bitmap_tiles,
.glyph8 = glyph8,
.glyph1 = glyph1,
.readrect = readrect,
diff --git a/src/plot/32bpp-xbgr8888.c b/src/plot/32bpp-xbgr8888.c
index 9050903..4c19688 100644
--- a/src/plot/32bpp-xbgr8888.c
+++ b/src/plot/32bpp-xbgr8888.c
@@ -62,6 +62,7 @@ const nsfb_plotter_fns_t _nsfb_32bpp_xbgr8888_plotters = {
.fill = fill,
.point = point,
.bitmap = bitmap,
+ .bitmap_tiles = bitmap_tiles,
.glyph8 = glyph8,
.glyph1 = glyph1,
.readrect = readrect,
diff --git a/src/plot/32bpp-xrgb8888.c b/src/plot/32bpp-xrgb8888.c
index 548c970..9b3d551 100644
--- a/src/plot/32bpp-xrgb8888.c
+++ b/src/plot/32bpp-xrgb8888.c
@@ -62,6 +62,7 @@ const nsfb_plotter_fns_t _nsfb_32bpp_xrgb8888_plotters = {
.fill = fill,
.point = point,
.bitmap = bitmap,
+ .bitmap_tiles = bitmap_tiles,
.glyph8 = glyph8,
.glyph1 = glyph1,
.readrect = readrect,
diff --git a/src/plot/8bpp.c b/src/plot/8bpp.c
index 0245542..4fef119 100644
--- a/src/plot/8bpp.c
+++ b/src/plot/8bpp.c
@@ -73,6 +73,7 @@ const nsfb_plotter_fns_t _nsfb_8bpp_plotters = {
.fill = fill,
.point = point,
.bitmap = bitmap,
+ .bitmap_tiles = bitmap_tiles,
.glyph8 = glyph8,
.glyph1 = glyph1,
.readrect = readrect,
diff --git a/src/plot/api.c b/src/plot/api.c
index 2b5b974..ba6afc8 100644
--- a/src/plot/api.c
+++ b/src/plot/api.c
@@ -165,7 +165,12 @@ nsfb_plot_copy(nsfb_t *srcfb,
bool nsfb_plot_bitmap(nsfb_t *nsfb, const nsfb_bbox_t *loc, const nsfb_colour_t *pixel, int bmp_width, int bmp_height, int bmp_stride, bool alpha)
{
- return nsfb->plotter_fns->bitmap(nsfb, loc, pixel, bmp_width, bmp_height, bmp_stride, alpha);
+ return nsfb->plotter_fns->bitmap(nsfb, loc, pixel, bmp_width, bmp_height, bmp_stride, alpha);
+}
+
+bool nsfb_plot_bitmap_tiles(nsfb_t *nsfb, const nsfb_bbox_t *loc, int tiles_x, int tiles_y, const nsfb_colour_t *pixel, int bmp_width, int bmp_height, int bmp_stride, bool alpha)
+{
+ return nsfb->plotter_fns->bitmap_tiles(nsfb, loc, tiles_x, tiles_y, pixel, bmp_width, bmp_height, bmp_stride, alpha);
}
/** Plot an 8 bit glyph.
diff --git a/src/plot/common.c b/src/plot/common.c
index 998e3a6..e1f4a7a 100644
--- a/src/plot/common.c
+++ b/src/plot/common.c
@@ -491,6 +491,88 @@ bitmap(nsfb_t *nsfb,
return true;
}
+static bool
+bitmap_tiles(nsfb_t *nsfb,
+ const nsfb_bbox_t *loc,
+ int tiles_x,
+ int tiles_y,
+ const nsfb_colour_t *pixel,
+ int bmp_width,
+ int bmp_height,
+ int bmp_stride,
+ bool alpha)
+{
+ nsfb_bbox_t render_area;
+ nsfb_bbox_t tloc;
+ int tx, ty;
+ int width = loc->x1 - loc->x0;
+ int height = loc->y1 - loc->y0;
+ bool ok = true;
+ bool set_dither = false; /* true iff we enabled dithering here */
+
+ /* Avoid pointless rendering */
+ if (width == 0 || height == 0)
+ return true;
+
+ render_area.x0 = loc->x0;
+ render_area.y0 = loc->y0;
+ render_area.x1 = loc->x0 + width * tiles_x;
+ render_area.y1 = loc->y0 + height * tiles_y;
+
+ if (!nsfb_plot_clip_ctx(nsfb, &render_area))
+ return true;
+
+ /* Enable error diffusion for paletted screens, if not already on,
+ * if not repeating in x direction */
+ if (tiles_x == 1 && nsfb->palette != NULL &&
+ nsfb_palette_dithering_on(nsfb->palette) == false) {
+ nsfb_palette_dither_init(nsfb->palette,
+ render_area.x1 - render_area.x0);
+ set_dither = true;
+ }
+
+ /* Given tile location is top left; start with that one. */
+ tloc = *loc;
+
+ if (width != bmp_width || height != bmp_height) {
+ /* Scaled */
+ for (ty = 0; ty < tiles_y; ty++) {
+ for (tx = 0; tx < tiles_x; tx++) {
+ ok &= bitmap_scaled(nsfb, &tloc, pixel,
+ bmp_width, bmp_height,
+ bmp_stride, alpha);
+ tloc.x0 += width;
+ tloc.x1 += width;
+ }
+ tloc.x0 = loc->x0;
+ tloc.y0 += height;
+ tloc.x1 = loc->x1;
+ tloc.y1 += height;
+ }
+ } else {
+ /* Unscaled */
+ for (ty = 0; ty < tiles_y; ty++) {
+ for (tx = 0; tx < tiles_x; tx++) {
+ ok &= bitmap(nsfb, &tloc, pixel,
+ bmp_width, bmp_height,
+ bmp_stride, alpha);
+ tloc.x0 += width;
+ tloc.x1 += width;
+ }
+ tloc.x0 = loc->x0;
+ tloc.y0 += height;
+ tloc.x1 = loc->x1;
+ tloc.y1 += height;
+ }
+ }
+
+ if (set_dither) {
+ nsfb_palette_dither_fini(nsfb->palette);
+ }
+
+ return ok;
+}
+
static bool readrect(nsfb_t *nsfb, nsfb_bbox_t *rect, nsfb_colour_t *buffer)
{
PLOT_TYPE *pvideo;