NetSurf
image.c
Go to the documentation of this file.
1/*
2 * Copyright 2004 John M Bell <jmb202@ecs.soton.ac.uk>
3 *
4 * This file is part of NetSurf, http://www.netsurf-browser.org/
5 *
6 * NetSurf is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * NetSurf is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <stdbool.h>
20#include <swis.h>
21#include <stdlib.h>
22#include <oslib/colourtrans.h>
23#include <oslib/osspriteop.h>
24
25#include "utils/nsoption.h"
26#include "utils/log.h"
27
28#include "riscos/image.h"
29#include "riscos/gui.h"
30#include "riscos/wimp.h"
31#include "riscos/tinct.h"
32
33/**
34 * Plot an image at the given coordinates using tinct
35 *
36 * \param header The sprite header
37 * \param x Left edge of sprite
38 * \param y Top edge of sprite
39 * \param req_width The requested width of the sprite
40 * \param req_height The requested height of the sprite
41 * \param width The actual width of the sprite
42 * \param height The actual height of the sprite
43 * \param background_colour The background colour to blend to
44 * \param repeatx Repeat the image in the x direction
45 * \param repeaty Repeat the image in the y direction
46 * \param alpha Use the alpha channel
47 * \param tinct_options The base option set to use
48 * \return true on success, false otherwise
49 */
50static bool image_redraw_tinct(osspriteop_id header, int x, int y,
51 int req_width, int req_height, int width, int height,
52 colour background_colour, bool repeatx, bool repeaty,
53 bool alpha, unsigned int tinct_options)
54{
55 _kernel_oserror *error;
56
57 /* Set up our flagword
58 */
59 tinct_options |= background_colour << tinct_BACKGROUND_SHIFT;
60 if (print_active)
62 if (repeatx)
64 if (repeaty)
66
67 if (alpha) {
68 error = _swix(Tinct_PlotScaledAlpha, _INR(2,7),
69 header, x, y,
70 req_width, req_height, tinct_options);
71 } else {
72 error = _swix(Tinct_PlotScaled, _INR(2,7),
73 header, x, y,
74 req_width, req_height, tinct_options);
75 }
76
77 if (error) {
78 NSLOG(netsurf, INFO, "xtinct_plotscaled%s: 0x%x: %s",
79 (alpha ? "alpha" : ""), error->errnum, error->errmess);
80 return false;
81 }
82
83 return true;
84}
85
86/**
87 * Plot an image at the given coordinates using os_spriteop
88 *
89 * \param header The sprite header
90 * \param x Left edge of sprite
91 * \param y Top edge of sprite
92 * \param req_width The requested width of the sprite
93 * \param req_height The requested height of the sprite
94 * \param width The actual width of the sprite
95 * \param height The actual height of the sprite
96 * \param tile Whether to tile the sprite
97 * \return true on success, false otherwise
98 */
99static bool image_redraw_os(osspriteop_id header, int x, int y, int req_width,
100 int req_height, int width, int height, bool tile)
101{
102 int size;
103 os_factors f;
104 osspriteop_trans_tab *table;
105 os_error *error;
106
107 error = xcolourtrans_generate_table_for_sprite(
108 osspriteop_UNSPECIFIED, header,
109 os_CURRENT_MODE,
110 colourtrans_CURRENT_PALETTE,
111 0, colourtrans_GIVEN_SPRITE, 0, 0, &size);
112 if (error) {
113 NSLOG(netsurf, INFO,
114 "xcolourtrans_generate_table_for_sprite: 0x%x: %s",
115 error->errnum,
116 error->errmess);
117 return false;
118 }
119
120 table = calloc(size, sizeof(char));
121 if (!table) {
122 NSLOG(netsurf, INFO, "malloc failed");
123 ro_warn_user("NoMemory", 0);
124 return false;
125 }
126
127 error = xcolourtrans_generate_table_for_sprite(
128 osspriteop_UNSPECIFIED, header,
129 os_CURRENT_MODE,
130 colourtrans_CURRENT_PALETTE,
131 table, colourtrans_GIVEN_SPRITE, 0, 0, 0);
132 if (error) {
133 NSLOG(netsurf, INFO,
134 "xcolourtrans_generate_table_for_sprite: 0x%x: %s",
135 error->errnum,
136 error->errmess);
137 free(table);
138 return false;
139 }
140
141 f.xmul = req_width;
142 f.ymul = req_height;
143 f.xdiv = width;
144 f.ydiv = height;
145
146 if (tile) {
147 error = xosspriteop_plot_tiled_sprite(osspriteop_PTR,
148 osspriteop_UNSPECIFIED, header, x, y,
149 osspriteop_USE_MASK, &f, table);
150 } else {
151 error = xosspriteop_put_sprite_scaled(osspriteop_PTR,
152 osspriteop_UNSPECIFIED, header, x, y,
153 osspriteop_USE_MASK, &f, table);
154 }
155 if (error) {
156 NSLOG(netsurf, INFO,
157 "xosspriteop_put_sprite_scaled: 0x%x: %s",
158 error->errnum,
159 error->errmess);
160 free(table);
161 return false;
162 }
163
164 free(table);
165
166 return true;
167}
168
169/**
170 * Override a sprite's mode.
171 *
172 * Only replaces mode if existing mode matches \ref old.
173 *
174 * \param[in] area The sprite area containing the sprite.
175 * \param[in] type Requested plot mode.
176 * \param[in] old Existing sprite mode to check for.
177 * \param[in] new Sprite mode to set if existing mode is expected.
178 */
180 osspriteop_area *area,
182 os_mode old,
183 os_mode new)
184{
185 osspriteop_header *sprite = (osspriteop_header *)(area + 1);
186
187 if (sprite->mode == old && type == IMAGE_PLOT_TINCT_ALPHA) {
188 sprite->mode = new;
189 }
190}
191
192/**
193 * Plot an image at the given coordinates using the method specified
194 *
195 * \param area The sprite area containing the sprite
196 * \param x Left edge of sprite
197 * \param y Top edge of sprite
198 * \param req_width The requested width of the sprite
199 * \param req_height The requested height of the sprite
200 * \param width The actual width of the sprite
201 * \param height The actual height of the sprite
202 * \param background_colour The background colour to blend to
203 * \param repeatx Repeat the image in the x direction
204 * \param repeaty Repeat the image in the y direction
205 * \param background Use background image settings (otherwise foreground)
206 * \param type The plot method to use
207 * \return true on success, false otherwise
208 */
209bool image_redraw(osspriteop_area *area, int x, int y, int req_width,
210 int req_height, int width, int height,
211 colour background_colour,
212 bool repeatx, bool repeaty, bool background, image_type type)
213{
214 image_type used_type = type;
215 unsigned int tinct_options;
216 bool tinct_avoid = false;
217 bool res = false;
218
219 /* failed decompression/loading can result in no image being present */
220 if (!area)
221 return false;
222
223 osspriteop_id header = (osspriteop_id)
224 ((char*) area + area->first);
225
226 req_width *= 2;
227 req_height *= 2;
228 width *= 2;
229 height *= 2;
230 y -= req_height;
231
232 tinct_options = background ? nsoption_int(plot_bg_quality) :
233 nsoption_int(plot_fg_quality);
234
236 /* Ideally Tinct would be updated to understand that modern OS
237 * versions can cope with alpha channels, and we could continue
238 * to pass to Tinct. The main drawback of fully avoiding Tinct
239 * is that we lose the optimisation for tiling tiny bitmaps.
240 */
242 used_type = IMAGE_PLOT_OS;
243 tinct_avoid = true;
244 }
245 }
246
247 if (tinct_avoid) {
248 int xeig;
249 int yeig;
250
251 if (ro_gui_wimp_read_eig_factors(os_CURRENT_MODE,
252 &xeig, &yeig)) {
253
254 req_width = (req_width / 2) * (4 >> xeig);
255 req_height = (req_height / 2) * (4 >> yeig);
256 }
257 }
258
259 switch (used_type) {
261 res = image_redraw_tinct(header, x, y,
262 req_width, req_height,
263 width, height,
264 background_colour,
265 repeatx, repeaty, true,
267 break;
268
270 res = image_redraw_tinct(header, x, y,
271 req_width, req_height,
272 width, height,
273 background_colour,
274 repeatx, repeaty, false,
276 break;
277
278 case IMAGE_PLOT_OS:
279 if (tinct_avoid) {
283 }
284 res = image_redraw_os(header, x, y, req_width,
285 req_height, width, height,
286 repeatx | repeaty);
287 if (tinct_avoid) {
291 }
292 break;
293
294 default:
295 break;
296 }
297
298 return res;
299}
unsigned int tinct_options[]
Definition: con_image.c:58
const char * type
Definition: filetype.cpp:44
static bool image_redraw_os(osspriteop_id header, int x, int y, int req_width, int req_height, int width, int height, bool tile)
Plot an image at the given coordinates using os_spriteop.
Definition: image.c:99
static bool image_redraw_tinct(osspriteop_id header, int x, int y, int req_width, int req_height, int width, int height, colour background_colour, bool repeatx, bool repeaty, bool alpha, unsigned int tinct_options)
Plot an image at the given coordinates using tinct.
Definition: image.c:50
bool image_redraw(osspriteop_area *area, int x, int y, int req_width, int req_height, int width, int height, colour background_colour, bool repeatx, bool repeaty, bool background, image_type type)
Plot an image at the given coordinates using the method specified.
Definition: image.c:209
static void image__override_sprite_mode(osspriteop_area *area, image_type type, os_mode old, os_mode new)
Override a sprite's mode.
Definition: image.c:179
image_type
Definition: image.h:28
@ IMAGE_PLOT_TINCT_OPAQUE
Definition: image.h:30
@ IMAGE_PLOT_OS
Definition: image.h:31
@ IMAGE_PLOT_TINCT_ALPHA
Definition: image.h:29
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
int width
Definition: gui.c:160
nserror ro_warn_user(const char *warning, const char *detail)
Display a warning for a serious problem (eg memory exhaustion).
Definition: gui.c:2077
bool os_alpha_sprite_supported
Definition: gui.c:98
int height
Definition: gui.c:161
bool print_active
Definition: print.c:81
Tinct SWI numbers and flags for version 0.11.
#define tinct_FILL_HORIZONTALLY
Definition: tinct.h:138
#define Tinct_PlotScaledAlpha
Plots a scaled alpha-blended sprite at the specified coordinates.
Definition: tinct.h:52
#define tinct_FILL_VERTICALLY
Definition: tinct.h:139
#define tinct_USE_OS_SPRITE_OP
Definition: tinct.h:141
#define tinct_SPRITE_MODE
Definition: tinct.h:156
#define Tinct_PlotScaled
Plots a scaled sprite at the specified coordinates with a constant 0xff value for the alpha channel,...
Definition: tinct.h:77
#define alpha_SPRITE_MODE
Definition: tinct.h:162
#define tinct_BACKGROUND_SHIFT
Definition: tinct.h:149
uint32_t colour
Colour type: XBGR.
Definition: types.h:35
Option reading and saving interface.
#define nsoption_int(OPTION)
Get the value of an integer option.
Definition: nsoption.h:313
bool ro_gui_wimp_read_eig_factors(os_mode mode, int *xeig, int *yeig)
Reads a modes EIG factors.
Definition: wimp.c:123
General RISC OS WIMP/OS library functions (interface).