NetSurf
bitmap.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2008 François Revol <mmu_man@users.sourceforge.net>
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 * BeOS implementation of generic bitmaps.
22 *
23 * This implements the interface given by image/bitmap.h using BBitmap.
24 */
25
26#define __STDBOOL_H__ 1
27#include <assert.h>
28#include <sys/param.h>
29#include <string.h>
30#include <Bitmap.h>
31#include <BitmapStream.h>
32#include <File.h>
33#include <GraphicsDefs.h>
34#include <TranslatorFormats.h>
35#include <TranslatorRoster.h>
36#include <View.h>
37#include <stdlib.h>
38
39extern "C" {
40#include "utils/log.h"
41#include "netsurf/plotters.h"
44#include "netsurf/bitmap.h"
45#include "netsurf/content.h"
46}
47
48#include "beos/bitmap.h"
49#include "beos/gui.h"
50#include "beos/scaffolding.h"
51#include "beos/plotters.h"
52
53
54struct bitmap {
55 BBitmap *primary;
56 BBitmap *shadow; // in NetSurf's ABGR order
57 BBitmap *pretile_x;
58 BBitmap *pretile_y;
59 BBitmap *pretile_xy;
60 bool opaque;
61};
62
63#define MIN_PRETILE_WIDTH 256
64#define MIN_PRETILE_HEIGHT 256
65
66#warning TODO: check rgba order
67#warning TODO: add correct locking (not strictly required)
68
69
70/**
71 * Convert to BeOS RGBA32_LITTLE (strictly BGRA) from NetSurf's favoured ABGR format.
72 *
73 * Copies the converted data elsewhere. Operation is rotate left 8 bits.
74 *
75 * \param src Source 32-bit pixels arranged in ABGR order.
76 * \param dst Output data in BGRA order.
77 * \param width Width of the bitmap
78 * \param height Height of the bitmap
79 * \param rowstride Number of bytes to skip after each row (this implementation
80 * requires this to be a multiple of 4.)
81 */
82static inline void nsbeos_rgba_to_bgra(void *src,
83 void *dst,
84 int width,
85 int height,
86 size_t rowstride)
87{
88 struct abgr { uint8 a, b, g, r; };
89 struct rgba { uint8 r, g, b ,a; };
90 struct bgra { uint8 b, g, r, a; };
91 struct rgba *from = (struct rgba *)src;
92 struct bgra *to = (struct bgra *)dst;
93
94 rowstride >>= 2;
95
96 for (int y = 0; y < height; y++) {
97 for (int x = 0; x < width; x++) {
98 to[x].b = from[x].b;
99 to[x].g = from[x].g;
100 to[x].r = from[x].r;
101 to[x].a = from[x].a;
102 /*
103 if (from[x].a == 0)
104 *(rgb_color *)&to[x] = B_TRANSPARENT_32_BIT;
105 */
106 }
107 from += rowstride;
108 to += rowstride;
109 }
110}
111
112
113/**
114 * Create a bitmap.
115 *
116 * \param width width of image in pixels
117 * \param height height of image in pixels
118 * \param bflags flags for bitmap creation
119 * \return an opaque struct bitmap, or NULL on memory exhaustion
120 */
121static void *bitmap_create(int width, int height, enum gui_bitmap_flags flags)
122{
123 struct bitmap *bmp = (struct bitmap *)malloc(sizeof(struct bitmap));
124 if (bmp == NULL)
125 return NULL;
126
127 int32 Bflags = 0;
128 if (flags & BITMAP_CLEAR)
129 Bflags |= B_BITMAP_CLEAR_TO_WHITE;
130
131 BRect frame(0, 0, width - 1, height - 1);
132 //XXX: bytes per row ?
133 bmp->primary = new BBitmap(frame, Bflags, B_RGBA32);
134 bmp->shadow = new BBitmap(frame, Bflags, B_RGBA32);
135
136 bmp->pretile_x = bmp->pretile_y = bmp->pretile_xy = NULL;
137
138 bmp->opaque = (flags & BITMAP_OPAQUE) != 0;
139
140 return bmp;
141}
142
143
144/**
145 * Sets whether a bitmap should be plotted opaque
146 *
147 * \param vbitmap a bitmap, as returned by bitmap_create()
148 * \param opaque whether the bitmap should be plotted opaque
149 */
150static void bitmap_set_opaque(void *vbitmap, bool opaque)
151{
152 struct bitmap *bitmap = (struct bitmap *)vbitmap;
153 assert(bitmap);
155}
156
157
158/**
159 * Gets whether a bitmap should be plotted opaque
160 *
161 * \param vbitmap a bitmap, as returned by bitmap_create()
162 */
163static bool bitmap_get_opaque(void *vbitmap)
164{
165 struct bitmap *bitmap = (struct bitmap *)vbitmap;
166 assert(bitmap);
167 return bitmap->opaque;
168}
169
170
171/**
172 * Return a pointer to the pixel data in a bitmap.
173 *
174 * \param vbitmap a bitmap, as returned by bitmap_create()
175 * \return pointer to the pixel buffer
176 *
177 * The pixel data is packed as BITMAP_FORMAT, possibly with padding at the end
178 * of rows. The width of a row in bytes is given by bitmap_get_rowstride().
179 */
180
181static unsigned char *bitmap_get_buffer(void *vbitmap)
182{
183 struct bitmap *bitmap = (struct bitmap *)vbitmap;
184 assert(bitmap);
185 return (unsigned char *)(bitmap->shadow->Bits());
186}
187
188
189/**
190 * Find the width of a pixel row in bytes.
191 *
192 * \param vbitmap a bitmap, as returned by bitmap_create()
193 * \return width of a pixel row in the bitmap
194 */
195static size_t bitmap_get_rowstride(void *vbitmap)
196{
197 struct bitmap *bitmap = (struct bitmap *)vbitmap;
198 assert(bitmap);
199 return (bitmap->primary->BytesPerRow());
200}
201
202
203/**
204 * Free pretiles of a bitmap.
205 *
206 * \param bitmap The bitmap to free the pretiles of.
207 */
209{
210#define FREE_TILE(XY) if (bitmap->pretile_##XY) delete (bitmap->pretile_##XY); bitmap->pretile_##XY = NULL
211 FREE_TILE(x);
212 FREE_TILE(y);
213 FREE_TILE(xy);
214#undef FREE_TILE
215}
216
217
218/**
219 * Free a bitmap.
220 *
221 * \param vbitmap a bitmap, as returned by bitmap_create()
222 */
223static void bitmap_destroy(void *vbitmap)
224{
225 struct bitmap *bitmap = (struct bitmap *)vbitmap;
226 assert(bitmap);
228 delete bitmap->primary;
229 delete bitmap->shadow;
230 free(bitmap);
231}
232
233
234/**
235 * The bitmap image has changed, so flush any persistant cache.
236 *
237 * \param vbitmap a bitmap, as returned by bitmap_create()
238 */
239void bitmap_modified(void *vbitmap)
240{
241 struct bitmap *bitmap = (struct bitmap *)vbitmap;
242 // convert the shadow (ABGR) to into the primary bitmap
244 bitmap->primary->Bounds().Width() + 1,
245 bitmap->primary->Bounds().Height() + 1,
246 bitmap->primary->BytesPerRow());
248}
249
250
251static int bitmap_get_width(void *vbitmap)
252{
253 struct bitmap *bitmap = (struct bitmap *)vbitmap;
254 return bitmap->primary->Bounds().Width() + 1;
255}
256
257
258static int bitmap_get_height(void *vbitmap)
259{
260 struct bitmap *bitmap = (struct bitmap *)vbitmap;
261 return bitmap->primary->Bounds().Height() + 1;
262}
263
264
265static BBitmap *
266nsbeos_bitmap_generate_pretile(BBitmap *primary, int repeat_x, int repeat_y)
267{
268 int width = primary->Bounds().Width() + 1;
269 int height = primary->Bounds().Height() + 1;
270 size_t primary_stride = primary->BytesPerRow();
271 BRect frame(0, 0, width * repeat_x - 1, height * repeat_y - 1);
272 BBitmap *result = new BBitmap(frame, 0, B_RGBA32);
273
274 char *target_buffer = (char *)result->Bits();
275 int x,y,row;
276 /* This algorithm won't work if the strides are not multiples */
277 assert((size_t)(result->BytesPerRow()) ==
278 (primary_stride * repeat_x));
279
280 if (repeat_x == 1 && repeat_y == 1) {
281 delete result;
282 // just return a copy
283 return new BBitmap(primary);
284 }
285
286 for (y = 0; y < repeat_y; ++y) {
287 char *primary_buffer = (char *)primary->Bits();
288 for (row = 0; row < height; ++row) {
289 for (x = 0; x < repeat_x; ++x) {
290 memcpy(target_buffer,
291 primary_buffer, primary_stride);
292 target_buffer += primary_stride;
293 }
294 primary_buffer += primary_stride;
295 }
296 }
297 return result;
298
299}
300
301
302/**
303 * The primary image associated with this bitmap object.
304 *
305 * \param bitmap a bitmap, as returned by bitmap_create()
306 */
307BBitmap *
309{
310 return bitmap->primary;
311}
312
313
314/**
315 * The X-pretiled image associated with this bitmap object.
316 *
317 * \param bitmap a bitmap, as returned by bitmap_create()
318 */
319BBitmap *
321{
322 if (!bitmap->pretile_x) {
323 int width = bitmap->primary->Bounds().Width() + 1;
324 int xmult = (MIN_PRETILE_WIDTH + width - 1)/width;
325 NSLOG(netsurf, INFO, "Pretiling %p for X*%d", bitmap, xmult);
327 }
328 return bitmap->pretile_x;
329
330}
331
332
333/**
334 * The Y-pretiled image associated with this bitmap object.
335 *
336 * \param bitmap a bitmap, as returned by bitmap_create()
337 */
338BBitmap *
340{
341 if (!bitmap->pretile_y) {
342 int height = bitmap->primary->Bounds().Height() + 1;
343 int ymult = (MIN_PRETILE_HEIGHT + height - 1)/height;
344 NSLOG(netsurf, INFO, "Pretiling %p for Y*%d", bitmap, ymult);
346 }
347 return bitmap->pretile_y;
348}
349
350
351/**
352 * The XY-pretiled image associated with this bitmap object.
353 *
354 * \param bitmap a bitmap, as returned by bitmap_create()
355 */
356BBitmap *
358{
359 if (!bitmap->pretile_xy) {
360 int width = bitmap->primary->Bounds().Width() + 1;
361 int height = bitmap->primary->Bounds().Height() + 1;
362 int xmult = (MIN_PRETILE_WIDTH + width - 1)/width;
363 int ymult = (MIN_PRETILE_HEIGHT + height - 1)/height;
364 NSLOG(netsurf, INFO, "Pretiling %p for X*%d Y*%d", bitmap,
365 xmult, ymult);
367 }
368 return bitmap->pretile_xy;
369}
370
371
372/**
373 * Create a thumbnail of a page.
374 *
375 * \param bitmap the bitmap to draw to
376 * \param content content structure to thumbnail
377 * \return true on success and bitmap updated else false
378 */
380{
381 BBitmap *thumbnail;
382 BBitmap *small;
383 BBitmap *big;
384 BView *oldView;
385 BView *view;
386 BView *thumbView;
387 float width;
388 float height;
389 int big_width;
390 int big_height;
391 int depth;
392
393 struct redraw_context ctx;
394 ctx.interactive = false;
395 ctx.background_images = true;
396 ctx.plot = &nsbeos_plotters;
397
398 assert(content);
399 assert(bitmap);
400
402 width = thumbnail->Bounds().Width();
403 height = thumbnail->Bounds().Height();
404 depth = 32;
405
406 big_width = MIN(content_get_width(content), 1024);
407 big_height = (int)(((big_width * height) + (width / 2)) / width);
408
409 BRect contentRect(0, 0, big_width - 1, big_height - 1);
410 big = new BBitmap(contentRect, B_BITMAP_ACCEPTS_VIEWS, B_RGB32);
411
412 if (big->InitCheck() < B_OK) {
413 delete big;
414 return NSERROR_NOMEM;
415 }
416
417 small = new BBitmap(thumbnail->Bounds(),
418 B_BITMAP_ACCEPTS_VIEWS, B_RGB32);
419
420 if (small->InitCheck() < B_OK) {
421 delete small;
422 delete big;
423 return NSERROR_NOMEM;
424 }
425
426 //XXX: _lock ?
427 // backup the current gc
428 oldView = nsbeos_current_gc();
429
430 view = new BView(contentRect, "thumbnailer",
431 B_FOLLOW_NONE, B_WILL_DRAW);
432 big->AddChild(view);
433
434 thumbView = new BView(small->Bounds(), "thumbnail",
435 B_FOLLOW_NONE, B_WILL_DRAW);
436 small->AddChild(thumbView);
437
438 view->LockLooper();
439
440 /* impose our view on the content... */
442
443 /* render the content */
444 content_scaled_redraw(content, big_width, big_height, &ctx);
445
446 view->Sync();
447 view->UnlockLooper();
448
449 // restore the current gc
450 nsbeos_current_gc_set(oldView);
451
452
453 // now scale it down
454 //XXX: use Zeta's bilinear scaler ?
455 //#ifdef B_ZETA_VERSION
456 // err = ScaleBitmap(*shot, *scaledBmp);
457 //#else
458 thumbView->LockLooper();
459 thumbView->DrawBitmap(big, big->Bounds(), small->Bounds());
460 thumbView->Sync();
461 thumbView->UnlockLooper();
462
463 small->LockBits();
464 thumbnail->LockBits();
465
466 // copy it to the bitmap
467 memcpy(thumbnail->Bits(), small->Bits(), thumbnail->BitsLength());
468
469 thumbnail->UnlockBits();
470 small->UnlockBits();
471
473
474 // cleanup
475 small->RemoveChild(thumbView);
476 delete thumbView;
477 delete small;
478 big->RemoveChild(view);
479 delete view;
480 delete big;
481
482 return NSERROR_OK;
483}
484
485
487 /*.create =*/ bitmap_create,
488 /*.destroy =*/ bitmap_destroy,
489 /*.set_opaque =*/ bitmap_set_opaque,
490 /*.get_opaque =*/ bitmap_get_opaque,
491 /*.get_buffer =*/ bitmap_get_buffer,
492 /*.get_rowstride =*/ bitmap_get_rowstride,
493 /*.get_width =*/ bitmap_get_width,
494 /*.get_height =*/ bitmap_get_height,
495 /*.modified =*/ bitmap_modified,
496 /*.render =*/ bitmap_render,
497};
498
STATIC char result[100]
Definition: arexx.c:77
static struct s_view view
Definition: plot.c:199
static void bitmap_set_opaque(void *vbitmap, bool opaque)
Sets whether a bitmap should be plotted opaque.
Definition: bitmap.cpp:150
static struct gui_bitmap_table bitmap_table
Definition: bitmap.cpp:486
static void nsbeos_rgba_to_bgra(void *src, void *dst, int width, int height, size_t rowstride)
Convert to BeOS RGBA32_LITTLE (strictly BGRA) from NetSurf's favoured ABGR format.
Definition: bitmap.cpp:82
static bool bitmap_get_opaque(void *vbitmap)
Gets whether a bitmap should be plotted opaque.
Definition: bitmap.cpp:163
BBitmap * nsbeos_bitmap_get_pretile_xy(struct bitmap *bitmap)
The XY-pretiled image associated with this bitmap object.
Definition: bitmap.cpp:357
#define MIN_PRETILE_HEIGHT
Definition: bitmap.cpp:64
#define MIN_PRETILE_WIDTH
Definition: bitmap.cpp:63
static nserror bitmap_render(struct bitmap *bitmap, hlcache_handle *content)
Create a thumbnail of a page.
Definition: bitmap.cpp:379
#define FREE_TILE(XY)
struct gui_bitmap_table * beos_bitmap_table
Definition: bitmap.cpp:499
static unsigned char * bitmap_get_buffer(void *vbitmap)
Return a pointer to the pixel data in a bitmap.
Definition: bitmap.cpp:181
static int bitmap_get_height(void *vbitmap)
Definition: bitmap.cpp:258
static BBitmap * nsbeos_bitmap_generate_pretile(BBitmap *primary, int repeat_x, int repeat_y)
Definition: bitmap.cpp:266
void bitmap_modified(void *vbitmap)
The bitmap image has changed, so flush any persistant cache.
Definition: bitmap.cpp:239
static size_t bitmap_get_rowstride(void *vbitmap)
Find the width of a pixel row in bytes.
Definition: bitmap.cpp:195
BBitmap * nsbeos_bitmap_get_primary(struct bitmap *bitmap)
The primary image associated with this bitmap object.
Definition: bitmap.cpp:308
static void * bitmap_create(int width, int height, enum gui_bitmap_flags flags)
Create a bitmap.
Definition: bitmap.cpp:121
static int bitmap_get_width(void *vbitmap)
Definition: bitmap.cpp:251
static void bitmap_destroy(void *vbitmap)
Free a bitmap.
Definition: bitmap.cpp:223
static void nsbeos_bitmap_free_pretiles(struct bitmap *bitmap)
Free pretiles of a bitmap.
Definition: bitmap.cpp:208
BBitmap * nsbeos_bitmap_get_pretile_x(struct bitmap *bitmap)
The X-pretiled image associated with this bitmap object.
Definition: bitmap.cpp:320
BBitmap * nsbeos_bitmap_get_pretile_y(struct bitmap *bitmap)
The Y-pretiled image associated with this bitmap object.
Definition: bitmap.cpp:339
Browser window creation and manipulation interface.
Declaration of content enumerations.
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
Target independent plotting (BeOS interface).
Generic bitmap handling interface.
gui_bitmap_flags
Bitmap creation flags.
Definition: bitmap.h:36
@ BITMAP_CLEAR
memory should be wiped to 0
Definition: bitmap.h:39
@ 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.
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
uint8_t uint8
Definition: os3support.h:180
#define MIN(a, b)
Definition: os3support.h:51
int32_t int32
Definition: os3support.h:183
const struct plotter_table nsbeos_plotters
beos plotter operation table
Definition: plotters.cpp:739
void nsbeos_current_gc_set(BView *view)
Definition: plotters.cpp:93
BView * nsbeos_current_gc(void)
Definition: plotters.cpp:70
int width
Definition: gui.c:160
int height
Definition: gui.c:161
Interface to utility string handling.
RISC OS wimp toolkit bitmap.
Definition: bitmap.c:68
BBitmap * shadow
Definition: bitmap.cpp:56
BBitmap * primary
Definition: bitmap.cpp:55
BBitmap * pretile_xy
Definition: bitmap.cpp:59
BBitmap * pretile_x
Definition: bitmap.cpp:57
bool opaque
Whether the bitmap is opaque.
Definition: bitmap.c:74
BBitmap * pretile_y
Definition: bitmap.cpp:58
Content which corresponds to a single URL.
Bitmap operations.
Definition: bitmap.h:125
High-level cache handle.
Definition: hlcache.c:66
Redraw context.
Definition: plotters.h:51
bool background_images
Render background images.
Definition: plotters.h:66
const struct plotter_table * plot
Current plot operation table.
Definition: plotters.h:73
bool interactive
Redraw to show interactive features.
Definition: plotters.h:59
char from[32]
Encoding name to convert from.
Definition: utf8.c:143
char to[32]
Encoding name to convert to.
Definition: utf8.c:144