Merge branch 'thumbnail-rework'

This commit is contained in:
Vincent Sanders 2015-04-24 23:52:10 +01:00
commit 9729febf72
42 changed files with 1251 additions and 1603 deletions

View File

@ -68,7 +68,7 @@ MESSAGES_FILTER=ami
# S_AMIGA are sources purely for the Amiga build
S_AMIGA := gui.c tree.c history.c hotlist.c schedule.c file.c \
thumbnail.c misc.c bitmap.c font.c filetype.c utf8.c login.c \
misc.c bitmap.c font.c filetype.c utf8.c login.c \
plotters.c object.c menu.c save_pdf.c arexx.c version.c \
cookies.c context_menu.c clipboard.c help.c font_scan.c \
launch.c search.c history_local.c download.c iff_dr2d.c \

View File

@ -24,14 +24,15 @@
#include <graphics/composite.h>
#endif
#include <graphics/gfxbase.h>
#include "utils/nsoption.h"
#include <proto/datatypes.h>
#include <datatypes/pictureclass.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/utility.h>
#include <sys/param.h>
#include "assert.h"
#include "utils/nsoption.h"
#include "utils/messages.h"
#include "desktop/mouse.h"
#include "desktop/gui_window.h"
@ -505,6 +506,80 @@ struct BitMap *ami_bitmap_get_native(struct bitmap *bitmap,
}
}
static nserror bitmap_render(struct bitmap *bitmap, hlcache_handle *content)
{
struct BitScaleArgs bsa;
int plot_width;
int plot_height;
int redraw_tile_size = nsoption_int(redraw_tile_size_x);
struct redraw_context ctx = {
.interactive = false,
.background_images = true,
.plot = &amiplot
};
if(nsoption_int(redraw_tile_size_y) < nsoption_int(redraw_tile_size_x))
redraw_tile_size = nsoption_int(redraw_tile_size_y);
plot_width = MIN(content_get_width(content), redraw_tile_size);
plot_height = ((plot_width * bitmap->height) + (bitmap->width / 2)) /
bitmap->width;
bitmap->nativebm = ami_rtg_allocbitmap(bitmap->width, bitmap->height, 32,
BMF_CLEAR, browserglob.bm, RGBFB_A8R8G8B8);
bitmap->nativebmwidth = bitmap->width;
bitmap->nativebmheight = bitmap->height;
ami_clearclipreg(&browserglob);
content_scaled_redraw(content, plot_width, plot_height, &ctx);
#ifdef __amigaos4__
if(__builtin_expect(GfxBase->LibNode.lib_Version >= 53, 1)) {
/* AutoDoc says v52, but this function isn't in OS4.0, so checking for v53 (OS4.1) */
float resample_scale = bitmap->width / (float)plot_width;
uint32 flags = COMPFLAG_IgnoreDestAlpha;
if(nsoption_bool(scale_quality)) flags |= COMPFLAG_SrcFilter;
CompositeTags(COMPOSITE_Src,browserglob.bm,bitmap->nativebm,
COMPTAG_ScaleX,
COMP_FLOAT_TO_FIX(resample_scale),
COMPTAG_ScaleY,
COMP_FLOAT_TO_FIX(resample_scale),
COMPTAG_Flags,flags,
COMPTAG_DestX,0,
COMPTAG_DestY,0,
COMPTAG_DestWidth,bitmap->width,
COMPTAG_DestHeight,bitmap->height,
COMPTAG_OffsetX,0,
COMPTAG_OffsetY,0,
COMPTAG_FriendBitMap, scrn->RastPort.BitMap,
TAG_DONE);
} else
#endif
{
bsa.bsa_SrcX = 0;
bsa.bsa_SrcY = 0;
bsa.bsa_SrcWidth = plot_width;
bsa.bsa_SrcHeight = plot_height;
bsa.bsa_DestX = 0;
bsa.bsa_DestY = 0;
// bsa.bsa_DestWidth = width;
// bsa.bsa_DestHeight = height;
bsa.bsa_XSrcFactor = plot_width;
bsa.bsa_XDestFactor = bitmap->width;
bsa.bsa_YSrcFactor = plot_height;
bsa.bsa_YDestFactor = bitmap->height;
bsa.bsa_SrcBitMap = browserglob.bm;
bsa.bsa_DestBitMap = bitmap->nativebm;
bsa.bsa_Flags = 0;
BitMapScale(&bsa);
}
return true;
}
static struct gui_bitmap_table bitmap_table = {
.create = amiga_bitmap_create,
.destroy = amiga_bitmap_destroy,
@ -518,6 +593,7 @@ static struct gui_bitmap_table bitmap_table = {
.get_bpp = bitmap_get_bpp,
.save = amiga_bitmap_save,
.modified = amiga_bitmap_modified,
.render = bitmap_render,
};
struct gui_bitmap_table *amiga_bitmap_table = &bitmap_table;

View File

@ -37,13 +37,13 @@
#endif
#include <workbench/icon.h>
#include "desktop/plotters.h"
#include "image/bitmap.h"
#include "content/content_protected.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "utils/utils.h"
#include "utils/file.h"
#include "desktop/plotters.h"
#include "image/bitmap.h"
#include "content/content_protected.h"
#include "amiga/os3support.h"
#include "amiga/bitmap.h"

View File

@ -1,117 +0,0 @@
/*
* Copyright 2008,2009 Chris Young <chris@unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "amiga/os3support.h"
#include <proto/graphics.h>
#include <intuition/intuition.h>
#ifdef __amigaos4__
#include <graphics/blitattr.h>
#include <graphics/composite.h>
#endif
#include <graphics/gfxbase.h>
#include <sys/param.h>
#include "amiga/os3support.h"
#include "desktop/browser.h"
#include "utils/nsoption.h"
#include "content/urldb.h"
#include "desktop/plotters.h"
#include "desktop/thumbnail.h"
#include "desktop/mouse.h"
#include "desktop/gui_window.h"
#include "amiga/gui.h"
#include "amiga/bitmap.h"
#include "amiga/rtg.h"
bool thumbnail_create(hlcache_handle *content, struct bitmap *bitmap)
{
struct BitScaleArgs bsa;
int plot_width;
int plot_height;
int redraw_tile_size = nsoption_int(redraw_tile_size_x);
struct redraw_context ctx = {
.interactive = false,
.background_images = true,
.plot = &amiplot
};
if(nsoption_int(redraw_tile_size_y) < nsoption_int(redraw_tile_size_x))
redraw_tile_size = nsoption_int(redraw_tile_size_y);
plot_width = MIN(content_get_width(content), redraw_tile_size);
plot_height = ((plot_width * bitmap->height) + (bitmap->width / 2)) /
bitmap->width;
bitmap->nativebm = ami_rtg_allocbitmap(bitmap->width, bitmap->height, 32,
BMF_CLEAR, browserglob.bm, RGBFB_A8R8G8B8);
bitmap->nativebmwidth = bitmap->width;
bitmap->nativebmheight = bitmap->height;
ami_clearclipreg(&browserglob);
thumbnail_redraw(content, plot_width, plot_height, &ctx);
#ifdef __amigaos4__
if(__builtin_expect(GfxBase->LibNode.lib_Version >= 53, 1)) {
/* AutoDoc says v52, but this function isn't in OS4.0, so checking for v53 (OS4.1) */
float resample_scale = bitmap->width / (float)plot_width;
uint32 flags = COMPFLAG_IgnoreDestAlpha;
if(nsoption_bool(scale_quality)) flags |= COMPFLAG_SrcFilter;
CompositeTags(COMPOSITE_Src,browserglob.bm,bitmap->nativebm,
COMPTAG_ScaleX,
COMP_FLOAT_TO_FIX(resample_scale),
COMPTAG_ScaleY,
COMP_FLOAT_TO_FIX(resample_scale),
COMPTAG_Flags,flags,
COMPTAG_DestX,0,
COMPTAG_DestY,0,
COMPTAG_DestWidth,bitmap->width,
COMPTAG_DestHeight,bitmap->height,
COMPTAG_OffsetX,0,
COMPTAG_OffsetY,0,
COMPTAG_FriendBitMap, scrn->RastPort.BitMap,
TAG_DONE);
} else
#endif
{
bsa.bsa_SrcX = 0;
bsa.bsa_SrcY = 0;
bsa.bsa_SrcWidth = plot_width;
bsa.bsa_SrcHeight = plot_height;
bsa.bsa_DestX = 0;
bsa.bsa_DestY = 0;
// bsa.bsa_DestWidth = width;
// bsa.bsa_DestHeight = height;
bsa.bsa_XSrcFactor = plot_width;
bsa.bsa_XDestFactor = bitmap->width;
bsa.bsa_YSrcFactor = plot_height;
bsa.bsa_YDestFactor = bitmap->height;
bsa.bsa_SrcBitMap = browserglob.bm;
bsa.bsa_DestBitMap = bitmap->nativebm;
bsa.bsa_Flags = 0;
BitMapScale(&bsa);
}
return true;
}

View File

@ -100,7 +100,6 @@ S_ATARI := \
statusbar.c \
settings.c \
toolbar.c \
thumbnail.c \
treeview.c \
plot/plot.c \
plot/fontplot.c \

View File

