From 7ebff5169afecd39fcc9161761d88e792b703d82 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Sat, 19 Jul 2014 09:20:45 +0100 Subject: Move private headers out of include/ and into src/ To match our other libraries. --- src/cursor.h | 44 +++++++++++ src/nsfb.h | 49 ++++++++++++ src/palette.h | 238 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/plot.h | 129 +++++++++++++++++++++++++++++++ src/surface.h | 65 ++++++++++++++++ 5 files changed, 525 insertions(+) create mode 100644 src/cursor.h create mode 100644 src/nsfb.h create mode 100644 src/palette.h create mode 100644 src/plot.h create mode 100644 src/surface.h (limited to 'src') diff --git a/src/cursor.h b/src/cursor.h new file mode 100644 index 0000000..15751bd --- /dev/null +++ b/src/cursor.h @@ -0,0 +1,44 @@ +/* + * Copyright 2009 Vincent Sanders + * + * This file is part of libnsfb, http://www.netsurf-browser.org/ + * Licenced under the MIT License, + * http://www.opensource.org/licenses/mit-license.php + * + * This is the *internal* interface for the cursor. + */ + +#ifndef CURSOR_H +#define CURSOR_H 1 + +struct nsfb_cursor_s { + bool plotted; + nsfb_bbox_t loc; + + /* current cursor image */ + const nsfb_colour_t *pixel; + int bmp_width; + int bmp_height; + int bmp_stride; + int hotspot_x; + int hotspot_y; + + /* current saved image */ + nsfb_bbox_t savloc; + nsfb_colour_t *sav; + int sav_size; + int sav_width; + int sav_height; + +}; + +/** Plot the cursor saving the image underneath. */ +bool nsfb_cursor_plot(nsfb_t *nsfb, struct nsfb_cursor_s *cursor); + +/** Clear the cursor restoring the image underneath */ +bool nsfb_cursor_clear(nsfb_t *nsfb, struct nsfb_cursor_s *cursor); + +/** Destroy the cursor */ +bool nsfb_cursor_destroy(struct nsfb_cursor_s *cursor); + +#endif /* CURSOR_H */ diff --git a/src/nsfb.h b/src/nsfb.h new file mode 100644 index 0000000..9a61775 --- /dev/null +++ b/src/nsfb.h @@ -0,0 +1,49 @@ +/* + * Copyright 2009 Vincent Sanders + * + * This file is part of libnsfb, http://www.netsurf-browser.org/ + * Licenced under the MIT License, + * http://www.opensource.org/licenses/mit-license.php + * + * This is the internal interface for the libnsfb graphics library. + */ + +#ifndef _NSFB_H +#define _NSFB_H 1 + +#include + + +/** NS Framebuffer context + */ +struct nsfb_s { + int width; /**< Visible width. */ + int height; /**< Visible height. */ + + char *parameters; + + enum nsfb_format_e format; /**< Framebuffer format */ + int bpp; /**< Bits per pixel - distinct from format */ + + uint8_t *ptr; /**< Base of video memory. */ + int linelen; /**< length of a video line. */ + + struct nsfb_palette_s *palette; /**< palette for index modes */ + nsfb_cursor_t *cursor; /**< cursor */ + + struct nsfb_surface_rtns_s *surface_rtns; /**< surface routines. */ + void *surface_priv; /**< surface opaque data. */ + + nsfb_bbox_t clip; /**< current clipping rectangle for plotters */ + struct nsfb_plotter_fns_s *plotter_fns; /**< Plotter methods */ +}; + + +#endif + +/* + * Local variables: + * c-basic-offset: 4 + * tab-width: 8 + * End: + */ diff --git a/src/palette.h b/src/palette.h new file mode 100644 index 0000000..a853254 --- /dev/null +++ b/src/palette.h @@ -0,0 +1,238 @@ +/* + * Copyright 2012 Michael Drake + * + * This file is part of libnsfb, http://www.netsurf-browser.org/ + * Licenced under the MIT License, + * http://www.opensource.org/licenses/mit-license.php + * + * This is the *internal* interface for the cursor. + */ + +#ifndef PALETTE_H +#define PALETTE_H 1 + +#include +#include + +#include "libnsfb.h" +#include "libnsfb_plot.h" + +enum nsfb_palette_type_e { + NSFB_PALETTE_EMPTY, /**< empty palette object */ + NSFB_PALETTE_NSFB_8BPP, /**< libnsfb's own 8bpp palette */ + NSFB_PALETTE_OTHER /**< any other palette */ +}; + +struct nsfb_palette_s { + enum nsfb_palette_type_e type; /**< Palette type */ + uint8_t last; /**< Last used palette index */ + nsfb_colour_t data[256]; /**< Palette for index modes */ + + bool dither; /**< Whether error diffusion was requested */ + struct { + int width; /**< Length of error value buffer ring*/ + int current; /**< Current pos in ring buffer*/ + int *data; /**< Ring buffer error values */ + int data_len; /**< Max size of ring */ + } dither_ctx; +}; + + +/** Create an empty palette object. */ +bool nsfb_palette_new(struct nsfb_palette_s **palette, int width); + +/** Free a palette object. */ +void nsfb_palette_free(struct nsfb_palette_s *palette); + +/** Init error diffusion for a plot. */ +void nsfb_palette_dither_init(struct nsfb_palette_s *palette, int width); + +/** Finalise error diffusion after a plot. */ +void nsfb_palette_dither_fini(struct nsfb_palette_s *palette); + +/** Generate libnsfb 8bpp default palette. */ +void nsfb_palette_generate_nsfb_8bpp(struct nsfb_palette_s *palette); + +static inline bool nsfb_palette_dithering_on(struct nsfb_palette_s *palette) +{ + return palette->dither; +} + +/** Find best palette match for given colour. */ +static inline uint8_t nsfb_palette_best_match(struct nsfb_palette_s *palette, + nsfb_colour_t c, int *r_error, int *g_error, int *b_error) +{ + uint8_t best_col = 0; + + nsfb_colour_t palent; + int col; + int dr, dg, db; /* delta red, green blue values */ + + int cur_distance; + int best_distance = INT_MAX; + + int r = ( c & 0xFF); + int g = ((c >> 8) & 0xFF); + int b = ((c >> 16) & 0xFF); + + switch (palette->type) { + case NSFB_PALETTE_NSFB_8BPP: + /* Index into colour cube part */ + dr = ((r * 5) + 128) / 256; + dg = ((g * 7) + 128) / 256; + db = ((b * 4) + 128) / 256; + col = 40 * dr + 5 * dg + db; + + palent = palette->data[col]; + dr = r - ( palent & 0xFF); + dg = g - ((palent >> 8) & 0xFF); + db = b - ((palent >> 16) & 0xFF); + cur_distance = (dr * dr) + (dg * dg) + (db * db); + + best_col = col; + best_distance = cur_distance; + *r_error = dr; + *g_error = dg; + *b_error = db; + + /* Index into grayscale part */ + col = (r + g + b + (45 / 2)) / (15 * 3) - 1 + 240; + palent = palette->data[col]; + + dr = r - (palent & 0xFF); + dg = g - (palent & 0xFF); + db = b - (palent & 0xFF); + cur_distance = (dr * dr) + (dg * dg) + (db * db); + if (cur_distance < best_distance) { + best_col = col; + *r_error = dr; + *g_error = dg; + *b_error = db; + } + break; + + case NSFB_PALETTE_OTHER: + /* Try all colours in palette */ + for (col = 0; col <= palette->last; col++) { + palent = palette->data[col]; + + dr = r - ( palent & 0xFF); + dg = g - ((palent >> 8) & 0xFF); + db = b - ((palent >> 16) & 0xFF); + cur_distance = (dr * dr) + (dg * dg) + (db * db); + if (cur_distance < best_distance) { + best_distance = cur_distance; + best_col = col; + *r_error = dr; + *g_error = dg; + *b_error = db; + } + } + break; + + default: + break; + } + + return best_col; +} + +/** Find best palette match for given colour, with error diffusion. */ +static inline uint8_t nsfb_palette_best_match_dither( + struct nsfb_palette_s *palette, nsfb_colour_t c) +{ + int r, g, b; + int current; + int error; + int width = palette->dither_ctx.width; + int *data = palette->dither_ctx.data; + uint8_t best_col_index; + + if (palette == NULL) + return 0; + + if (palette->dither == false) + return nsfb_palette_best_match(palette, c, &r, &g, &b); + + current = palette->dither_ctx.current; + + /* Get RGB components of colour, and apply error */ + r = ( c & 0xFF) + data[current ]; + g = ((c >> 8) & 0xFF) + data[current + 1]; + b = ((c >> 16) & 0xFF) + data[current + 2]; + + /* Clamp new RGB components to range */ + if (r < 0) r = 0; + if (r > 255) r = 255; + if (g < 0) g = 0; + if (g > 255) g = 255; + if (b < 0) b = 0; + if (b > 255) b = 255; + + /* Reset error diffusion slots to 0 */ + data[current ] = 0; + data[current + 1] = 0; + data[current + 2] = 0; + + /* Rebuild colour from modified components */ + c = r + (g << 8) + (b << 16); + + /* Get best match for pixel, and find errors for each component */ + best_col_index = nsfb_palette_best_match(palette, c, &r, &g, &b); + + /* Advance one set of error diffusion slots */ + current += 3; + if (current >= width) + current = 0; + palette->dither_ctx.current = current; + + /* Save errors + * + * [*]-[N] + * / | \ + * [l]-[m]-[r] + */ + error = current; + + /* Error for [N] (next) */ + if (error != 0) { + /* The pixel exists */ + data[error ] += r * 7 / 16; + data[error + 1] += g * 7 / 16; + data[error + 2] += b * 7 / 16; + } + + error += width - 2 * 3; + if (error >= width) + error -= width; + /* Error for [l] (below, left) */ + if (error >= 0 && error != 3) { + /* The pixel exists */ + data[error ] += r * 3 / 16; + data[error + 1] += g * 3 / 16; + data[error + 2] += b * 3 / 16; + } + + error += 3; + if (error >= width) + error -= width; + /* Error for [m] (below, middle) */ + data[error ] += r * 5 / 16; + data[error + 1] += g * 5 / 16; + data[error + 2] += b * 5 / 16; + + error += 3; + if (error >= width) + error -= width; + /* Error for [r] (below, right) */ + if (error != 0) { + /* The pixel exists */ + data[error ] += r / 16; + data[error + 1] += g / 16; + data[error + 2] += b / 16; + } + + return best_col_index; +} + +#endif /* PALETTE_H */ diff --git a/src/plot.h b/src/plot.h new file mode 100644 index 0000000..4b1545d --- /dev/null +++ b/src/plot.h @@ -0,0 +1,129 @@ + + +/** Clears plotting area to a flat colour (if needed) + */ +typedef bool (nsfb_plotfn_clg_t)(nsfb_t *nsfb, nsfb_colour_t c); + +/** Plots a rectangle outline. The line can be solid, dotted or + * dashed. Top left corner at (x0,y0) and rectangle has given + * width and height. + */ +typedef bool (nsfb_plotfn_rectangle_t)(nsfb_t *nsfb, nsfb_bbox_t *rect, int line_width, nsfb_colour_t c, bool dotted, bool dashed); + +/** Plots a line using a given pen. + */ +typedef bool (nsfb_plotfn_line_t)(nsfb_t *nsfb, int linec, nsfb_bbox_t *line, nsfb_plot_pen_t *pen); + +/** Plots a filled polygon with straight lines between points. + * The lines around the edge of the ploygon are not plotted. The + * polygon is filled with the non-zero winding rule. + */ +typedef bool (nsfb_plotfn_polygon_t)(nsfb_t *nsfb, const int *p, unsigned int n, nsfb_colour_t fill); + +/** Plots a filled rectangle. Top left corner at (x0,y0), bottom + * right corner at (x1,y1). Note: (x0,y0) is inside filled area, + * but (x1,y1) is below and to the right. See diagram below. + */ +typedef bool (nsfb_plotfn_fill_t)(nsfb_t *nsfb, nsfb_bbox_t *rect, nsfb_colour_t c); + +/** Clipping operations. + */ +typedef bool (nsfb_plotfn_clip_t)(nsfb_t *nsfb, nsfb_bbox_t *clip); + +/** Plots an arc, around (x,y), from anticlockwise from angle1 to + * angle2. Angles are measured anticlockwise from horizontal, in + * degrees. + */ +typedef bool (nsfb_plotfn_arc_t)(nsfb_t *nsfb, int x, int y, int radius, int angle1, int angle2, nsfb_colour_t c); + +/** Plots a point. + * + * Plot a single alpha blended pixel. + */ +typedef bool (nsfb_plotfn_point_t)(nsfb_t *nsfb, int x, int y, nsfb_colour_t c); + +/** Plot an ellipse. + * + * plot an ellipse outline, note if teh bounding box is square this will plot a + * circle. + */ +typedef bool (nsfb_plotfn_ellipse_t)(nsfb_t *nsfb, nsfb_bbox_t *ellipse, nsfb_colour_t c); + +/** Plot a filled ellipse. + * + * plot a filled ellipse, note if the bounding box is square this will plot a + * circle. + */ +typedef bool (nsfb_plotfn_ellipse_fill_t)(nsfb_t *nsfb, nsfb_bbox_t *ellipse, nsfb_colour_t c); + + +/** Plot bitmap + */ +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 + * + * Copy an area of the display. + */ +typedef bool (nsfb_plotfn_copy_t)(nsfb_t *nsfb, nsfb_bbox_t *srcbox, nsfb_bbox_t *dstbox); + + +/** Plot an 8 bit per pixel glyph. + */ +typedef bool (nsfb_plotfn_glyph8_t)(nsfb_t *nsfb, nsfb_bbox_t *loc, const uint8_t *pixel, int pitch, nsfb_colour_t c); + + +/** Plot an 1 bit per pixel glyph. + */ +typedef bool (nsfb_plotfn_glyph1_t)(nsfb_t *nsfb, nsfb_bbox_t *loc, const uint8_t *pixel, int pitch, nsfb_colour_t c); + +/** Read rectangle of screen into buffer + */ +typedef bool (nsfb_plotfn_readrect_t)(nsfb_t *nsfb, nsfb_bbox_t *rect, nsfb_colour_t *buffer); + +/** Plot quadratic bezier spline + */ +typedef bool (nsfb_plotfn_quadratic_bezier_t)(nsfb_t *nsfb, nsfb_bbox_t *curve, nsfb_point_t *ctrla, nsfb_plot_pen_t *pen); + +/** Plot cubic bezier spline + */ +typedef bool (nsfb_plotfn_cubic_bezier_t)(nsfb_t *nsfb, nsfb_bbox_t *curve, nsfb_point_t *ctrla, nsfb_point_t *ctrlb, nsfb_plot_pen_t *pen); + +typedef bool (nsfb_plotfn_polylines_t)(nsfb_t *nsfb, int pointc, const nsfb_point_t *points, nsfb_plot_pen_t *pen); + +/** plot path */ +typedef bool (nsfb_plotfn_path_t)(nsfb_t *nsfb, int pathc, nsfb_plot_pathop_t *pathop, nsfb_plot_pen_t *pen); + +/** plotter function table. */ +typedef struct nsfb_plotter_fns_s { + nsfb_plotfn_clg_t *clg; + nsfb_plotfn_rectangle_t *rectangle; + nsfb_plotfn_line_t *line; + nsfb_plotfn_polygon_t *polygon; + nsfb_plotfn_fill_t *fill; + nsfb_plotfn_clip_t *get_clip; + nsfb_plotfn_clip_t *set_clip; + nsfb_plotfn_ellipse_t *ellipse; + 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; + nsfb_plotfn_glyph1_t *glyph1; + nsfb_plotfn_readrect_t *readrect; + nsfb_plotfn_quadratic_bezier_t *quadratic; + nsfb_plotfn_cubic_bezier_t *cubic; + nsfb_plotfn_path_t *path; + nsfb_plotfn_polylines_t *polylines; +} nsfb_plotter_fns_t; + + +bool select_plotters(nsfb_t *nsfb); + diff --git a/src/surface.h b/src/surface.h new file mode 100644 index 0000000..efb84fb --- /dev/null +++ b/src/surface.h @@ -0,0 +1,65 @@ +/* libnsfb framebuffer surface support */ + +#include "libnsfb.h" +#include "libnsfb_plot.h" +#include "nsfb.h" + +/* surface default options */ +typedef int (nsfb_surfacefn_defaults_t)(nsfb_t *nsfb); + +/* surface init */ +typedef int (nsfb_surfacefn_init_t)(nsfb_t *nsfb); + +/* surface finalise */ +typedef int (nsfb_surfacefn_fini_t)(nsfb_t *nsfb); + +/* surface set geometry */ +typedef int (nsfb_surfacefn_geometry_t)(nsfb_t *nsfb, int width, int height, enum nsfb_format_e format); + +/* surface set parameters */ +typedef int (nsfb_surfacefn_parameters_t)(nsfb_t *nsfb, const char *parameters); + +/* surface input */ +typedef bool (nsfb_surfacefn_input_t)(nsfb_t *nsfb, nsfb_event_t *event, int timeout); + +/* surface area claim */ +typedef int (nsfb_surfacefn_claim_t)(nsfb_t *nsfb, nsfb_bbox_t *box); + +/* surface area update */ +typedef int (nsfb_surfacefn_update_t)(nsfb_t *nsfb, nsfb_bbox_t *box); + +/* surface cursor display */ +typedef int (nsfb_surfacefn_cursor_t)(nsfb_t *nsfb, struct nsfb_cursor_s *cursor); + +typedef struct nsfb_surface_rtns_s { + nsfb_surfacefn_defaults_t *defaults; + nsfb_surfacefn_init_t *initialise; + nsfb_surfacefn_fini_t *finalise; + nsfb_surfacefn_geometry_t *geometry; + nsfb_surfacefn_parameters_t *parameters; + nsfb_surfacefn_input_t *input; + nsfb_surfacefn_claim_t *claim; + nsfb_surfacefn_update_t *update; + nsfb_surfacefn_cursor_t *cursor; +} nsfb_surface_rtns_t; + +void _nsfb_register_surface(const enum nsfb_type_e type, const nsfb_surface_rtns_t *rtns, const char *name); + + +/* macro which adds a builtin command with no argument limits */ +#define NSFB_SURFACE_DEF(__name, __type, __rtns) \ + static void __name##_register_surface(void) __attribute__((constructor)); \ + void __name##_register_surface(void) { \ + _nsfb_register_surface(__type, __rtns, #__name); \ + } + +/** Obtain routines for a surface + * + * Obtain a vlist of methods for a surface type. + * + * @param type The surface type. + * @return A vtable of routines which teh caller must deallocate or + * NULL on error + */ +nsfb_surface_rtns_t *nsfb_surface_get_rtns(enum nsfb_type_e type); + -- cgit v1.2.3