mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-12-14 16:27:22 +03:00
Merge branch 'thumbnail-rework'
This commit is contained in:
commit
9729febf72
@ -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 \
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -100,7 +100,6 @@ S_ATARI := \
|
||||
statusbar.c \
|
||||
settings.c \
|
||||
toolbar.c \
|
||||
thumbnail.c \
|
||||
treeview.c \
|
||||
plot/plot.c \
|
||||
plot/fontplot.c \
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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;
|
||||
}
|
@ -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
|
||||
|
463
beos/bitmap.cpp
463
beos/bitmap.cpp
@ -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;
|
||||
|
@ -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;
|
||||
}
|
@ -87,7 +87,6 @@ S_COCOA := \
|
||||
plotter.m \
|
||||
schedule.m \
|
||||
selection.m \
|
||||
thumbnail.m \
|
||||
utils.m \
|
||||
ArrowBox.m \
|
||||
ArrowWindow.m \
|
||||
|
119
cocoa/bitmap.m
119
cocoa/bitmap.m
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
@ -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
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
@ -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 \
|
||||
|
115
gtk/bitmap.c
115
gtk/bitmap.c
@ -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;
|
||||
|
122
gtk/thumbnail.c
122
gtk/thumbnail.c
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
@ -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 \
|
||||
|
364
riscos/bitmap.c
364
riscos/bitmap.c
@ -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;
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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."));
|
||||
|
@ -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);
|
||||
}
|
@ -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
|
@ -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."));
|
||||
|
@ -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
|
||||
|
102
windows/bitmap.c
102
windows/bitmap.c
@ -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;
|
||||
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user