@ -426,6 +426,11 @@ bool atari_bitmap_resize(struct bitmap *img, HermesHandle hermes_h,
return(true);
}
static nserror bitmap_render(struct bitmap *bitmap, struct hlcache_handle *content)
{
return NSERROR_NOT_IMPLEMENTED;
}
static struct gui_bitmap_table bitmap_table = {
.create = atari_bitmap_create,
.destroy = atari_bitmap_destroy,
@ -439,6 +444,7 @@ static struct gui_bitmap_table bitmap_table = {
.get_bpp = bitmap_get_bpp,
.save = bitmap_save,
.modified = bitmap_modified,
.render = bitmap_render,
};
struct gui_bitmap_table *atari_bitmap_table = &bitmap_table;

View File

@ -25,10 +25,10 @@
#include <mt_gem.h>
#include <mint/osbind.h>
#include "image/bitmap.h"
#include "utils/log.h"
#include "utils/utf8.h"
#include "utils/utils.h"
#include "image/bitmap.h"
#include "desktop/plotters.h"
#include "desktop/mouse.h"

View File

@ -1,24 +0,0 @@
/*
* Copyright 2010 Ole Loots <ole@monochrom.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "desktop/thumbnail.h"
bool thumbnail_create(struct hlcache_handle *content, struct bitmap *bitmap)
{
return false;
}

View File

@ -95,8 +95,7 @@ endif
# S_BEOS are sources purely for the BeOS build
S_BEOS := about.cpp bitmap.cpp download.cpp fetch_rsrc.cpp filetype.cpp \
font.cpp gui.cpp login.cpp gui_options.cpp plotters.cpp \
scaffolding.cpp search.cpp schedule.cpp thumbnail.cpp \
throbber.cpp window.cpp
scaffolding.cpp search.cpp schedule.cpp throbber.cpp window.cpp
S_BEOS := $(addprefix beos/,$(S_BEOS))
RDEF_BEOS := res.rdef

View File

@ -16,15 +16,16 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file
* Generic bitmap handling (BeOS implementation).
/**
* \file
* BeOS implementation of generic bitmaps.
*
* This implements the interface given by desktop/bitmap.h using BBitmap.
* This implements the interface given by image/bitmap.h using BBitmap.
*/
#define __STDBOOL_H__ 1
//#include <stdbool.h>
#include <assert.h>
#include <sys/param.h>
#include <string.h>
#include <Bitmap.h>
#include <BitmapStream.h>
@ -32,22 +33,31 @@
#include <GraphicsDefs.h>
#include <TranslatorFormats.h>
#include <TranslatorRoster.h>
#include <View.h>
extern "C" {
#include "content/content.h"
#include "image/bitmap.h"
#include "utils/log.h"
#include "content/content.h"
#include "content/urldb.h"
#include "desktop/plotters.h"
#include "desktop/browser.h"
#include "desktop/font.h"
#include "image/bitmap.h"
}
#include "beos/bitmap.h"
#include "beos/gui.h"
#include "beos/scaffolding.h"
#include "beos/plotters.h"
struct bitmap {
BBitmap *primary;
BBitmap *shadow; // in NetSurf's ABGR order
BBitmap *pretile_x;
BBitmap *pretile_y;
BBitmap *pretile_xy;
bool opaque;
BBitmap *primary;
BBitmap *shadow; // in NetSurf's ABGR order
BBitmap *pretile_x;
BBitmap *pretile_y;
BBitmap *pretile_xy;
bool opaque;
};
#define MIN_PRETILE_WIDTH 256
@ -64,7 +74,7 @@ struct bitmap {
*
* \param src Source 32-bit pixels arranged in ABGR order.
* \param dst Output data in BGRA order.
* \param width Width of the bitmap
* \param width Width of the bitmap
* \param height Height of the bitmap
* \param rowstride Number of bytes to skip after each row (this implementation
* requires this to be a multiple of 4.)
@ -75,28 +85,28 @@ static inline void nsbeos_rgba_to_bgra(void *src,
int height,
size_t rowstride)
{
struct abgr { uint8 a, b, g, r; };
struct rgba { uint8 r, g, b ,a; };
struct bgra { uint8 b, g, r, a; };
struct rgba *from = (struct rgba *)src;
struct bgra *to = (struct bgra *)dst;
struct abgr { uint8 a, b, g, r; };
struct rgba { uint8 r, g, b ,a; };
struct bgra { uint8 b, g, r, a; };
struct rgba *from = (struct rgba *)src;
struct bgra *to = (struct bgra *)dst;
rowstride >>= 2;
rowstride >>= 2;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
to[x].b = from[x].b;
to[x].g = from[x].g;
to[x].r = from[x].r;
to[x].a = from[x].a;
/*
if (from[x].a == 0)
*(rgb_color *)&to[x] = B_TRANSPARENT_32_BIT;
*/
}
from += rowstride;
to += rowstride;
}
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
to[x].b = from[x].b;
to[x].g = from[x].g;
to[x].r = from[x].r;
to[x].a = from[x].a;
/*
if (from[x].a == 0)
*(rgb_color *)&to[x] = B_TRANSPARENT_32_BIT;
*/
}
from += rowstride;
to += rowstride;
}
}
@ -108,27 +118,26 @@ static inline void nsbeos_rgba_to_bgra(void *src,
* \param state a flag word indicating the initial state
* \return an opaque struct bitmap, or NULL on memory exhaustion
*/
void *bitmap_create(int width, int height, unsigned int state)
{
struct bitmap *bmp = (struct bitmap *)malloc(sizeof(struct bitmap));
if (bmp == NULL)
return NULL;
struct bitmap *bmp = (struct bitmap *)malloc(sizeof(struct bitmap));
if (bmp == NULL)
return NULL;
int32 flags = 0;
if (state & BITMAP_CLEAR_MEMORY)
flags |= B_BITMAP_CLEAR_TO_WHITE;
int32 flags = 0;
if (state & BITMAP_CLEAR_MEMORY)
flags |= B_BITMAP_CLEAR_TO_WHITE;
BRect frame(0, 0, width - 1, height - 1);
//XXX: bytes per row ?
bmp->primary = new BBitmap(frame, flags, B_RGBA32);
bmp->shadow = new BBitmap(frame, flags, B_RGBA32);
BRect frame(0, 0, width - 1, height - 1);
//XXX: bytes per row ?
bmp->primary = new BBitmap(frame, flags, B_RGBA32);
bmp->shadow = new BBitmap(frame, flags, B_RGBA32);
bmp->pretile_x = bmp->pretile_y = bmp->pretile_xy = NULL;
bmp->pretile_x = bmp->pretile_y = bmp->pretile_xy = NULL;
bmp->opaque = (state & BITMAP_OPAQUE) != 0;
bmp->opaque = (state & BITMAP_OPAQUE) != 0;
return bmp;
return bmp;
}
@ -140,9 +149,9 @@ void *bitmap_create(int width, int height, unsigned int state)
*/
void bitmap_set_opaque(void *vbitmap, bool opaque)
{
struct bitmap *bitmap = (struct bitmap *)vbitmap;
assert(bitmap);
bitmap->opaque = opaque;
struct bitmap *bitmap = (struct bitmap *)vbitmap;
assert(bitmap);
bitmap->opaque = opaque;
}
@ -154,10 +163,10 @@ void bitmap_set_opaque(void *vbitmap, bool opaque)
*/
bool bitmap_test_opaque(void *vbitmap)
{
struct bitmap *bitmap = (struct bitmap *)vbitmap;
assert(bitmap);
/* todo: test if bitmap is opaque */
return false;
struct bitmap *bitmap = (struct bitmap *)vbitmap;
assert(bitmap);
/* todo: test if bitmap is opaque */
return false;
}
@ -168,9 +177,9 @@ bool bitmap_test_opaque(void *vbitmap)
*/
bool bitmap_get_opaque(void *vbitmap)
{
struct bitmap *bitmap = (struct bitmap *)vbitmap;
assert(bitmap);
return bitmap->opaque;
struct bitmap *bitmap = (struct bitmap *)vbitmap;
assert(bitmap);
return bitmap->opaque;
}
@ -186,9 +195,9 @@ bool bitmap_get_opaque(void *vbitmap)
unsigned char *bitmap_get_buffer(void *vbitmap)
{
struct bitmap *bitmap = (struct bitmap *)vbitmap;
assert(bitmap);
return (unsigned char *)(bitmap->shadow->Bits());
struct bitmap *bitmap = (struct bitmap *)vbitmap;
assert(bitmap);
return (unsigned char *)(bitmap->shadow->Bits());
}
@ -198,12 +207,11 @@ unsigned char *bitmap_get_buffer(void *vbitmap)
* \param vbitmap a bitmap, as returned by bitmap_create()
* \return width of a pixel row in the bitmap
*/
size_t bitmap_get_rowstride(void *vbitmap)
{
struct bitmap *bitmap = (struct bitmap *)vbitmap;
assert(bitmap);
return (bitmap->primary->BytesPerRow());
struct bitmap *bitmap = (struct bitmap *)vbitmap;
assert(bitmap);
return (bitmap->primary->BytesPerRow());
}
@ -213,39 +221,42 @@ size_t bitmap_get_rowstride(void *vbitmap)
* \param vbitmap a bitmap, as returned by bitmap_create()
* \return bytes per pixels of the bitmap
*/
size_t bitmap_get_bpp(void *vbitmap)
{
struct bitmap *bitmap = (struct bitmap *)vbitmap;
assert(bitmap);
return 4;
struct bitmap *bitmap = (struct bitmap *)vbitmap;
assert(bitmap);
return 4;
}
static void
nsbeos_bitmap_free_pretiles(struct bitmap *bitmap)
/**
* Free pretiles of a bitmap.
*
* \param bitmap The bitmap to free the pretiles of.
*/
static void nsbeos_bitmap_free_pretiles(struct bitmap *bitmap)
{
#define FREE_TILE(XY) if (bitmap->pretile_##XY) delete (bitmap->pretile_##XY); bitmap->pretile_##XY = NULL
FREE_TILE(x);
FREE_TILE(y);
FREE_TILE(xy);
FREE_TILE(x);
FREE_TILE(y);
FREE_TILE(xy);
#undef FREE_TILE
}
/**
* Free a bitmap.
*
* \param vbitmap a bitmap, as returned by bitmap_create()
*/
void bitmap_destroy(void *vbitmap)
{
struct bitmap *bitmap = (struct bitmap *)vbitmap;
assert(bitmap);
nsbeos_bitmap_free_pretiles(bitmap);
delete bitmap->primary;
delete bitmap->shadow;
free(bitmap);
struct bitmap *bitmap = (struct bitmap *)vbitmap;
assert(bitmap);
nsbeos_bitmap_free_pretiles(bitmap);
delete bitmap->primary;
delete bitmap->shadow;
free(bitmap);
}
@ -257,22 +268,21 @@ void bitmap_destroy(void *vbitmap)
* \param flags modify the behaviour of the save
* \return true on success, false on error and error reported
*/
bool bitmap_save(void *vbitmap, const char *path, unsigned flags)
{
struct bitmap *bitmap = (struct bitmap *)vbitmap;
BTranslatorRoster *roster = BTranslatorRoster::Default();
BBitmapStream stream(bitmap->primary);
BFile file(path, B_WRITE_ONLY | B_CREATE_FILE);
uint32 type = B_PNG_FORMAT;
struct bitmap *bitmap = (struct bitmap *)vbitmap;
BTranslatorRoster *roster = BTranslatorRoster::Default();
BBitmapStream stream(bitmap->primary);
BFile file(path, B_WRITE_ONLY | B_CREATE_FILE);
uint32 type = B_PNG_FORMAT;
if (file.InitCheck() < B_OK)
return false;
if (file.InitCheck() < B_OK)
return false;
if (roster->Translate(&stream, NULL, NULL, &file, type) < B_OK)
return false;
if (roster->Translate(&stream, NULL, NULL, &file, type) < B_OK)
return false;
return true;
return true;
}
@ -283,63 +293,67 @@ bool bitmap_save(void *vbitmap, const char *path, unsigned flags)
*/
void bitmap_modified(void *vbitmap)
{
struct bitmap *bitmap = (struct bitmap *)vbitmap;
// convert the shadow (ABGR) to into the primary bitmap
nsbeos_rgba_to_bgra(bitmap->shadow->Bits(), bitmap->primary->Bits(),
bitmap->primary->Bounds().Width() + 1,
bitmap->primary->Bounds().Height() + 1,
bitmap->primary->BytesPerRow());
nsbeos_bitmap_free_pretiles(bitmap);
struct bitmap *bitmap = (struct bitmap *)vbitmap;
// convert the shadow (ABGR) to into the primary bitmap
nsbeos_rgba_to_bgra(bitmap->shadow->Bits(), bitmap->primary->Bits(),
bitmap->primary->Bounds().Width() + 1,
bitmap->primary->Bounds().Height() + 1,
bitmap->primary->BytesPerRow());
nsbeos_bitmap_free_pretiles(bitmap);
}
int bitmap_get_width(void *vbitmap)
{
struct bitmap *bitmap = (struct bitmap *)vbitmap;
return bitmap->primary->Bounds().Width() + 1;
struct bitmap *bitmap = (struct bitmap *)vbitmap;
return bitmap->primary->Bounds().Width() + 1;
}
int bitmap_get_height(void *vbitmap)
{
struct bitmap *bitmap = (struct bitmap *)vbitmap;
return bitmap->primary->Bounds().Height() + 1;
struct bitmap *bitmap = (struct bitmap *)vbitmap;
return bitmap->primary->Bounds().Height() + 1;
}
static BBitmap *
nsbeos_bitmap_generate_pretile(BBitmap *primary, int repeat_x, int repeat_y)
{
int width = primary->Bounds().Width() + 1;
int height = primary->Bounds().Height() + 1;
size_t primary_stride = primary->BytesPerRow();
BRect frame(0, 0, width * repeat_x - 1, height * repeat_y - 1);
BBitmap *result = new BBitmap(frame, 0, B_RGBA32);
int width = primary->Bounds().Width() + 1;
int height = primary->Bounds().Height() + 1;
size_t primary_stride = primary->BytesPerRow();
BRect frame(0, 0, width * repeat_x - 1, height * repeat_y - 1);
BBitmap *result = new BBitmap(frame, 0, B_RGBA32);
char *target_buffer = (char *)result->Bits();
int x,y,row;
/* This algorithm won't work if the strides are not multiples */
assert((size_t)(result->BytesPerRow()) ==
(primary_stride * repeat_x));
char *target_buffer = (char *)result->Bits();
int x,y,row;
/* This algorithm won't work if the strides are not multiples */
assert((size_t)(result->BytesPerRow()) ==
(primary_stride * repeat_x));
if (repeat_x == 1 && repeat_y == 1) {
delete result;
// just return a copy
return new BBitmap(primary);
}
if (repeat_x == 1 && repeat_y == 1) {
delete result;
// just return a copy
return new BBitmap(primary);
}
for (y = 0; y < repeat_y; ++y) {
char *primary_buffer = (char *)primary->Bits();
for (row = 0; row < height; ++row) {
for (x = 0; x < repeat_x; ++x) {
memcpy(target_buffer,
primary_buffer, primary_stride);
target_buffer += primary_stride;
}
primary_buffer += primary_stride;
}
}
return result;
for (y = 0; y < repeat_y; ++y) {
char *primary_buffer = (char *)primary->Bits();
for (row = 0; row < height; ++row) {
for (x = 0; x < repeat_x; ++x) {
memcpy(target_buffer,
primary_buffer, primary_stride);
target_buffer += primary_stride;
}
primary_buffer += primary_stride;
}
}
return result;
}
/**
* The primary image associated with this bitmap object.
*
@ -348,9 +362,10 @@ nsbeos_bitmap_generate_pretile(BBitmap *primary, int repeat_x, int repeat_y)
BBitmap *
nsbeos_bitmap_get_primary(struct bitmap* bitmap)
{
return bitmap->primary;
return bitmap->primary;
}
/**
* The X-pretiled image associated with this bitmap object.
*
@ -359,16 +374,17 @@ nsbeos_bitmap_get_primary(struct bitmap* bitmap)
BBitmap *
nsbeos_bitmap_get_pretile_x(struct bitmap* bitmap)
{
if (!bitmap->pretile_x) {
int width = bitmap->primary->Bounds().Width() + 1;
int xmult = (MIN_PRETILE_WIDTH + width - 1)/width;
LOG(("Pretiling %p for X*%d", bitmap, xmult));
bitmap->pretile_x = nsbeos_bitmap_generate_pretile(bitmap->primary, xmult, 1);
}
return bitmap->pretile_x;
if (!bitmap->pretile_x) {
int width = bitmap->primary->Bounds().Width() + 1;
int xmult = (MIN_PRETILE_WIDTH + width - 1)/width;
LOG(("Pretiling %p for X*%d", bitmap, xmult));
bitmap->pretile_x = nsbeos_bitmap_generate_pretile(bitmap->primary, xmult, 1);
}
return bitmap->pretile_x;
}
/**
* The Y-pretiled image associated with this bitmap object.
*
@ -377,15 +393,16 @@ nsbeos_bitmap_get_pretile_x(struct bitmap* bitmap)
BBitmap *
nsbeos_bitmap_get_pretile_y(struct bitmap* bitmap)
{
if (!bitmap->pretile_y) {
int height = bitmap->primary->Bounds().Height() + 1;
int ymult = (MIN_PRETILE_HEIGHT + height - 1)/height;
LOG(("Pretiling %p for Y*%d", bitmap, ymult));
bitmap->pretile_y = nsbeos_bitmap_generate_pretile(bitmap->primary, 1, ymult);
}
return bitmap->pretile_y;
if (!bitmap->pretile_y) {
int height = bitmap->primary->Bounds().Height() + 1;
int ymult = (MIN_PRETILE_HEIGHT + height - 1)/height;
LOG(("Pretiling %p for Y*%d", bitmap, ymult));
bitmap->pretile_y = nsbeos_bitmap_generate_pretile(bitmap->primary, 1, ymult);
}
return bitmap->pretile_y;
}
/**
* The XY-pretiled image associated with this bitmap object.
*
@ -394,30 +411,146 @@ nsbeos_bitmap_get_pretile_y(struct bitmap* bitmap)
BBitmap *
nsbeos_bitmap_get_pretile_xy(struct bitmap* bitmap)
{
if (!bitmap->pretile_xy) {
int width = bitmap->primary->Bounds().Width() + 1;
int height = bitmap->primary->Bounds().Height() + 1;
int xmult = (MIN_PRETILE_WIDTH + width - 1)/width;
int ymult = (MIN_PRETILE_HEIGHT + height - 1)/height;
LOG(("Pretiling %p for X*%d Y*%d", bitmap, xmult, ymult));
bitmap->pretile_xy = nsbeos_bitmap_generate_pretile(bitmap->primary, xmult, ymult);
}
return bitmap->pretile_xy;
if (!bitmap->pretile_xy) {
int width = bitmap->primary->Bounds().Width() + 1;
int height = bitmap->primary->Bounds().Height() + 1;
int xmult = (MIN_PRETILE_WIDTH + width - 1)/width;
int ymult = (MIN_PRETILE_HEIGHT + height - 1)/height;
LOG(("Pretiling %p for X*%d Y*%d", bitmap, xmult, ymult));
bitmap->pretile_xy = nsbeos_bitmap_generate_pretile(bitmap->primary, xmult, ymult);
}
return bitmap->pretile_xy;
}
/**
* Create a thumbnail of a page.
*
* \param bitmap the bitmap to draw to
* \param content content structure to thumbnail
* \return true on success and bitmap updated else false
*/
static nserror bitmap_render(struct bitmap *bitmap, hlcache_handle *content)
{
BBitmap *thumbnail;
BBitmap *small;
BBitmap *big;
BView *oldView;
BView *view;
BView *thumbView;
float width;
float height;
int big_width;
int big_height;
int depth;
struct redraw_context ctx;
ctx.interactive = false;
ctx.background_images = true;
ctx.plot = &nsbeos_plotters;
assert(content);
assert(bitmap);
thumbnail = nsbeos_bitmap_get_primary(bitmap);
width = thumbnail->Bounds().Width();
height = thumbnail->Bounds().Height();
depth = 32;
big_width = MIN(content_get_width(content), 1024);
big_height = (int)(((big_width * height) + (width / 2)) / width);
BRect contentRect(0, 0, big_width - 1, big_height - 1);
big = new BBitmap(contentRect, B_BITMAP_ACCEPTS_VIEWS, B_RGB32);
if (big->InitCheck() < B_OK) {
delete big;
return NSERROR_NOMEM;
}
small = new BBitmap(thumbnail->Bounds(),
B_BITMAP_ACCEPTS_VIEWS, B_RGB32);
if (small->InitCheck() < B_OK) {
delete small;
delete big;
return NSERROR_NOMEM;
}
//XXX: _lock ?
// backup the current gc
oldView = nsbeos_current_gc();
view = new BView(contentRect, "thumbnailer",
B_FOLLOW_NONE, B_WILL_DRAW);
big->AddChild(view);
thumbView = new BView(small->Bounds(), "thumbnail",
B_FOLLOW_NONE, B_WILL_DRAW);
small->AddChild(thumbView);
view->LockLooper();
/* impose our view on the content... */
nsbeos_current_gc_set(view);
/* render the content */
content_scaled_redraw(content, big_width, big_height, &ctx);
view->Sync();
view->UnlockLooper();
// restore the current gc
nsbeos_current_gc_set(oldView);
// now scale it down
//XXX: use Zeta's bilinear scaler ?
//#ifdef B_ZETA_VERSION
// err = ScaleBitmap(*shot, *scaledBmp);
//#else
thumbView->LockLooper();
thumbView->DrawBitmap(big, big->Bounds(), small->Bounds());
thumbView->Sync();
thumbView->UnlockLooper();
small->LockBits();
thumbnail->LockBits();
// copy it to the bitmap
memcpy(thumbnail->Bits(), small->Bits(), thumbnail->BitsLength());
thumbnail->UnlockBits();
small->UnlockBits();
bitmap_modified(bitmap);
// cleanup
small->RemoveChild(thumbView);
delete thumbView;
delete small;
big->RemoveChild(view);
delete view;
delete big;
return NSERROR_OK;
}
static struct gui_bitmap_table bitmap_table = {
.create = bitmap_create,
.destroy = bitmap_destroy,
.set_opaque = bitmap_set_opaque,
.get_opaque = bitmap_get_opaque,
.test_opaque = bitmap_test_opaque,
.get_buffer = bitmap_get_buffer,
.get_rowstride = bitmap_get_rowstride,
.get_width = bitmap_get_width,
.get_height = bitmap_get_height,
.get_bpp = bitmap_get_bpp,
.save = bitmap_save,
.modified = bitmap_modified,
.create = bitmap_create,
.destroy = bitmap_destroy,
.set_opaque = bitmap_set_opaque,
.get_opaque = bitmap_get_opaque,
.test_opaque = bitmap_test_opaque,
.get_buffer = bitmap_get_buffer,
.get_rowstride = bitmap_get_rowstride,
.get_width = bitmap_get_width,
.get_height = bitmap_get_height,
.get_bpp = bitmap_get_bpp,
.save = bitmap_save,
.modified = bitmap_modified,
.render = bitmap_render,
};
struct gui_bitmap_table *beos_bitmap_table = &bitmap_table;

View File

@ -1,163 +0,0 @@
/*
* Copyright 2008 François Revol <mmu_man@users.sourceforge.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file
* Page thumbnail creation (implementation).
*
* Thumbnails are created by setting the current drawing contexts to a BView
* attached to the BBitmap we are passed, and plotting the page at a small
* scale.
*/
#define __STDBOOL_H__ 1
#include <assert.h>
#include <sys/param.h>
#include <Bitmap.h>
#include <View.h>
extern "C" {
#include "content/content.h"
#include "content/urldb.h"
#include "desktop/plotters.h"
#include "desktop/browser.h"
#include "desktop/thumbnail.h"
#include "image/bitmap.h"
#include "desktop/font.h"
#include "utils/log.h"
}
#include "beos/scaffolding.h"
#include "beos/plotters.h"
#include "beos/bitmap.h"
// Zeta PRIVATE: in libzeta for now.
extern status_t ScaleBitmap(const BBitmap& inBitmap, BBitmap& outBitmap);
#warning XXX do we need to set bitmap:shadow ?
/**
* Create a thumbnail of a page.
*
* \param content content structure to thumbnail
* \param bitmap the bitmap to draw to
* \return true on success and bitmap updated else false
*/
bool thumbnail_create(hlcache_handle *content, struct bitmap *bitmap)
{
BBitmap *thumbnail;
BBitmap *small;
BBitmap *big;
BView *oldView;
BView *view;
BView *thumbView;
float width;
float height;
int big_width;
int big_height;
int depth;
struct redraw_context ctx;
ctx.interactive = false;
ctx.background_images = true;
ctx.plot = &nsbeos_plotters;
assert(content);
assert(bitmap);
thumbnail = nsbeos_bitmap_get_primary(bitmap);
width = thumbnail->Bounds().Width();
height = thumbnail->Bounds().Height();
depth = 32;
big_width = MIN(content_get_width(content), 1024);
big_height = (int)(((big_width * height) + (width / 2)) / width);
BRect contentRect(0, 0, big_width - 1, big_height - 1);
big = new BBitmap(contentRect, B_BITMAP_ACCEPTS_VIEWS, B_RGB32);
if (big->InitCheck() < B_OK) {
delete big;
return false;
}
small = new BBitmap(thumbnail->Bounds(),
B_BITMAP_ACCEPTS_VIEWS, B_RGB32);
if (small->InitCheck() < B_OK) {
delete small;
delete big;
return false;
}
//XXX: _lock ?
// backup the current gc
oldView = nsbeos_current_gc();
view = new BView(contentRect, "thumbnailer",
B_FOLLOW_NONE, B_WILL_DRAW);
big->AddChild(view);
thumbView = new BView(small->Bounds(), "thumbnail",
B_FOLLOW_NONE, B_WILL_DRAW);
small->AddChild(thumbView);
view->LockLooper();
/* impose our view on the content... */
nsbeos_current_gc_set(view);
/* render the content */
thumbnail_redraw(content, big_width, big_height, &ctx);
view->Sync();
view->UnlockLooper();
// restore the current gc
nsbeos_current_gc_set(oldView);
// now scale it down
//XXX: use Zeta's bilinear scaler ?
//#ifdef B_ZETA_VERSION
// err = ScaleBitmap(*shot, *scaledBmp);
//#else
thumbView->LockLooper();
thumbView->DrawBitmap(big, big->Bounds(), small->Bounds());
thumbView->Sync();
thumbView->UnlockLooper();
small->LockBits();
thumbnail->LockBits();
// copy it to the bitmap
memcpy(thumbnail->Bits(), small->Bits(), thumbnail->BitsLength());
thumbnail->UnlockBits();
small->UnlockBits();
bitmap_modified(bitmap);
// cleanup
small->RemoveChild(thumbView);
delete thumbView;
delete small;
big->RemoveChild(view);
delete view;
delete big;
return true;
}

View File

@ -87,7 +87,6 @@ S_COCOA := \
plotter.m \
schedule.m \
selection.m \
thumbnail.m \
utils.m \
ArrowBox.m \
ArrowWindow.m \

View File

@ -16,11 +16,21 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* \file
* Cocoa implementation of bitmap operations.
*/
#import <Cocoa/Cocoa.h>
#import "cocoa/bitmap.h"
#import "desktop/browser.h"
#import "desktop/plotters.h"
#import "image/bitmap.h"
#import "content/urldb.h"
#import "content/content.h"
#import "cocoa/plotter.h"
#import "cocoa/bitmap.h"
#define BITS_PER_SAMPLE (8)
#define SAMPLES_PER_PIXEL (4)
@ -65,24 +75,25 @@ void bitmap_destroy(void *bitmap)
CGImageRelease( image );
NSMapRemove( cache, bitmap );
}
NSBitmapImageRep *bmp = (NSBitmapImageRep *)bitmap;
[bmp release];
}
void *bitmap_create(int width, int height, unsigned int state)
{
NSBitmapImageRep *bmp = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
pixelsWide: width
pixelsHigh: height
bitsPerSample: BITS_PER_SAMPLE
samplesPerPixel: SAMPLES_PER_PIXEL
hasAlpha: YES
isPlanar: NO
colorSpaceName: NSDeviceRGBColorSpace
bitmapFormat: NSAlphaNonpremultipliedBitmapFormat
bytesPerRow: BYTES_PER_PIXEL * width
bitsPerPixel: BITS_PER_PIXEL];
NSBitmapImageRep *bmp = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes: NULL
pixelsWide: width
pixelsHigh: height
bitsPerSample: BITS_PER_SAMPLE
samplesPerPixel: SAMPLES_PER_PIXEL
hasAlpha: YES
isPlanar: NO
colorSpaceName: NSDeviceRGBColorSpace
bitmapFormat: NSAlphaNonpremultipliedBitmapFormat
bytesPerRow: BYTES_PER_PIXEL * width
bitsPerPixel: BITS_PER_PIXEL];
return bmp;
}
@ -118,12 +129,12 @@ size_t bitmap_get_bpp(void *bitmap)
bool bitmap_test_opaque(void *bitmap)
{
NSCParameterAssert( bitmap_get_bpp( bitmap ) == BYTES_PER_PIXEL );
unsigned char *buf = bitmap_get_buffer( bitmap );
const size_t height = bitmap_get_height( bitmap );
const size_t width = bitmap_get_width( bitmap );
const size_t line_step = bitmap_get_rowstride( bitmap ) - BYTES_PER_PIXEL * width;
for (size_t y = 0; y < height; y++) {
@ -133,7 +144,7 @@ bool bitmap_test_opaque(void *bitmap)
}
buf += line_step;
}
return true;
}
@ -141,7 +152,7 @@ bool bitmap_save(void *bitmap, const char *path, unsigned flags)
{
NSCParameterAssert( NULL != bitmap );
NSBitmapImageRep *bmp = (NSBitmapImageRep *)bitmap;
NSData *tiff = [bmp TIFFRepresentation];
return [tiff writeToFile: [NSString stringWithUTF8String: path] atomically: YES];
}
@ -165,7 +176,7 @@ CGImageRef cocoa_get_cgimage( void *bitmap )
result = cocoa_prepare_bitmap( bitmap );
NSMapInsertKnownAbsent( cache, bitmap, result );
}
return result;
}
@ -181,40 +192,77 @@ static inline NSMapTable *cocoa_get_bitmap_cache( void )
static CGImageRef cocoa_prepare_bitmap( void *bitmap )
{
NSCParameterAssert( NULL != bitmap );
NSBitmapImageRep *bmp = (NSBitmapImageRep *)bitmap;
size_t w = [bmp pixelsWide];
size_t h = [bmp pixelsHigh];
CGImageRef original = [bmp CGImage];
if (h <= 1) return CGImageRetain( original );
void *data = malloc( 4 * w * h );
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate( data, w, h, BITS_PER_SAMPLE,
BYTES_PER_PIXEL * w, colorSpace,
[bmp isOpaque] ? kCGImageAlphaNoneSkipLast
: kCGImageAlphaPremultipliedLast );
CGContextRef context = CGBitmapContextCreate( data, w, h, BITS_PER_SAMPLE,
BYTES_PER_PIXEL * w, colorSpace,
[bmp isOpaque] ? kCGImageAlphaNoneSkipLast
: kCGImageAlphaPremultipliedLast );
CGColorSpaceRelease( colorSpace );
CGContextTranslateCTM( context, 0.0, h );
CGContextScaleCTM( context, 1.0, -1.0 );
CGRect rect = CGRectMake( 0, 0, w, h );
CGContextClearRect( context, rect );
CGContextDrawImage( context, rect, original );
CGImageRef result = CGBitmapContextCreateImage( context );
CGContextRelease( context );
free( data );
return result;
}
static nserror bitmap_render(struct bitmap *bitmap, struct hlcache_handle *content)
{
int bwidth = bitmap_get_width( bitmap );
int bheight = bitmap_get_height( bitmap );
struct redraw_context ctx = {
.interactive = false,
.background_images = true,
.plot = &cocoa_plotters
};
CGColorSpaceRef cspace = CGColorSpaceCreateWithName( kCGColorSpaceGenericRGB );
CGContextRef bitmapContext = CGBitmapContextCreate( bitmap_get_buffer( bitmap ),
bwidth, bheight,
bitmap_get_bpp( bitmap ) * 8 / 4,
bitmap_get_rowstride( bitmap ),
cspace, kCGImageAlphaNoneSkipLast );
CGColorSpaceRelease( cspace );
size_t width = MIN( content_get_width( content ), 1024 );
size_t height = ((width * bheight) + bwidth / 2) / bwidth;
CGContextTranslateCTM( bitmapContext, 0, bheight );
CGContextScaleCTM( bitmapContext, (CGFloat)bwidth / width, -(CGFloat)bheight / height );
[NSGraphicsContext setCurrentContext: [NSGraphicsContext graphicsContextWithGraphicsPort: bitmapContext flipped: YES]];
content_scaled_redraw( content, width, height, &ctx );
[NSGraphicsContext setCurrentContext: nil];
CGContextRelease( bitmapContext );
bitmap_modified( bitmap );
return true;
}
static struct gui_bitmap_table bitmap_table = {
.create = bitmap_create,
.destroy = bitmap_destroy,
@ -228,6 +276,7 @@ static struct gui_bitmap_table bitmap_table = {
.get_bpp = bitmap_get_bpp,
.save = bitmap_save,
.modified = bitmap_modified,
.render = bitmap_render,
};
struct gui_bitmap_table *cocoa_bitmap_table = &bitmap_table;

View File

@ -1,65 +0,0 @@
/*
* Copyright 2011 Sven Weidauer <sven.weidauer@gmail.com>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import <Cocoa/Cocoa.h>
#import "desktop/browser.h"
#import "desktop/plotters.h"
#import "desktop/thumbnail.h"
#import "content/urldb.h"
#import "cocoa/plotter.h"
#import "image/bitmap.h"
/* In platform specific thumbnail.c. */
bool thumbnail_create(struct hlcache_handle *content, struct bitmap *bitmap)
{
int bwidth = bitmap_get_width( bitmap );
int bheight = bitmap_get_height( bitmap );
struct redraw_context ctx = {
.interactive = false,
.background_images = true,
.plot = &cocoa_plotters
};
CGColorSpaceRef cspace = CGColorSpaceCreateWithName( kCGColorSpaceGenericRGB );
CGContextRef bitmapContext = CGBitmapContextCreate( bitmap_get_buffer( bitmap ),
bwidth, bheight,
bitmap_get_bpp( bitmap ) * 8 / 4,
bitmap_get_rowstride( bitmap ),
cspace, kCGImageAlphaNoneSkipLast );
CGColorSpaceRelease( cspace );
size_t width = MIN( content_get_width( content ), 1024 );
size_t height = ((width * bheight) + bwidth / 2) / bwidth;
CGContextTranslateCTM( bitmapContext, 0, bheight );
CGContextScaleCTM( bitmapContext, (CGFloat)bwidth / width, -(CGFloat)bheight / height );
[NSGraphicsContext setCurrentContext: [NSGraphicsContext graphicsContextWithGraphicsPort: bitmapContext flipped: YES]];
thumbnail_redraw( content, width, height, &ctx );
[NSGraphicsContext setCurrentContext: nil];
CGContextRelease( bitmapContext );
bitmap_modified( bitmap );
return true;
}

View File

@ -33,7 +33,9 @@
#include "content/content_protected.h"
#include "content/hlcache.h"
#include "image/bitmap.h"
#include "desktop/knockout.h"
#include "desktop/browser.h"
#include "desktop/plotters.h"
#include "desktop/gui_internal.h"
#include "utils/nsoption.h"
@ -551,8 +553,7 @@ void content__request_redraw(struct content *c,
/**
* Display content on screen with optional tiling.
*
* Calls the redraw_tile function for the content, or emulates it with the
* redraw function if it doesn't exist.
* Calls the redraw function for the content.
*/
bool content_redraw(hlcache_handle *h, struct content_redraw_data *data,
@ -576,6 +577,74 @@ bool content_redraw(hlcache_handle *h, struct content_redraw_data *data,
}
/* exported interface, documented in content/content.h */
bool content_scaled_redraw(struct hlcache_handle *h,
int width, int height, const struct redraw_context *ctx)
{
struct content *c = hlcache_handle_get_content(h);
struct redraw_context new_ctx = *ctx;
struct rect clip;
struct content_redraw_data data;
bool plot_ok = true;
assert(c != NULL);
/* ensure it is safe to attempt redraw */
if (c->locked) {
return true;
}
/* ensure we have a redrawable content */
if (c->handler->redraw == NULL) {
return true;
}
LOG(("Content %p %dx%d ctx:%p", c, width, height, ctx));
if (ctx->plot->option_knockout) {
knockout_plot_start(ctx, &new_ctx);
}
/* Set clip rectangle to required thumbnail size */
clip.x0 = 0;
clip.y0 = 0;
clip.x1 = width;
clip.y1 = height;
new_ctx.plot->clip(&clip);
/* Plot white background */
plot_ok &= new_ctx.plot->rectangle(clip.x0, clip.y0, clip.x1, clip.y1,
plot_style_fill_white);
/* Set up content redraw data */
data.x = 0;
data.y = 0;
data.width = width;
data.height = height;
data.background_colour = 0xFFFFFF;
data.repeat_x = false;
data.repeat_y = false;
/* Find the scale factor to use if the content has a width */
if (c->width) {
data.scale = (float)width / (float)c->width;
} else {
data.scale = 1.0;
}
/* Render the content */
plot_ok &= c->handler->redraw(c, &data, &clip, &new_ctx);
if (ctx->plot->option_knockout) {
knockout_plot_end();
}
return plot_ok;
}
/**
* Register a user for callbacks.
*

View File

@ -270,6 +270,27 @@ void content_mouse_action(struct hlcache_handle *h, struct browser_window *bw,
bool content_keypress(struct hlcache_handle *h, uint32_t key);
bool content_redraw(struct hlcache_handle *h, struct content_redraw_data *data,
const struct rect *clip, const struct redraw_context *ctx);
/**
* Redraw a content with scale set for horizontal fit.
*
* Redraws the content at a specified width and height with the
* content drawing scaled to fit within the area.
*
* \param content The content to redraw
* \param width The target width
* \param height The target height
* \param ctx current redraw context
* \return true if successful, false otherwise
*
* The thumbnail is guaranteed to be filled to its width/height extents, so
* there is no need to render a solid background first.
*
* Units for width and height are pixels.
*/
bool content_scaled_redraw(struct hlcache_handle *content, int width, int height, const struct redraw_context *ctx);
void content_open(struct hlcache_handle *h, struct browser_window *bw,
struct content *page, struct object_params *params);
void content_close(struct hlcache_handle *h);

View File

@ -2,7 +2,7 @@
S_DESKTOP := cookie_manager.c knockout.c hotlist.c mouse.c \
plot_style.c print.c search.c searchweb.c scrollbar.c \
sslcert_viewer.c textarea.c thumbnail.c tree.c version.c \
sslcert_viewer.c textarea.c tree.c version.c \
system_colour.c global_history.c treeview.c
S_DESKTOP := $(addprefix desktop/,$(S_DESKTOP))

View File

@ -1363,7 +1363,7 @@ static nserror browser_window_callback(hlcache_handle *c,
* explode or overwrite the node for the previous URL.
*
* We call it after, rather than before urldb_add_url
* because history_add calls thumbnail_create, which
* because history_add calls bitmap render, which
* tries to register the thumbnail with urldb. That
* thumbnail registration fails if the url doesn't
* exist in urldb already, and only urldb-registered

View File

@ -41,7 +41,6 @@
#include "desktop/browser_history.h"
#include "desktop/browser_private.h"
#include "desktop/plotters.h"
#include "desktop/thumbnail.h"
#include "desktop/font.h"
#define WIDTH 100
@ -281,13 +280,18 @@ browser_window_history__redraw_entry(struct history *history,
rect.y0 = y0 + yoffset;
rect.x1 = x1 + xoffset;
rect.y1 = y1 + yoffset;
if(!plot->clip(&rect))
if (!plot->clip(&rect)) {
return false;
}
}
if (!plot->bitmap(entry->x + xoffset, entry->y + yoffset, WIDTH, HEIGHT,
entry->bitmap, 0xffffff, 0))
return false;
/* Only attempt to plot bitmap if it is present */
if (entry->bitmap != NULL) {
plot->bitmap(entry->x + xoffset,
entry->y + yoffset,
WIDTH, HEIGHT,
entry->bitmap, 0xffffff, 0);
}
if (!plot->rectangle(entry->x - 1 + xoffset,
entry->y - 1 + yoffset,
entry->x + xoffset + WIDTH,
@ -466,6 +470,7 @@ nserror browser_window_history_add(struct browser_window *bw,
nsurl *nsurl = hlcache_handle_get_url(content);
char *title;
struct bitmap *bitmap;
nserror ret;
assert(bw);
assert(bw->history);
@ -516,7 +521,8 @@ nserror browser_window_history_add(struct browser_window *bw,
BITMAP_NEW | BITMAP_CLEAR_MEMORY |
BITMAP_OPAQUE);
if (bitmap != NULL) {
if (thumbnail_create(content, bitmap)) {
ret = guit->bitmap->render(bitmap, content);
if (ret == NSERROR_OK) {
/* Successful thumbnail so register it
* with the url.
*/
@ -525,7 +531,7 @@ nserror browser_window_history_add(struct browser_window *bw,
/* Thumbnailing failed. Ignore it
* silently but clean up bitmap.
*/
LOG(("Thumbnail bitmap creation failed"));
LOG(("Thumbnail renderfailed"));
guit->bitmap->destroy(bitmap);
bitmap = NULL;
}
@ -565,7 +571,7 @@ nserror browser_window_history_update(struct browser_window *bw,
free(history->current->page.title);
history->current->page.title = title;
thumbnail_create(content, history->current->bitmap);
guit->bitmap->render(history->current->bitmap, content);
return NSERROR_OK;
}

View File

@ -620,6 +620,10 @@ static nserror verify_bitmap_register(struct gui_bitmap_table *gbt)
return NSERROR_BAD_PARAMETER;
}
if (gbt->render == NULL) {
return NSERROR_BAD_PARAMETER;
}
return NSERROR_OK;
}

View File

@ -1,110 +0,0 @@
/*
* Copyright 2011 Michael Drake <tlsa@netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file
* Core thumbnail handling (implementation).
*/
#include <assert.h>
#include <stdbool.h>
#include "content/content.h"
#include "content/hlcache.h"
#include "desktop/browser.h"
#include "desktop/knockout.h"
#include "utils/nsoption.h"
#include "desktop/plotters.h"
#include "desktop/thumbnail.h"
#include "utils/log.h"
/**
* Get scale at which thumbnail will be rendered for a given content and
* thumbnail size.
*
* \param content The content to redraw for thumbnail
* \param width The thumbnail width
* \return scale thumbnail will be rendered at
*
* Units for width and height are pixels.
*/
static float thumbnail_get_redraw_scale(struct hlcache_handle *content,
int width)
{
assert(content);
if (content_get_width(content))
return (float)width / (float)content_get_width(content);
else
return 1.0;
}
/* exported interface, documented in thumbnail.h */
bool thumbnail_redraw(struct hlcache_handle *content,
int width, int height, const struct redraw_context *ctx)
{
struct redraw_context new_ctx = *ctx;
struct rect clip;
struct content_redraw_data data;
float scale;
bool plot_ok = true;
assert(content);
LOG(("Content %p %dx%d ctx:%p", content, width, height, ctx));
if (ctx->plot->option_knockout) {
knockout_plot_start(ctx, &new_ctx);
}
/* Set clip rectangle to required thumbnail size */
clip.x0 = 0;
clip.y0 = 0;
clip.x1 = width;
clip.y1 = height;
new_ctx.plot->clip(&clip);
/* Plot white background */
plot_ok &= new_ctx.plot->rectangle(clip.x0, clip.y0, clip.x1, clip.y1,
plot_style_fill_white);
/* Find the scale we're using */
scale = thumbnail_get_redraw_scale(content, width);
/* Set up content redraw data */
data.x = 0;
data.y = 0;
data.width = width;
data.height = height;
data.background_colour = 0xFFFFFF;
data.scale = scale;
data.repeat_x = false;
data.repeat_y = false;
/* Render the content */
plot_ok &= content_redraw(content, &data, &clip, &new_ctx);
if (ctx->plot->option_knockout) {
knockout_plot_end();
}
return plot_ok;
}

View File

@ -1,55 +0,0 @@
/*
* Copyright 2011 Michael Drake <tlsa@netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file
* Thumbail handling (interface).
*/
#ifndef _NETSURF_DESKTOP_THUMBNAIL_H_
#define _NETSURF_DESKTOP_THUMBNAIL_H_
#include <stdbool.h>
struct hlcache_handle;
struct redraw_context;
struct bitmap;
/**
* Redraw a content for thumbnailing
*
* Calls the redraw function for the content,
*
* \param content The content to redraw for thumbnail
* \param width The thumbnail width
* \param height The thumbnail height
* \param ctx current redraw context
* \return true if successful, false otherwise
*
* The thumbnail is guaranteed to be filled to its width/height extents, so
* there is no need to render a solid background first.
*
* Units for width and height are pixels.
*/
bool thumbnail_redraw(struct hlcache_handle *content, int width, int height,
const struct redraw_context *ctx);
/* In platform specific thumbnail.c. */
bool thumbnail_create(struct hlcache_handle *content, struct bitmap *bitmap);
#endif

View File

@ -163,9 +163,8 @@ $(eval $(foreach V,$(filter FB_FONT_$(NETSURF_FB_FONTLIB)_%,$(.VARIABLES)),$(cal
# ----------------------------------------------------------------------------
# S_FRAMEBUFFER are sources purely for the framebuffer build
S_FRAMEBUFFER := gui.c framebuffer.c schedule.c \
thumbnail.c misc.c bitmap.c fetch.c findfile.c \
localhistory.c clipboard.c
S_FRAMEBUFFER := gui.c framebuffer.c schedule.c misc.c bitmap.c fetch.c \
findfile.c localhistory.c clipboard.c
S_FRAMEBUFFER_FBTK := fbtk.c event.c fill.c bitmap.c user.c window.c \
text.c scroll.c osk.c

View File

@ -26,10 +26,17 @@
#include <stdbool.h>
#include <assert.h>
#include <libnsfb.h>
#include <libnsfb_plot.h>
#include "image/bitmap.h"
#include "utils/log.h"
#include "utils/utils.h"
#include "image/bitmap.h"
#include "desktop/plotters.h"
#include "content/content.h"
#include "framebuffer/gui.h"
#include "framebuffer/fbtk.h"
#include "framebuffer/framebuffer.h"
#include "framebuffer/bitmap.h"
/**
@ -249,6 +256,76 @@ static size_t bitmap_get_bpp(void *bitmap)
return 4;
}
/**
* Render content into a bitmap.
*
* \param bitmap the bitmap to draw to
* \param content content structure to render
* \return true on success and bitmap updated else false
*/
static nserror
bitmap_render(struct bitmap *bitmap,
struct hlcache_handle *content)
{
nsfb_t *tbm = (nsfb_t *)bitmap; /* target bitmap */
nsfb_t *bm; /* temporary bitmap */
nsfb_t *current; /* current main fb */
int width, height; /* target bitmap width height */
int cwidth, cheight;/* content width /height */
nsfb_bbox_t loc;
struct redraw_context ctx = {
.interactive = false,
.background_images = true,
.plot = &fb_plotters
};
nsfb_get_geometry(tbm, &width, &height, NULL);
LOG(("width %d, height %d", width, height));
/* Calculate size of buffer to render the content into */
/* We get the width from the content width, unless it exceeds 1024,
* in which case we use 1024. This means we never create excessively
* large render buffers for huge contents, which would eat memory and
* cripple performance. */
cwidth = min(content_get_width(content), 1024);
/* The height is set in proportion with the width, according to the
* aspect ratio of the required thumbnail. */
cheight = ((cwidth * height) + (width / 2)) / width;
/* create temporary surface */
bm = nsfb_new(NSFB_SURFACE_RAM);
if (bm == NULL) {
return NSERROR_NOMEM;
}
nsfb_set_geometry(bm, cwidth, cheight, NSFB_FMT_XBGR8888);
if (nsfb_init(bm) == -1) {
nsfb_free(bm);
return NSERROR_NOMEM;
}
current = framebuffer_set_surface(bm);
/* render the content into temporary surface */
content_scaled_redraw(content, cwidth, cheight, &ctx);
framebuffer_set_surface(current);
loc.x0 = 0;
loc.y0 = 0;
loc.x1 = width;
loc.y1 = height;
nsfb_plot_copy(bm, NULL, tbm, &loc);
nsfb_free(bm);
return NSERROR_OK;
}
static struct gui_bitmap_table bitmap_table = {
.create = bitmap_create,
.destroy = bitmap_destroy,
@ -262,6 +339,7 @@ static struct gui_bitmap_table bitmap_table = {
.get_bpp = bitmap_get_bpp,
.save = bitmap_save,
.modified = bitmap_modified,
.render = bitmap_render,
};
struct gui_bitmap_table *framebuffer_bitmap_table = &bitmap_table;

View File

@ -1,97 +0,0 @@
/*
* Copyright 2008 Chris Young <chris@unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdbool.h>
#include <libnsfb.h>
#include <libnsfb_plot.h>
#include "utils/log.h"
#include "utils/utils.h"
#include "desktop/plotters.h"
#include "desktop/thumbnail.h"
#include "content/urldb.h"
#include "content/content.h"
#include "framebuffer/gui.h"
#include "framebuffer/fbtk.h"
#include "framebuffer/framebuffer.h"
bool
thumbnail_create(struct hlcache_handle *content,
struct bitmap *bitmap)
{
nsfb_t *tbm = (nsfb_t *)bitmap; /* target bitmap */
nsfb_t *bm; /* temporary bitmap */
nsfb_t *current; /* current main fb */
int width, height; /* target bitmap width height */
int cwidth, cheight;/* content width /height */
nsfb_bbox_t loc;
struct redraw_context ctx = {
.interactive = false,
.background_images = true,
.plot = &fb_plotters
};
nsfb_get_geometry(tbm, &width, &height, NULL);
LOG(("width %d, height %d", width, height));
/* Calculate size of buffer to render the content into */
/* We get the width from the content width, unless it exceeds 1024,
* in which case we use 1024. This means we never create excessively
* large render buffers for huge contents, which would eat memory and
* cripple performance. */
cwidth = min(content_get_width(content), 1024);
/* The height is set in proportion with the width, according to the
* aspect ratio of the required thumbnail. */
cheight = ((cwidth * height) + (width / 2)) / width;
/* create temporary surface */
bm = nsfb_new(NSFB_SURFACE_RAM);
if (bm == NULL) {
return false;
}
nsfb_set_geometry(bm, cwidth, cheight, NSFB_FMT_XBGR8888);
if (nsfb_init(bm) == -1) {
nsfb_free(bm);
return false;
}
current = framebuffer_set_surface(bm);
/* render the content into temporary surface */
thumbnail_redraw(content, cwidth, cheight, &ctx);
framebuffer_set_surface(current);
loc.x0 = 0;
loc.y0 = 0;
loc.x1 = width;
loc.y1 = height;
nsfb_plot_copy(bm, NULL, tbm, &loc);
nsfb_free(bm);
return true;
}

View File

@ -107,7 +107,7 @@ S_PIXBUF :=
$(eval $(foreach V,$(filter GTK_IMAGE_%,$(.VARIABLES)),$(call convert_image,$($(V)),$(OBJROOT)/$(patsubst GTK_IMAGE_%,%,$(V)).c,$(patsubst GTK_IMAGE_%,%,$(V))_pixdata)))
# S_GTK are sources purely for the GTK build
S_GTK := font_pango.c bitmap.c gui.c schedule.c thumbnail.c plotters.c \
S_GTK := font_pango.c bitmap.c gui.c schedule.c plotters.c \
treeview.c scaffolding.c gdk.c completion.c login.c throbber.c \
selection.c history.c window.c fetch.c download.c menu.c \
print.c search.c tabs.c theme.c toolbar.c gettext.c \

View File

@ -32,8 +32,10 @@
#include "utils/log.h"
#include "content/content.h"
#include "image/bitmap.h"
#include "desktop/plotters.h"
#include "gtk/scaffolding.h"
#include "gtk/plotters.h"
#include "gtk/bitmap.h"
@ -86,17 +88,17 @@ static void bitmap_set_opaque(void *vbitmap, bool opaque)
if (fmt == CAIRO_FORMAT_RGB24) {
if (opaque == false) {
/* opaque to transparent */
nsurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
cairo_image_surface_get_width(gbitmap->surface),
nsurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
cairo_image_surface_get_width(gbitmap->surface),
cairo_image_surface_get_height(gbitmap->surface));
}
} else {
if (opaque == true) {
/* transparent to opaque */
nsurface = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
cairo_image_surface_get_width(gbitmap->surface),
nsurface = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
cairo_image_surface_get_width(gbitmap->surface),
cairo_image_surface_get_height(gbitmap->surface));
}
@ -106,8 +108,8 @@ static void bitmap_set_opaque(void *vbitmap, bool opaque)
if (cairo_surface_status(nsurface) != CAIRO_STATUS_SUCCESS) {
cairo_surface_destroy(nsurface);
} else {
memcpy(cairo_image_surface_get_data(nsurface),
cairo_image_surface_get_data(gbitmap->surface),
memcpy(cairo_image_surface_get_data(nsurface),
cairo_image_surface_get_data(gbitmap->surface),
cairo_image_surface_get_stride(gbitmap->surface) * cairo_image_surface_get_height(gbitmap->surface));
cairo_surface_destroy(gbitmap->surface);
gbitmap->surface = nsurface;
@ -116,7 +118,7 @@ static void bitmap_set_opaque(void *vbitmap, bool opaque)
}
}
}
}
@ -137,13 +139,13 @@ static bool bitmap_test_opaque(void *vbitmap)
pixels = cairo_image_surface_get_data(gbitmap->surface);
pcount = cairo_image_surface_get_stride(gbitmap->surface) *
pcount = cairo_image_surface_get_stride(gbitmap->surface) *
cairo_image_surface_get_height(gbitmap->surface);
for (ploop = 3; ploop < pcount; ploop += 4) {
if (pixels[ploop] != 0xff) {
return false;
}
}
}
return true;
@ -190,7 +192,7 @@ static unsigned char *bitmap_get_buffer(void *vbitmap)
cairo_format_t fmt;
assert(gbitmap);
cairo_surface_flush(gbitmap->surface);
pixels = cairo_image_surface_get_data(gbitmap->surface);
@ -259,7 +261,7 @@ static unsigned char *bitmap_get_buffer(void *vbitmap)
}
gbitmap->converted = false;
return (unsigned char *) pixels;
}
@ -341,7 +343,7 @@ static void bitmap_modified(void *vbitmap)
{
struct bitmap *gbitmap = (struct bitmap *)vbitmap;
int pixel_loop;
int pixel_count;
int pixel_count;
uint8_t *pixels;
uint32_t t, r, g, b;
cairo_format_t fmt;
@ -350,7 +352,7 @@ static void bitmap_modified(void *vbitmap)
fmt = cairo_image_surface_get_format(gbitmap->surface);
pixel_count = cairo_image_surface_get_width(gbitmap->surface) *
pixel_count = cairo_image_surface_get_width(gbitmap->surface) *
cairo_image_surface_get_height(gbitmap->surface);
pixels = cairo_image_surface_get_data(gbitmap->surface);
@ -411,7 +413,7 @@ static void bitmap_modified(void *vbitmap)
#endif
}
}
cairo_surface_mark_dirty(gbitmap->surface);
gbitmap->converted = true;
@ -435,6 +437,88 @@ int nsgtk_bitmap_get_height(void *vbitmap)
return cairo_image_surface_get_height(gbitmap->surface);
}
/**
* Render content into a bitmap.
*
* \param bitmap The bitmap to draw to
* \param content The content to render
* \return true on success and bitmap updated else false
*/
static nserror
bitmap_render(struct bitmap *bitmap, struct hlcache_handle *content)
{
cairo_surface_t *dsurface = bitmap->surface;
cairo_surface_t *surface;
cairo_t *old_cr;
gint dwidth, dheight;
int cwidth, cheight;
struct redraw_context ctx = {
.interactive = false,
.background_images = true,
.plot = &nsgtk_plotters
};
assert(content);
assert(bitmap);
dwidth = cairo_image_surface_get_width(dsurface);
dheight = cairo_image_surface_get_height(dsurface);
/* Calculate size of buffer to render the content into */
/* Get the width from the content width, unless it exceeds 1024,
* in which case we use 1024. This means we never create excessively
* large render buffers for huge contents, which would eat memory and
* cripple performance.
*/
cwidth = min(max(content_get_width(content), dwidth), 1024);
/* The height is set in proportion with the width, according to the
* aspect ratio of the required thumbnail. */
cheight = ((cwidth * dheight) + (dwidth / 2)) / dwidth;
/* Create surface to render into */
surface = cairo_surface_create_similar(dsurface, CAIRO_CONTENT_COLOR_ALPHA, cwidth, cheight);
if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
cairo_surface_destroy(surface);
return false;
}
old_cr = current_cr;
current_cr = cairo_create(surface);
/* render the content */
content_scaled_redraw(content, cwidth, cheight, &ctx);
cairo_destroy(current_cr);
current_cr = old_cr;
cairo_t *cr = cairo_create(dsurface);
/* Scale *before* setting the source surface (1) */
cairo_scale (cr, (double)dwidth / cwidth, (double)dheight / cheight);
cairo_set_source_surface (cr, surface, 0, 0);
/* To avoid getting the edge pixels blended with 0 alpha,
* which would occur with the default EXTEND_NONE. Use
* EXTEND_PAD for 1.2 or newer (2)
*/
cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REFLECT);
/* Replace the destination with the source instead of overlaying */
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
/* Do the actual drawing */
cairo_paint(cr);
cairo_destroy(cr);
cairo_surface_destroy(surface);
return NSERROR_OK;
}
static struct gui_bitmap_table bitmap_table = {
.create = bitmap_create,
.destroy = bitmap_destroy,
@ -448,6 +532,7 @@ static struct gui_bitmap_table bitmap_table = {
.get_bpp = bitmap_get_bpp,
.save = bitmap_save,
.modified = bitmap_modified,
.render = bitmap_render,
};
struct gui_bitmap_table *nsgtk_bitmap_table = &bitmap_table;

View File

@ -1,122 +0,0 @@
/*
* Copyright 2006 Rob Kendrick <rjek@rjek.com>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file
* Page thumbnail creation (implementation).
*
* Thumbnails are created by setting the current drawing contexts to the
* bitmap (a gdk pixbuf) we are passed, and plotting the page at a small
* scale.
*/
#include <assert.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include "utils/log.h"
#include "utils/utils.h"
#include "content/content.h"
#include "content/hlcache.h"
#include "desktop/plotters.h"
#include "desktop/browser.h"
#include "desktop/thumbnail.h"
#include "gtk/scaffolding.h"
#include "gtk/plotters.h"
#include "gtk/bitmap.h"
/**
* Create a thumbnail of a page.
*
* \param content content structure to thumbnail
* \param bitmap the bitmap to draw to
* \return true on success and bitmap updated else false
*/
bool thumbnail_create(hlcache_handle *content, struct bitmap *bitmap)
{
cairo_surface_t *dsurface = bitmap->surface;
cairo_surface_t *surface;
cairo_t *old_cr;
gint dwidth, dheight;
int cwidth, cheight;
struct redraw_context ctx = {
.interactive = false,
.background_images = true,
.plot = &nsgtk_plotters
};
assert(content);
assert(bitmap);
dwidth = cairo_image_surface_get_width(dsurface);
dheight = cairo_image_surface_get_height(dsurface);
/* Calculate size of buffer to render the content into */
/* Get the width from the content width, unless it exceeds 1024,
* in which case we use 1024. This means we never create excessively
* large render buffers for huge contents, which would eat memory and
* cripple performance.
*/
cwidth = min(max(content_get_width(content), dwidth), 1024);
/* The height is set in proportion with the width, according to the
* aspect ratio of the required thumbnail. */
cheight = ((cwidth * dheight) + (dwidth / 2)) / dwidth;
/* Create surface to render into */
surface = cairo_surface_create_similar(dsurface, CAIRO_CONTENT_COLOR_ALPHA, cwidth, cheight);
if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
cairo_surface_destroy(surface);
return false;
}
old_cr = current_cr;
current_cr = cairo_create(surface);
/* render the content */
thumbnail_redraw(content, cwidth, cheight, &ctx);
cairo_destroy(current_cr);
current_cr = old_cr;
cairo_t *cr = cairo_create(dsurface);
/* Scale *before* setting the source surface (1) */
cairo_scale (cr, (double)dwidth / cwidth, (double)dheight / cheight);
cairo_set_source_surface (cr, surface, 0, 0);
/* To avoid getting the edge pixels blended with 0 alpha,
* which would occur with the default EXTEND_NONE. Use
* EXTEND_PAD for 1.2 or newer (2)
*/
cairo_pattern_set_extend (cairo_get_source(cr), CAIRO_EXTEND_REFLECT);
/* Replace the destination with the source instead of overlaying */
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
/* Do the actual drawing */
cairo_paint(cr);
cairo_destroy(cr);
cairo_surface_destroy(surface);
return true;
}

View File

@ -28,27 +28,27 @@
* For example, an opaque 1x1 pixel image would yield the following bitmap
* data:
*
* Red : 0xff 0x00 0x00 0x00
* Green: 0x00 0xff 0x00 0x00
* Blue : 0x00 0x00 0xff 0x00
* > Red : 0xff 0x00 0x00 0x00
* > Green: 0x00 0xff 0x00 0x00
* > Blue : 0x00 0x00 0xff 0x00
*
* Any attempt to read pixels by casting bitmap data to uint32_t or similar
* will need to cater for the order of bytes in a word being different on
* big and little endian systems. To avoid confusion, it is recommended
* that pixel data is loaded as follows:
*
* uint32_t read_pixel(const uint8_t *bmp)
* {
* // red green blue alpha
* return bmp[0] | (bmp[1] << 8) | (bmp[2] << 16) | (bmp[3] << 24);
* }
* uint32_t read_pixel(const uint8_t *bmp)
* {
* // red green blue alpha
* return bmp[0] | (bmp[1] << 8) | (bmp[2] << 16) | (bmp[3] << 24);
* }
*
* and *not* as follows:
*
* uint32_t read_pixel(const uint8_t *bmp)
* {
* return *((uint32_t *) bmp);
* }
* uint32_t read_pixel(const uint8_t *bmp)
* {
* return *((uint32_t *) bmp);
* }
*/
#ifndef _NETSURF_IMAGE_BITMAP_H_
@ -61,6 +61,7 @@
struct content;
struct bitmap;
struct hlcache_handle;
/**
* Bitmap operations.
@ -163,6 +164,14 @@ struct gui_bitmap_table {
* \param bitmap The bitmap set as modified.
*/
void (*modified)(void *bitmap);
/**
* Render content into a bitmap.
*
* \param bitmap The bitmap to render into.
* \param content The content to render.
*/
nserror (*render)(struct bitmap *bitmap, struct hlcache_handle *content);
};
#endif

