NetSurf
bitmap.c
Go to the documentation of this file.
1/*
2 * Copyright 2008 Vincent Sanders <vince@simtec.co.uk>
3 *
4 * This file is part of NetSurf, http://www.netsurf-browser.org/
5 *
6 * NetSurf is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * NetSurf is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/**
20 * \file
21 * Framebuffer implementation of generic bitmap interface.
22 */
23
24#include <inttypes.h>
25#include <sys/types.h>
26#include <stdbool.h>
27#include <assert.h>
28#include <libnsfb.h>
29#include <libnsfb_plot.h>
30
31#include "utils/log.h"
32#include "utils/utils.h"
33#include "netsurf/bitmap.h"
34#include "netsurf/plotters.h"
35#include "netsurf/content.h"
36
37#include "framebuffer/gui.h"
38#include "framebuffer/fbtk.h"
40#include "framebuffer/bitmap.h"
41
42/**
43 * Create a bitmap.
44 *
45 * \param width width of image in pixels
46 * \param height width of image in pixels
47 * \param state a flag word indicating the initial state
48 * \return an opaque struct bitmap, or NULL on memory exhaustion
49 */
50static void *bitmap_create(int width, int height, enum gui_bitmap_flags flags)
51{
52 nsfb_t *bm;
53
54 bm = nsfb_new(NSFB_SURFACE_RAM);
55 if (bm == NULL) {
56 return NULL;
57 }
58
59 if ((flags & BITMAP_OPAQUE) == 0) {
60 nsfb_set_geometry(bm, width, height, NSFB_FMT_ABGR8888);
61 } else {
62 nsfb_set_geometry(bm, width, height, NSFB_FMT_XBGR8888);
63 }
64
65 if (nsfb_init(bm) == -1) {
66 nsfb_free(bm);
67 return NULL;
68 }
69
70 return bm;
71}
72
73
74/**
75 * Return a pointer to the pixel data in a bitmap.
76 *
77 * \param bitmap a bitmap, as returned by bitmap_create()
78 * \return pointer to the pixel buffer
79 *
80 * The pixel data is packed as BITMAP_FORMAT, possibly with padding at the end
81 * of rows. The width of a row in bytes is given by bitmap_get_rowstride().
82 */
83static unsigned char *bitmap_get_buffer(void *bitmap)
84{
85 nsfb_t *bm = bitmap;
86 unsigned char *bmpptr;
87
88 assert(bm != NULL);
89
90 nsfb_get_buffer(bm, &bmpptr, NULL);
91
92 return bmpptr;
93}
94
95
96/**
97 * Find the width of a pixel row in bytes.
98 *
99 * \param bitmap a bitmap, as returned by bitmap_create()
100 * \return width of a pixel row in the bitmap
101 */
102static size_t bitmap_get_rowstride(void *bitmap)
103{
104 nsfb_t *bm = bitmap;
105 int bmpstride;
106
107 assert(bm != NULL);
108
109 nsfb_get_buffer(bm, NULL, &bmpstride);
110
111 return bmpstride;
112}
113
114
115/**
116 * Free a bitmap.
117 *
118 * \param bitmap a bitmap, as returned by bitmap_create()
119 */
120static void bitmap_destroy(void *bitmap)
121{
122 nsfb_t *bm = bitmap;
123
124 assert(bm != NULL);
125
126 nsfb_free(bm);
127}
128
129
130/**
131 * The bitmap image has changed, so flush any persistant cache.
132 *
133 * \param bitmap a bitmap, as returned by bitmap_create()
134 */
135static void bitmap_modified(void *bitmap) {
136}
137
138/**
139 * Sets wether a bitmap should be plotted opaque
140 *
141 * \param bitmap a bitmap, as returned by bitmap_create()
142 * \param opaque whether the bitmap should be plotted opaque
143 */
144static void bitmap_set_opaque(void *bitmap, bool opaque)
145{
146 nsfb_t *bm = bitmap;
147
148 assert(bm != NULL);
149
150 if (opaque) {
151 nsfb_set_geometry(bm, 0, 0, NSFB_FMT_XBGR8888);
152 } else {
153 nsfb_set_geometry(bm, 0, 0, NSFB_FMT_ABGR8888);
154 }
155}
156
157
158/**
159 * Gets weather a bitmap should be plotted opaque
160 *
161 * \param bitmap a bitmap, as returned by bitmap_create()
162 */
164{
165 nsfb_t *bm = bitmap;
166 enum nsfb_format_e format;
167
168 assert(bm != NULL);
169
170 nsfb_get_geometry(bm, NULL, NULL, &format);
171
172 if (format == NSFB_FMT_ABGR8888)
173 return false;
174
175 return true;
176}
177
178static int bitmap_get_width(void *bitmap)
179{
180 nsfb_t *bm = bitmap;
181 int width;
182
183 assert(bm != NULL);
184
185 nsfb_get_geometry(bm, &width, NULL, NULL);
186
187 return(width);
188}
189
190static int bitmap_get_height(void *bitmap)
191{
192 nsfb_t *bm = bitmap;
193 int height;
194
195 assert(bm != NULL);
196
197 nsfb_get_geometry(bm, NULL, &height, NULL);
198
199 return(height);
200}
201
202/**
203 * Render content into a bitmap.
204 *
205 * \param bitmap the bitmap to draw to
206 * \param content content structure to render
207 * \return true on success and bitmap updated else false
208 */
209static nserror
211 struct hlcache_handle *content)
212{
213 nsfb_t *tbm = (nsfb_t *)bitmap; /* target bitmap */
214 nsfb_t *bm; /* temporary bitmap */
215 nsfb_t *current; /* current main fb */
216 int width, height; /* target bitmap width height */
217 int cwidth, cheight;/* content width /height */
218 nsfb_bbox_t loc;
219
220 struct redraw_context ctx = {
221 .interactive = false,
222 .background_images = true,
223 .plot = &fb_plotters
224 };
225
226 nsfb_get_geometry(tbm, &width, &height, NULL);
227
228 NSLOG(netsurf, INFO, "width %d, height %d", width, height);
229
230 /* Calculate size of buffer to render the content into */
231 /* We get the width from the largest of the bitmap width and the content
232 * width, unless it exceeds 1024, in which case we use 1024. This means
233 * we never create excessively large render buffers for huge contents,
234 * which would eat memory and cripple performance. */
235 cwidth = max(width, min(content_get_width(content), 1024));
236 /* The height is set in proportion with the width, according to the
237 * aspect ratio of the required thumbnail. */
238 cheight = ((cwidth * height) + (width / 2)) / width;
239
240 /* create temporary surface */
241 bm = nsfb_new(NSFB_SURFACE_RAM);
242 if (bm == NULL) {
243 return NSERROR_NOMEM;
244 }
245
246 nsfb_set_geometry(bm, cwidth, cheight, NSFB_FMT_XBGR8888);
247
248 if (nsfb_init(bm) == -1) {
249 nsfb_free(bm);
250 return NSERROR_NOMEM;
251 }
252
253 current = framebuffer_set_surface(bm);
254
255 /* render the content into temporary surface */
256 content_scaled_redraw(content, cwidth, cheight, &ctx);
257
259
260 loc.x0 = 0;
261 loc.y0 = 0;
262 loc.x1 = width;
263 loc.y1 = height;
264
265 nsfb_plot_copy(bm, NULL, tbm, &loc);
266
267 nsfb_free(bm);
268
269 return NSERROR_OK;
270}
271
274 .destroy = bitmap_destroy,
275 .set_opaque = bitmap_set_opaque,
276 .get_opaque = framebuffer_bitmap_get_opaque,
277 .get_buffer = bitmap_get_buffer,
278 .get_rowstride = bitmap_get_rowstride,
279 .get_width = bitmap_get_width,
280 .get_height = bitmap_get_height,
281 .modified = bitmap_modified,
282 .render = bitmap_render,
283};
284
286
287
288/*
289 * Local Variables:
290 * c-basic-offset:8
291 * End:
292 */
nserror
Enumeration of error codes.
Definition: errors.h:29
@ NSERROR_NOMEM
Memory exhaustion.
Definition: errors.h:32
@ NSERROR_OK
No error.
Definition: errors.h:30
const struct plotter_table fb_plotters
framebuffer plot operation table
Definition: framebuffer.c:525
nsfb_t * framebuffer_set_surface(nsfb_t *new_nsfb)
Set framebuffer surface to render into.
Definition: framebuffer.c:649
framebuffer interface.
int bitmap_get_width(void *bitmap)
get width of a bitmap.
Definition: bitmap.c:319
int bitmap_get_height(void *bitmap)
get height of a bitmap.
Definition: bitmap.c:336
static struct gui_bitmap_table bitmap_table
Definition: bitmap.c:272
static void bitmap_modified(void *bitmap)
The bitmap image has changed, so flush any persistant cache.
Definition: bitmap.c:135
struct gui_bitmap_table * framebuffer_bitmap_table
Definition: bitmap.c:285
static size_t bitmap_get_rowstride(void *bitmap)
Find the width of a pixel row in bytes.
Definition: bitmap.c:102
static nserror bitmap_render(struct bitmap *bitmap, struct hlcache_handle *content)
Render content into a bitmap.
Definition: bitmap.c:210
static unsigned char * bitmap_get_buffer(void *bitmap)
Return a pointer to the pixel data in a bitmap.
Definition: bitmap.c:83
static void bitmap_set_opaque(void *bitmap, bool opaque)
Sets wether a bitmap should be plotted opaque.
Definition: bitmap.c:144
static void * bitmap_create(int width, int height, enum gui_bitmap_flags flags)
Create a bitmap.
Definition: bitmap.c:50
bool framebuffer_bitmap_get_opaque(void *bitmap)
Gets weather a bitmap should be plotted opaque.
Definition: bitmap.c:163
static void bitmap_destroy(void *bitmap)
Free a bitmap.
Definition: bitmap.c:120
Generic bitmap handling interface.
gui_bitmap_flags
Bitmap creation flags.
Definition: bitmap.h:36
@ BITMAP_OPAQUE
image is opaque
Definition: bitmap.h:38
Public content interface.
int content_get_width(struct hlcache_handle *h)
Retrieve width of content.
Definition: content.c:1158
bool content_scaled_redraw(struct hlcache_handle *h, int width, int height, const struct redraw_context *ctx)
Redraw a content with scale set for horizontal fit.
Definition: content.c:583
Target independent plotting interface.
Netsurf additional integer type formatting macros.
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
int width
Definition: gui.c:160
int height
Definition: gui.c:161
RISC OS wimp toolkit bitmap.
Definition: bitmap.c:68
Content which corresponds to a single URL.
Bitmap operations.
Definition: bitmap.h:125
void *(* create)(int width, int height, enum gui_bitmap_flags flags)
Create a new bitmap.
Definition: bitmap.h:136
High-level cache handle.
Definition: hlcache.c:66
Redraw context.
Definition: plotters.h:51
bool interactive
Redraw to show interactive features.
Definition: plotters.h:59
Interface to a number of general purpose functionality.
#define min(x, y)
Definition: utils.h:46
#define max(x, y)
Definition: utils.h:50
static nserror bitmap(const struct redraw_context *ctx, struct bitmap *bitmap, int x, int y, int width, int height, colour bg, bitmap_flags_t flags)
Plot a bitmap.
Definition: plot.c:857