View File

@ -57,9 +57,8 @@ endif
# ----------------------------------------------------------------------------
# S_MONKEY are sources purely for the MONKEY build
S_MONKEY := main.c utils.c filetype.c schedule.c \
bitmap.c plot.c browser.c download.c thumbnail.c \
401login.c cert.c font.c poll.c dispatch.c fetch.c
S_MONKEY := main.c utils.c filetype.c schedule.c bitmap.c plot.c browser.c \
download.c 401login.c cert.c font.c poll.c dispatch.c fetch.c
S_MONKEY := $(addprefix monkey/,$(S_MONKEY))

View File

@ -20,6 +20,7 @@
#include <stdio.h>
#include <stdlib.h>
#include "utils/errors.h"
#include "image/bitmap.h"
#include "monkey/bitmap.h"
@ -123,6 +124,13 @@ static int bitmap_get_height(void *bitmap)
return bmap->height;
}
static nserror bitmap_render(struct bitmap *bitmap,
struct hlcache_handle *content)
{
fprintf(stdout, "GENERIC BITMAP RENDER\n");
return NSERROR_OK;
}
static struct gui_bitmap_table bitmap_table = {
.create = bitmap_create,
.destroy = bitmap_destroy,
@ -136,6 +144,7 @@ static struct gui_bitmap_table bitmap_table = {
.get_bpp = bitmap_get_bpp,
.save = bitmap_save,
.modified = bitmap_modified,
.render = bitmap_render,
};
struct gui_bitmap_table *monkey_bitmap_table = &bitmap_table;

View File

@ -1,30 +0,0 @@
/*
* Copyright 2011 Daniel Silverstone <dsilvers@digital-scurf.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#include "desktop/thumbnail.h"
#include "content/hlcache.h"
#include "monkey/browser.h"
bool thumbnail_create(hlcache_handle *content, struct bitmap *bitmap)
{
fprintf(stdout, "GENERIC THUMBNAIL\n");
return false;
}

View File

@ -69,7 +69,7 @@ S_RISCOS := 401login.c assert.c bitmap.c buffer.c cookies.c configure.c \
image.c menus.c message.c mouse.c palettes.c plotters.c \
print.c query.c save.c save_draw.c save_pdf.c schedule.c \
search.c searchweb.c sslcert.c textarea.c \
textselection.c theme.c theme_install.c thumbnail.c toolbar.c \
textselection.c theme.c theme_install.c toolbar.c \
treeview.c ucstables.c uri.c url_complete.c url_protocol.c \
url_suggest.c wimp.c wimp_event.c window.c \
$(addprefix content-handlers/,artworks.c awrender.s draw.c \

View File

@ -18,10 +18,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file
* Generic bitmap handling (RISC OS implementation).
/**
* \file
* RISC OS implementation of bitmap operations.
*
* This implements the interface given by desktop/bitmap.h using RISC OS
* This implements the interface given by image/bitmap.h using RISC OS
* sprites.
*/
@ -29,7 +30,9 @@
#include <stdbool.h>
#include <string.h>
#include <swis.h>
#include <rufl.h>
#include <unixlib/local.h>
#include <oslib/colourtrans.h>
#include <oslib/osfile.h>
#include <oslib/osfind.h>
#include <oslib/osgbpb.h>
@ -40,9 +43,11 @@
#include "utils/filename.h"
#include "utils/log.h"
#include "utils/utils.h"
#include "desktop/plotters.h"
#include "content/content.h"
#include "image/bitmap.h"
#include "riscos/gui.h"
#include "riscos/image.h"
#include "riscos/palettes.h"
#include "riscos/content-handlers/sprite.h"
@ -55,6 +60,20 @@
/** Size of buffer used when constructing mask data to be saved */
#define SAVE_CHUNK_SIZE 4096
/**
* Whether we can use 32bpp sprites
*/
static int thumbnail_32bpp_available = -1;
/**
* Sprite output context saving
*/
struct thumbnail_save_area {
osspriteop_save_area *save_area;
int context1;
int context2;
int context3;
};
/**
* Initialise a bitmaps sprite area.
@ -160,8 +179,13 @@ static void bitmap_set_opaque(void *vbitmap, bool opaque)
}
/* exported interface documented in riscos/bitmap.h */
size_t riscos_bitmap_get_rowstride(void *vbitmap)
/**
* Find the width of a pixel row in bytes.
*
* \param vbitmap A bitmap, as returned by riscos_bitmap_create()
* \return width of a pixel row in the bitmap
*/
static size_t bitmap_get_rowstride(void *vbitmap)
{
struct bitmap *bitmap = (struct bitmap *) vbitmap;
return bitmap->width * 4;
@ -188,7 +212,7 @@ static bool bitmap_test_opaque(void *vbitmap)
if (!sprite)
return false;
width = riscos_bitmap_get_rowstride(bitmap);
width = bitmap_get_rowstride(bitmap);
sprite_header = (osspriteop_header *) (bitmap->sprite_area + 1);
@ -408,24 +432,38 @@ bool riscos_bitmap_save(void *vbitmap, const char *path, unsigned flags)
}
/* exported interface documented in riscos/bitmap.h */
void riscos_bitmap_modified(void *vbitmap)
/**
* The bitmap image has changed, so flush any persistent cache.
*
* \param vbitmap a bitmap, as returned by bitmap_create()
*/
static void bitmap_modified(void *vbitmap)
{
struct bitmap *bitmap = (struct bitmap *) vbitmap;
bitmap->state |= BITMAP_MODIFIED;
}
/* exported interface documented in riscos/bitmap.h */
int riscos_bitmap_get_width(void *vbitmap)
/**
* Get the width of a bitmap.
*
* \param vbitmap A bitmap, as returned by bitmap_create()
* \return The bitmaps width in pixels.
*/
static int bitmap_get_width(void *vbitmap)
{
struct bitmap *bitmap = (struct bitmap *) vbitmap;
return bitmap->width;
}
/* exported interface documented in riscos/bitmap.h */
int riscos_bitmap_get_height(void *vbitmap)
/**
* Get the height of a bitmap.
*
* \param vbitmap A bitmap, as returned by bitmap_create()
* \return The bitmaps height in pixels.
*/
static int bitmap_get_height(void *vbitmap)
{
struct bitmap *bitmap = (struct bitmap *) vbitmap;
return bitmap->height;
@ -482,7 +520,7 @@ void riscos_bitmap_overlay_sprite(struct bitmap *bitmap,
if (h > bitmap->height)
h = bitmap->height;
dp_offset = riscos_bitmap_get_rowstride(bitmap) / 4;
dp_offset = bitmap_get_rowstride(bitmap) / 4;
dp = (void*)riscos_bitmap_get_buffer(bitmap);
if (!dp)
@ -529,6 +567,297 @@ void riscos_bitmap_overlay_sprite(struct bitmap *bitmap,
}
}
/**
* Creates an 8bpp canvas.
*
* \param bitmap the bitmap to clone the size of
* \return a sprite area containing an 8bpp sprite
*/
static osspriteop_area *thumbnail_create_8bpp(struct bitmap *bitmap)
{
unsigned image_size = ((bitmap->width + 3) & ~3) * bitmap->height;
bool opaque = riscos_bitmap_get_opaque(bitmap);
osspriteop_header *sprite_header = NULL;
osspriteop_area *sprite_area = NULL;
unsigned area_size;
/* clone the sprite */
area_size = sizeof(osspriteop_area) +
sizeof(osspriteop_header) +
image_size +
2048;
if (!opaque) area_size += image_size;
sprite_area = (osspriteop_area *)malloc(area_size);
if (!sprite_area) {
LOG(("no memory for malloc()"));
return NULL;
}
sprite_area->size = area_size;
sprite_area->sprite_count = 1;
sprite_area->first = 16;
sprite_area->used = area_size;
sprite_header = (osspriteop_header *)(sprite_area + 1);
sprite_header->size = area_size - sizeof(osspriteop_area);
memset(sprite_header->name, 0x00, 12);
strcpy(sprite_header->name, "bitmap");
sprite_header->left_bit = 0;
sprite_header->height = bitmap->height - 1;
sprite_header->mode = os_MODE8BPP90X90;
sprite_header->right_bit = ((bitmap->width << 3) - 1) & 31;
sprite_header->width = ((bitmap->width + 3) >> 2) - 1;
sprite_header->image = sizeof(osspriteop_header) + 2048;
sprite_header->mask = sizeof(osspriteop_header) + 2048;
if (!opaque) sprite_header->mask += image_size;
/* create the palette. we don't read the necessary size like
* we really should as we know it's going to have 256 entries
* of 8 bytes = 2048. */
xcolourtrans_read_palette((osspriteop_area *)os_MODE8BPP90X90,
(osspriteop_id)0,
(os_palette *)(sprite_header + 1), 2048,
(colourtrans_palette_flags)(1 << 1), 0);
return sprite_area;
}
/**
* Switches output to the specified sprite and returns the previous context.
*/
static struct thumbnail_save_area*
thumbnail_switch_output(osspriteop_area *sprite_area,
osspriteop_header *sprite_header)
{
struct thumbnail_save_area *save_area;
int size;
/* create a save area */
save_area = calloc(sizeof(struct thumbnail_save_area), 1);
if (save_area == NULL) return NULL;
/* allocate OS_SpriteOp save area */
if (xosspriteop_read_save_area_size(osspriteop_PTR, sprite_area,
(osspriteop_id)sprite_header, &size)) {
free(save_area);
return NULL;
}
/* create the save area */
save_area->save_area = malloc((unsigned)size);
if (save_area->save_area == NULL) {
free(save_area);
return NULL;
}
save_area->save_area->a[0] = 0;
/* switch output to sprite */
if (xosspriteop_switch_output_to_sprite(osspriteop_PTR, sprite_area,
(osspriteop_id)sprite_header, save_area->save_area,
0, &save_area->context1, &save_area->context2,
&save_area->context3)) {
free(save_area->save_area);
free(save_area);
return NULL;
}
return save_area;
}
/**
* Restores output to the specified context, and destroys it.
*/
static void thumbnail_restore_output(struct thumbnail_save_area *save_area)
{
/* we don't care if we err, as there's nothing we can do about it */
xosspriteop_switch_output_to_sprite(osspriteop_PTR,
(osspriteop_area *)save_area->context1,
(osspriteop_id)save_area->context2,
(osspriteop_save_area *)save_area->context3,
0, 0, 0, 0);
free(save_area->save_area);
free(save_area);
}
/**
* Convert a bitmap to 8bpp.
*
* \param bitmap the bitmap to convert
* \return a sprite area containing an 8bpp sprite
*/
osspriteop_area *riscos_bitmap_convert_8bpp(struct bitmap *bitmap)
{
struct thumbnail_save_area *save_area;
osspriteop_area *sprite_area = NULL;
osspriteop_header *sprite_header = NULL;
sprite_area = thumbnail_create_8bpp(bitmap);
if (!sprite_area)
return NULL;
sprite_header = (osspriteop_header *)(sprite_area + 1);
/* switch output and redraw */
save_area = thumbnail_switch_output(sprite_area, sprite_header);
if (save_area == NULL) {
if (thumbnail_32bpp_available != 1)
free(sprite_area);
return false;
}
_swix(Tinct_Plot, _IN(2) | _IN(3) | _IN(4) | _IN(7),
(osspriteop_header *)(bitmap->sprite_area + 1),
0, 0,
tinct_ERROR_DIFFUSE);
thumbnail_restore_output(save_area);
if (sprite_header->image != sprite_header->mask) {
/* build the sprite mask from the alpha channel */
void *buf = riscos_bitmap_get_buffer(bitmap);
unsigned *dp = (unsigned *) buf;
if (!dp)
return sprite_area;
int w = bitmap_get_width(bitmap);
int h = bitmap_get_height(bitmap);
int dp_offset = bitmap_get_rowstride(bitmap) / 4 - w;
int mp_offset = ((sprite_header->width + 1) * 4) - w;
byte *mp = (byte*)sprite_header + sprite_header->mask;
bool alpha = ((unsigned)sprite_header->mode & 0x80000000U) != 0;
while (h-- > 0) {
int x = 0;
for(x = 0; x < w; x++) {
unsigned d = *dp++;
if (alpha)
*mp++ = (d >> 24) ^ 0xff;
else
*mp++ = (d < 0xff000000U) ? 0 : 0xff;
}
dp += dp_offset;
mp += mp_offset;
}
}
return sprite_area;
}
/**
* Check to see whether 32bpp sprites are available.
*
* Rather than using Wimp_ReadSysInfo we test if 32bpp sprites are available
* in case the user has a 3rd party patch to enable them.
*/
static void thumbnail_test(void)
{
unsigned int area_size;
osspriteop_area *sprite_area;
/* try to create a 1x1 32bpp sprite */
area_size = sizeof(osspriteop_area) +
sizeof(osspriteop_header) + sizeof(int);
if ((sprite_area = (osspriteop_area *)malloc(area_size)) == NULL) {
LOG(("Insufficient memory to perform sprite test."));
return;
}
sprite_area->size = area_size + 1;
sprite_area->sprite_count = 0;
sprite_area->first = 16;
sprite_area->used = 16;
if (xosspriteop_create_sprite(osspriteop_NAME, sprite_area,
"test", false, 1, 1, (os_mode)tinct_SPRITE_MODE))
thumbnail_32bpp_available = 0;
else
thumbnail_32bpp_available = 1;
free(sprite_area);
}
/* exported interface documented in riscos/bitmap.h */
nserror riscos_bitmap_render(struct bitmap *bitmap,
struct hlcache_handle *content)
{
struct thumbnail_save_area *save_area;
osspriteop_area *sprite_area = NULL;
osspriteop_header *sprite_header = NULL;
struct redraw_context ctx = {
.interactive = false,
.background_images = true,
.plot = &ro_plotters
};
assert(content);
assert(bitmap);
LOG(("content %p in bitmap %p", content, bitmap));
/* check if we have access to 32bpp sprites natively */
if (thumbnail_32bpp_available == -1) {
thumbnail_test();
}
/* if we don't support 32bpp sprites then we redirect to an 8bpp
* image and then convert back.
*/
if (thumbnail_32bpp_available != 1) {
sprite_area = thumbnail_create_8bpp(bitmap);
if (!sprite_area)
return false;
sprite_header = (osspriteop_header *)(sprite_area + 1);
} else {
const uint8_t *pixbufp = riscos_bitmap_get_buffer(bitmap);
if (!pixbufp || !bitmap->sprite_area)
return false;
sprite_area = bitmap->sprite_area;
sprite_header = (osspriteop_header *)(sprite_area + 1);
}
/* set up the plotters */
ro_plot_origin_x = 0;
ro_plot_origin_y = bitmap->height * 2;
/* switch output and redraw */
save_area = thumbnail_switch_output(sprite_area, sprite_header);
if (!save_area) {
if (thumbnail_32bpp_available != 1)
free(sprite_area);
return false;
}
rufl_invalidate_cache();
colourtrans_set_gcol(os_COLOUR_WHITE, colourtrans_SET_BG_GCOL,
os_ACTION_OVERWRITE, 0);
/* render the content */
content_scaled_redraw(content, bitmap->width, bitmap->height, &ctx);
thumbnail_restore_output(save_area);
rufl_invalidate_cache();
/* if we changed to 8bpp then go back to 32bpp */
if (thumbnail_32bpp_available != 1) {
const uint8_t *pixbufp = riscos_bitmap_get_buffer(bitmap);
_kernel_oserror *error;
if (!pixbufp || !bitmap->sprite_area) {
free(sprite_area);
return false;
}
error = _swix(Tinct_ConvertSprite, _INR(2,3),
sprite_header,
(osspriteop_header *)(bitmap->sprite_area + 1));
free(sprite_area);
if (error)
return false;
}
bitmap_modified(bitmap);
return NSERROR_OK;
}
static struct gui_bitmap_table bitmap_table = {
.create = riscos_bitmap_create,
.destroy = riscos_bitmap_destroy,
@ -536,12 +865,13 @@ static struct gui_bitmap_table bitmap_table = {
.get_opaque = riscos_bitmap_get_opaque,
.test_opaque = bitmap_test_opaque,
.get_buffer = riscos_bitmap_get_buffer,
.get_rowstride = riscos_bitmap_get_rowstride,
.get_width = riscos_bitmap_get_width,
.get_height = riscos_bitmap_get_height,
.get_rowstride = bitmap_get_rowstride,
.get_width = bitmap_get_width,
.get_height = bitmap_get_height,
.get_bpp = bitmap_get_bpp,
.save = riscos_bitmap_save,
.modified = riscos_bitmap_modified,
.modified = bitmap_modified,
.render = riscos_bitmap_render,
};
struct gui_bitmap_table *riscos_bitmap_table = &bitmap_table;

View File

@ -21,6 +21,8 @@
struct osspriteop_area;
struct osspriteop_header;
struct hlcache_handle;
struct bitmap;
/** bitmap operations table */
struct gui_bitmap_table *riscos_bitmap_table;
@ -40,6 +42,22 @@ struct bitmap {
struct osspriteop_area *sprite_area; /**< Uncompressed data, or NULL */
};
/**
* Convert bitmap to 8bpp sprite.
*
* \param bitmap the bitmap to convert.
* \return The converted sprite.
*/
struct osspriteop_area *riscos_bitmap_convert_8bpp(struct bitmap *bitmap);
/**
* Render content into bitmap.
*
* \param bitmap the bitmap to draw to
* \param content content structure to render
* \return true on success and bitmap updated else false
*/
nserror riscos_bitmap_render(struct bitmap *bitmap, struct hlcache_handle *content);
/**
* Overlay a sprite onto the given bitmap
@ -49,7 +67,6 @@ struct bitmap {
*/
void riscos_bitmap_overlay_sprite(struct bitmap *bitmap, const struct osspriteop_header *s);
/**
* Create a bitmap.
*
@ -60,7 +77,6 @@ void riscos_bitmap_overlay_sprite(struct bitmap *bitmap, const struct osspriteop
*/
void *riscos_bitmap_create(int width, int height, unsigned int state);
/**
* Free a bitmap.
*
@ -80,37 +96,6 @@ void riscos_bitmap_destroy(void *vbitmap);
*/
unsigned char *riscos_bitmap_get_buffer(void *vbitmap);
/**
* The bitmap image has changed, so flush any persistent cache.
*
* \param vbitmap a bitmap, as returned by bitmap_create()
*/
void riscos_bitmap_modified(void *vbitmap);
/**
* Get the width of a bitmap.
*
* \param vbitmap A bitmap, as returned by bitmap_create()
* \return The bitmaps width in pixels.
*/
int riscos_bitmap_get_width(void *vbitmap);
/**
* Get the height of a bitmap.
*
* \param vbitmap A bitmap, as returned by bitmap_create()
* \return The bitmaps height in pixels.
*/
int riscos_bitmap_get_height(void *vbitmap);
/**
* Find the width of a pixel row in bytes.
*
* \param vbitmap A bitmap, as returned by riscos_bitmap_create()
* \return width of a pixel row in the bitmap
*/
size_t riscos_bitmap_get_rowstride(void *vbitmap);
/**
* Gets whether a bitmap should be plotted opaque
*

View File

@ -49,7 +49,6 @@
#include "desktop/version.h"
#include "desktop/save_complete.h"
#include "desktop/save_text.h"
#include "desktop/thumbnail.h"
#include "desktop/gui_window.h"
#include "image/bitmap.h"
#include "render/form.h"
@ -66,7 +65,6 @@
#include "riscos/save_draw.h"
#include "riscos/save_pdf.h"
#include "riscos/textselection.h"
#include "riscos/thumbnail.h"
#include "riscos/wimp.h"
#include "riscos/wimp_event.h"
#include "riscos/ucstables.h"
@ -1375,8 +1373,8 @@ bool ro_gui_save_create_thumbnail(hlcache_handle *h, const char *name)
LOG(("Thumbnail initialisation failed."));
return false;
}
thumbnail_create(h, bitmap);
area = thumbnail_convert_8bpp(bitmap);
riscos_bitmap_render(bitmap, h);
area = riscos_bitmap_convert_8bpp(bitmap);
riscos_bitmap_destroy(bitmap);
if (!area) {
LOG(("Thumbnail conversion failed."));

View File

@ -1,363 +0,0 @@
/*
* Copyright 2004 James Bursa <bursa@users.sourceforge.net>
* Copyright 2005 Richard Wilson <info@tinct.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file
* Page thumbnail creation (implementation).
*
* Thumbnails are created by redirecting output to a sprite and rendering the
* page at a small scale.
*/
#include <assert.h>
#include <string.h>
#include <swis.h>
#include "rufl.h"
#include "oslib/colourtrans.h"
#include "oslib/osfile.h"
#include "oslib/osspriteop.h"
#include "utils/nsoption.h"
#include "utils/log.h"
#include "content/content.h"
#include "content/hlcache.h"
#include "desktop/plotters.h"
#include "desktop/thumbnail.h"
#include "image/bitmap.h"
#include "riscos/bitmap.h"
#include "riscos/gui.h"
#include "riscos/oslib_pre7.h"
#include "riscos/thumbnail.h"
#include "riscos/tinct.h"
/* Whether we can use 32bpp sprites
*/
static int thumbnail_32bpp_available = -1;
/* Sprite output context saving
*/
struct thumbnail_save_area {
osspriteop_save_area *save_area;
int context1;
int context2;
int context3;
};
/* Internal prototypes
*/
static osspriteop_area *thumbnail_create_8bpp(struct bitmap *bitmap);
static void thumbnail_test(void);
static struct thumbnail_save_area* thumbnail_switch_output(
osspriteop_area *sprite_area,
osspriteop_header *sprite_header);
static void thumbnail_restore_output(struct thumbnail_save_area *save_area);
/**
* Create a thumbnail of a page.
*
* \param content content structure to thumbnail
* \param bitmap the bitmap to draw to
* \return true on success and bitmap updated else false
*/
bool thumbnail_create(hlcache_handle *content, struct bitmap *bitmap)
{
struct thumbnail_save_area *save_area;
osspriteop_area *sprite_area = NULL;
osspriteop_header *sprite_header = NULL;
struct redraw_context ctx = {
.interactive = false,
.background_images = true,
.plot = &ro_plotters
};
assert(content);
assert(bitmap);
LOG(("content %p in bitmap %p", content, bitmap));
/* check if we have access to 32bpp sprites natively */
if (thumbnail_32bpp_available == -1) {
thumbnail_test();
}
/* if we don't support 32bpp sprites then we redirect to an 8bpp
* image and then convert back.
*/
if (thumbnail_32bpp_available != 1) {
sprite_area = thumbnail_create_8bpp(bitmap);
if (!sprite_area)
return false;
sprite_header = (osspriteop_header *)(sprite_area + 1);
} else {
const uint8_t *pixbufp = riscos_bitmap_get_buffer(bitmap);
if (!pixbufp || !bitmap->sprite_area)
return false;
sprite_area = bitmap->sprite_area;
sprite_header = (osspriteop_header *)(sprite_area + 1);
}
/* set up the plotters */
ro_plot_origin_x = 0;
ro_plot_origin_y = bitmap->height * 2;
/* switch output and redraw */
save_area = thumbnail_switch_output(sprite_area, sprite_header);
if (!save_area) {
if (thumbnail_32bpp_available != 1)
free(sprite_area);
return false;
}
rufl_invalidate_cache();
colourtrans_set_gcol(os_COLOUR_WHITE, colourtrans_SET_BG_GCOL,
os_ACTION_OVERWRITE, 0);
thumbnail_redraw(content, bitmap->width, bitmap->height, &ctx);
thumbnail_restore_output(save_area);
rufl_invalidate_cache();
/* if we changed to 8bpp then go back to 32bpp */
if (thumbnail_32bpp_available != 1) {
const uint8_t *pixbufp = riscos_bitmap_get_buffer(bitmap);
_kernel_oserror *error;
if (!pixbufp || !bitmap->sprite_area) {
free(sprite_area);
return false;
}
error = _swix(Tinct_ConvertSprite, _INR(2,3),
sprite_header,
(osspriteop_header *)(bitmap->sprite_area + 1));
free(sprite_area);
if (error)
return false;
}
riscos_bitmap_modified(bitmap);
return true;
}
/**
* Convert a bitmap to 8bpp.
*
* \param bitmap the bitmap to convert
* \return a sprite area containing an 8bpp sprite
*/
osspriteop_area *thumbnail_convert_8bpp(struct bitmap *bitmap)
{
struct thumbnail_save_area *save_area;
osspriteop_area *sprite_area = NULL;
osspriteop_header *sprite_header = NULL;
sprite_area = thumbnail_create_8bpp(bitmap);
if (!sprite_area)
return NULL;
sprite_header = (osspriteop_header *)(sprite_area + 1);
/* switch output and redraw */
save_area = thumbnail_switch_output(sprite_area, sprite_header);
if (save_area == NULL) {
if (thumbnail_32bpp_available != 1)
free(sprite_area);
return false;
}
_swix(Tinct_Plot, _IN(2) | _IN(3) | _IN(4) | _IN(7),
(osspriteop_header *)(bitmap->sprite_area + 1),
0, 0,
tinct_ERROR_DIFFUSE);
thumbnail_restore_output(save_area);
if (sprite_header->image != sprite_header->mask) {
/* build the sprite mask from the alpha channel */
void *buf = riscos_bitmap_get_buffer(bitmap);
unsigned *dp = (unsigned *) buf;
if (!dp)
return sprite_area;
int w = riscos_bitmap_get_width(bitmap);
int h = riscos_bitmap_get_height(bitmap);
int dp_offset = riscos_bitmap_get_rowstride(bitmap) / 4 - w;
int mp_offset = ((sprite_header->width + 1) * 4) - w;
byte *mp = (byte*)sprite_header + sprite_header->mask;
bool alpha = ((unsigned)sprite_header->mode & 0x80000000U) != 0;
while (h-- > 0) {
int x = 0;
for(x = 0; x < w; x++) {
unsigned d = *dp++;
if (alpha)
*mp++ = (d >> 24) ^ 0xff;
else
*mp++ = (d < 0xff000000U) ? 0 : 0xff;
}
dp += dp_offset;
mp += mp_offset;
}
}
return sprite_area;
}
/**
* Creates an 8bpp canvas.
*
* \param bitmap the bitmap to clone the size of
* \return a sprite area containing an 8bpp sprite
*/
osspriteop_area *thumbnail_create_8bpp(struct bitmap *bitmap)
{
unsigned image_size = ((bitmap->width + 3) & ~3) * bitmap->height;
bool opaque = riscos_bitmap_get_opaque(bitmap);
osspriteop_header *sprite_header = NULL;
osspriteop_area *sprite_area = NULL;
unsigned area_size;
/* clone the sprite */
area_size = sizeof(osspriteop_area) +
sizeof(osspriteop_header) +
image_size +
2048;
if (!opaque) area_size += image_size;
sprite_area = (osspriteop_area *)malloc(area_size);
if (!sprite_area) {
LOG(("no memory for malloc()"));
return NULL;
}
sprite_area->size = area_size;
sprite_area->sprite_count = 1;
sprite_area->first = 16;
sprite_area->used = area_size;
sprite_header = (osspriteop_header *)(sprite_area + 1);
sprite_header->size = area_size - sizeof(osspriteop_area);
memset(sprite_header->name, 0x00, 12);
strcpy(sprite_header->name, "bitmap");
sprite_header->left_bit = 0;
sprite_header->height = bitmap->height - 1;
sprite_header->mode = os_MODE8BPP90X90;
sprite_header->right_bit = ((bitmap->width << 3) - 1) & 31;
sprite_header->width = ((bitmap->width + 3) >> 2) - 1;
sprite_header->image = sizeof(osspriteop_header) + 2048;
sprite_header->mask = sizeof(osspriteop_header) + 2048;
if (!opaque) sprite_header->mask += image_size;
/* create the palette. we don't read the necessary size like
* we really should as we know it's going to have 256 entries
* of 8 bytes = 2048. */
xcolourtrans_read_palette((osspriteop_area *)os_MODE8BPP90X90,
(osspriteop_id)0,
(os_palette *)(sprite_header + 1), 2048,
(colourtrans_palette_flags)(1 << 1), 0);
return sprite_area;
}
/**
* Check to see whether 32bpp sprites are available.
*
* Rather than using Wimp_ReadSysInfo we test if 32bpp sprites are available
* in case the user has a 3rd party patch to enable them.
*/
static void thumbnail_test(void)
{
unsigned int area_size;
osspriteop_area *sprite_area;
/* try to create a 1x1 32bpp sprite */
area_size = sizeof(osspriteop_area) +
sizeof(osspriteop_header) + sizeof(int);
if ((sprite_area = (osspriteop_area *)malloc(area_size)) == NULL) {
LOG(("Insufficient memory to perform sprite test."));
return;
}
sprite_area->size = area_size + 1;
sprite_area->sprite_count = 0;
sprite_area->first = 16;
sprite_area->used = 16;
if (xosspriteop_create_sprite(osspriteop_NAME, sprite_area,
"test", false, 1, 1, (os_mode)tinct_SPRITE_MODE))
thumbnail_32bpp_available = 0;
else
thumbnail_32bpp_available = 1;
free(sprite_area);
}
/**
* Switches output to the specified sprite and returns the previous context.
*/
static struct thumbnail_save_area* thumbnail_switch_output(
osspriteop_area *sprite_area,
osspriteop_header *sprite_header)
{
struct thumbnail_save_area *save_area;
int size;
/* create a save area */
save_area = calloc(sizeof(struct thumbnail_save_area), 1);
if (save_area == NULL) return NULL;
/* allocate OS_SpriteOp save area */
if (xosspriteop_read_save_area_size(osspriteop_PTR, sprite_area,
(osspriteop_id)sprite_header, &size)) {
free(save_area);
return NULL;
}
/* create the save area */
save_area->save_area = malloc((unsigned)size);
if (save_area->save_area == NULL) {
free(save_area);
return NULL;
}
save_area->save_area->a[0] = 0;
/* switch output to sprite */
if (xosspriteop_switch_output_to_sprite(osspriteop_PTR, sprite_area,
(osspriteop_id)sprite_header, save_area->save_area,
0, &save_area->context1, &save_area->context2,
&save_area->context3)) {
free(save_area->save_area);
free(save_area);
return NULL;
}
return save_area;
}
/**
* Restores output to the specified context, and destroys it.
*/
static void thumbnail_restore_output(struct thumbnail_save_area *save_area)
{
/* we don't care if we err, as there's nothing we can do about it */
xosspriteop_switch_output_to_sprite(osspriteop_PTR,
(osspriteop_area *)save_area->context1,
(osspriteop_id)save_area->context2,
(osspriteop_save_area *)save_area->context3,
0, 0, 0, 0);
free(save_area->save_area);
free(save_area);
}

View File

@ -1,32 +0,0 @@
/*
* Copyright 2004 James Bursa <bursa@users.sourceforge.net>
* Copyright 2005 Richard Wilson <info@tinct.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* \file
* Page thumbnail creation interface.
*/
#ifndef _NETSURF_RISCOS_THUMBNAIL_H_
#define _NETSURF_RISCOS_THUMBNAIL_H_
struct osspriteop_area;
struct osspriteop_area *thumbnail_convert_8bpp(struct bitmap *bitmap);
#endif

View File

@ -60,7 +60,6 @@
#include "desktop/mouse.h"
#include "desktop/plotters.h"
#include "desktop/textinput.h"
#include "desktop/thumbnail.h"
#include "desktop/tree.h"
#include "desktop/gui_window.h"
#include "image/bitmap.h"
@ -82,7 +81,6 @@
#include "riscos/content-handlers/sprite.h"
#include "riscos/textselection.h"
#include "riscos/toolbar.h"
#include "riscos/thumbnail.h"
#include "riscos/url_complete.h"
#include "riscos/url_suggest.h"
#include "riscos/wimp.h"
@ -3418,11 +3416,11 @@ void ro_gui_window_iconise(struct gui_window *g,
LOG(("Thumbnail initialisation failed."));
return;
}
thumbnail_create(h, bitmap);
riscos_bitmap_render(bitmap, h);
if (overlay) {
riscos_bitmap_overlay_sprite(bitmap, overlay);
}
area = thumbnail_convert_8bpp(bitmap);
area = riscos_bitmap_convert_8bpp(bitmap);
riscos_bitmap_destroy(bitmap);
if (!area) {
LOG(("Thumbnail conversion failed."));

View File

@ -59,7 +59,7 @@ S_RESOURCES := windows_resource.o
# S_WINDOWS are sources purely for the windows build
S_WINDOWS := main.c window.c gui.c drawable.c misc.c plot.c findfile.c \
font.c bitmap.c about.c prefs.c download.c filetype.c \
localhistory.c schedule.c thumbnail.c windbg.c pointers.c
localhistory.c schedule.c windbg.c pointers.c
S_WINDOWS := $(addprefix windows/,$(S_WINDOWS))
# This is the final source build list

View File

@ -17,6 +17,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* \file
* win32 implementation of the bitmap operations.
*/
#include "utils/config.h"
#include <inttypes.h>
@ -26,7 +31,9 @@
#include "utils/log.h"
#include "image/bitmap.h"
#include "content/content.h"
#include "windows/plot.h"
#include "windows/bitmap.h"
/**
@ -50,10 +57,10 @@ void *win32_bitmap_create(int width, int height, unsigned int state)
if (pbmi == NULL) {
return NULL;
}
pbmi->bV5Size = sizeof(BITMAPV5HEADER);
pbmi->bV5Width = width;
pbmi->bV5Height = -height;
pbmi->bV5Planes = 1;
pbmi->bV5Size = sizeof(BITMAPV5HEADER);
pbmi->bV5Width = width;
pbmi->bV5Height = -height;
pbmi->bV5Planes = 1;
pbmi->bV5BitCount = 32;
pbmi->bV5Compression = BI_BITFIELDS;
@ -110,7 +117,7 @@ static unsigned char *bitmap_get_buffer(void *bitmap)
LOG(("NULL bitmap!"));
return NULL;
}
return bm->pixdata;
}
@ -157,8 +164,8 @@ void win32_bitmap_destroy(void *bitmap)
/**
* Save a bitmap in the platform's native format.
*
* \param bitmap a bitmap, as returned by bitmap_create()
* \param path pathname for file
* \param bitmap a bitmap, as returned by bitmap_create()
* \param path pathname for file
* \param flags flags controlling how the bitmap is saved.
* \return true on success, false on error and error reported
*/
@ -183,7 +190,7 @@ static void bitmap_modified(void *bitmap) {
* \param opaque whether the bitmap should be plotted opaque
*/
static void bitmap_set_opaque(void *bitmap, bool opaque)
{
{
struct bitmap *bm = bitmap;
if (bitmap == NULL) {
@ -217,8 +224,8 @@ static bool bitmap_test_opaque(void *bitmap)
while (tst-- > 0) {
if (bm->pixdata[(tst << 2) + 3] != 0xff) {
LOG(("bitmap %p has transparency",bm));
return false;
}
return false;
}
}
LOG(("bitmap %p is opaque", bm));
return true;
@ -293,24 +300,24 @@ struct bitmap *bitmap_scale(struct bitmap *prescale, int width, int height)
vv = (int)((i * prescale->height) / height) * prescale->width;
for (ii = 0; ii < width; ii++) {
retpixdata[v + ii] = inpixdata[vv + (int)
((ii * prescale->width) / width)];
((ii * prescale->width) / width)];
}
}
return ret;
}
struct bitmap *bitmap_pretile(struct bitmap *untiled, int width, int height,
bitmap_flags_t flags)
bitmap_flags_t flags)
{
struct bitmap *ret = malloc(sizeof(struct bitmap));
if (ret == NULL)
return NULL;
int i, hrepeat, vrepeat, repeat;
vrepeat = ((flags & BITMAPF_REPEAT_Y) != 0) ?
((height + untiled->height - 1) / untiled->height) : 1;
hrepeat = ((flags & BITMAPF_REPEAT_X) != 0) ?
((width + untiled->width - 1) / untiled->width) : 1;
vrepeat = ((flags & BITMAPF_REPEAT_Y) != 0) ?
((height + untiled->height - 1) / untiled->height) : 1;
hrepeat = ((flags & BITMAPF_REPEAT_X) != 0) ?
((width + untiled->width - 1) / untiled->width) : 1;
width = untiled->width * hrepeat;
height = untiled->height * vrepeat;
uint8_t *indata = untiled->pixdata;
@ -330,7 +337,7 @@ struct bitmap *bitmap_pretile(struct bitmap *untiled, int width, int height,
}
indata += stride;
}
/* vertical tiling */
stride = untiled->height * width * 4;
newdata = ret->pixdata + stride;
@ -338,13 +345,69 @@ struct bitmap *bitmap_pretile(struct bitmap *untiled, int width, int height,
for (repeat = 1; repeat < vrepeat; repeat++) {
memcpy(newdata, indata, stride);
newdata += stride;
newdata += stride;
}
ret->width = width;
ret->height = height;
return ret;
}
static nserror bitmap_render(struct bitmap *bitmap, struct hlcache_handle *content)
{
int width;
int height;
HDC hdc, bufferdc, minidc;
struct bitmap *fsbitmap;
struct redraw_context ctx = {
.interactive = false,
.background_images = true,
.plot = &win_plotters
};
width = min(content_get_width(content), 1024);
height = ((width * bitmap->height) + (bitmap->width / 2)) /
bitmap->width;
LOG(("bitmap %p for content %p width %d, height %d",
bitmap, content, width, height));
/* create two memory device contexts to put the bitmaps in */
bufferdc = CreateCompatibleDC(NULL);
if ((bufferdc == NULL)) {
return NSERROR_NOMEM;
}
minidc = CreateCompatibleDC(NULL);
if ((minidc == NULL)) {
DeleteDC(bufferdc);
return NSERROR_NOMEM;
}
/* create a full size bitmap and plot into it */
fsbitmap = win32_bitmap_create(width, height, BITMAP_NEW | BITMAP_CLEAR_MEMORY | BITMAP_OPAQUE);
SelectObject(bufferdc, fsbitmap->windib);
hdc = plot_hdc;
plot_hdc = bufferdc;
/* render the content */
content_scaled_redraw(content, width, height, &ctx);
plot_hdc = hdc;
/* scale bitmap bufferbm into minibm */
SelectObject(minidc, bitmap->windib);
bitmap->opaque = true;
StretchBlt(minidc, 0, 0, bitmap->width, bitmap->height, bufferdc, 0, 0, width, height, SRCCOPY);
DeleteDC(bufferdc);
DeleteDC(minidc);
win32_bitmap_destroy(fsbitmap);
return NSERROR_OK;
}
static struct gui_bitmap_table bitmap_table = {
.create = win32_bitmap_create,
.destroy = win32_bitmap_destroy,
@ -358,6 +421,7 @@ static struct gui_bitmap_table bitmap_table = {
.get_bpp = bitmap_get_bpp,
.save = bitmap_save,
.modified = bitmap_modified,
.render = bitmap_render,
};
struct gui_bitmap_table *win32_bitmap_table = &bitmap_table;

View File

@ -1,89 +0,0 @@
/*
* Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.net>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
* NetSurf is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* NetSurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "utils/config.h"
#include <windows.h>
#include "utils/log.h"
#include "desktop/browser.h"
#include "desktop/thumbnail.h"
#include "image/bitmap.h"
#include "windows/bitmap.h"
#include "windows/gui.h"
#include "windows/plot.h"
#include "content/hlcache.h"
bool
thumbnail_create(hlcache_handle *content,
struct bitmap *bitmap)
{
int width;
int height;
HDC hdc, bufferdc, minidc;
struct bitmap *fsbitmap;
struct redraw_context ctx = {
.interactive = false,
.background_images = true,
.plot = &win_plotters
};
width = min(content_get_width(content), 1024);
height = ((width * bitmap->height) + (bitmap->width / 2)) /
bitmap->width;
LOG(("bitmap %p for content %p width %d, height %d",
bitmap, content, width, height));
/* create two memory device contexts to put the bitmaps in */
bufferdc = CreateCompatibleDC(NULL);
if ((bufferdc == NULL)) {
return false;
}
minidc = CreateCompatibleDC(NULL);
if ((minidc == NULL)) {
DeleteDC(bufferdc);
return false;
}
/* create a full size bitmap and plot into it */
fsbitmap = win32_bitmap_create(width, height, BITMAP_NEW | BITMAP_CLEAR_MEMORY | BITMAP_OPAQUE);
SelectObject(bufferdc, fsbitmap->windib);
hdc = plot_hdc;
plot_hdc = bufferdc;
thumbnail_redraw(content, width, height, &ctx);
plot_hdc = hdc;
/* scale bitmap bufferbm into minibm */
SelectObject(minidc, bitmap->windib);
bitmap->opaque = true;
StretchBlt(minidc, 0, 0, bitmap->width, bitmap->height, bufferdc, 0, 0, width, height, SRCCOPY);
DeleteDC(bufferdc);
DeleteDC(minidc);
win32_bitmap_destroy(fsbitmap);
return true;
}