aboutsummaryrefslogtreecommitdiffstats
path: root/libart_lgpl/art_render.c
diff options
context:
space:
mode:
Diffstat (limited to 'libart_lgpl/art_render.c')
-rw-r--r--libart_lgpl/art_render.c552
1 files changed, 0 insertions, 552 deletions
diff --git a/libart_lgpl/art_render.c b/libart_lgpl/art_render.c
index 65b344cc56..771f15fe44 100644
--- a/libart_lgpl/art_render.c
+++ b/libart_lgpl/art_render.c
@@ -39,115 +39,10 @@ struct _ArtRenderPriv {
ArtRenderCallback **callbacks;
};
-ArtRender *
-art_render_new (int x0, int y0, int x1, int y1,
- art_u8 *pixels, int rowstride,
- int n_chan, int depth, ArtAlphaType alpha_type,
- ArtAlphaGamma *alphagamma)
-{
- ArtRenderPriv *priv;
- ArtRender *result;
-
- priv = art_new (ArtRenderPriv, 1);
- result = &priv->super;
-
- if (n_chan > ART_MAX_CHAN)
- {
- art_warn ("art_render_new: n_chan = %d, exceeds %d max\n",
- n_chan, ART_MAX_CHAN);
- return NULL;
- }
- if (depth > ART_MAX_DEPTH)
- {
- art_warn ("art_render_new: depth = %d, exceeds %d max\n",
- depth, ART_MAX_DEPTH);
- return NULL;
- }
- if (x0 >= x1)
- {
- art_warn ("art_render_new: x0 >= x1 (x0 = %d, x1 = %d)\n", x0, x1);
- return NULL;
- }
- result->x0 = x0;
- result->y0 = y0;
- result->x1 = x1;
- result->y1 = y1;
- result->pixels = pixels;
- result->rowstride = rowstride;
- result->n_chan = n_chan;
- result->depth = depth;
- result->alpha_type = alpha_type;
-
- result->clear = ART_FALSE;
- result->opacity = 0x10000;
- result->compositing_mode = ART_COMPOSITE_NORMAL;
- result->alphagamma = alphagamma;
-
- result->alpha_buf = NULL;
- result->image_buf = NULL;
-
- result->run = NULL;
- result->span_x = NULL;
-
- result->need_span = ART_FALSE;
-
- priv->image_source = NULL;
-
- priv->n_mask_source = 0;
- priv->mask_source = NULL;
-
- return result;
-}
-
/* todo on clear routines: I haven't really figured out what to do
with clearing the alpha channel. It _should_ be possible to clear
to an arbitrary RGBA color. */
-/**
- * art_render_clear: Set clear color.
- * @clear_color: Color with which to clear dest.
- *
- * Sets clear color, equivalent to actually clearing the destination
- * buffer before rendering. This is the most general form.
- **/
-void
-art_render_clear (ArtRender *render, const ArtPixMaxDepth *clear_color)
-{
- int i;
- int n_ch = render->n_chan + (render->alpha_type != ART_ALPHA_NONE);
-
- render->clear = ART_TRUE;
- for (i = 0; i < n_ch; i++)
- render->clear_color[i] = clear_color[i];
-}
-
-/**
- * art_render_clear_rgb: Set clear color, given in RGB format.
- * @clear_rgb: Clear color, in 0xRRGGBB format.
- *
- * Sets clear color, equivalent to actually clearing the destination
- * buffer before rendering.
- **/
-void
-art_render_clear_rgb (ArtRender *render, art_u32 clear_rgb)
-{
- if (render->n_chan != 3)
- art_warn ("art_render_clear_rgb: called on render with %d channels, only works with 3\n",
- render->n_chan);
- else
- {
- int r, g, b;
-
- render->clear = ART_TRUE;
- r = clear_rgb >> 16;
- g = (clear_rgb >> 8) & 0xff;
- b = clear_rgb & 0xff;
- render->clear_color[0] = ART_PIX_MAX_FROM_8(r);
- render->clear_color[1] = ART_PIX_MAX_FROM_8(g);
- render->clear_color[2] = ART_PIX_MAX_FROM_8(b);
- }
-}
-
static void
art_render_nop_done (ArtRenderCallback *self, ArtRender *render)
{
@@ -238,43 +133,6 @@ const ArtRenderCallback art_render_clear_16_obj =
#endif /* ART_MAX_DEPTH >= 16 */
-/* todo: inline */
-static ArtRenderCallback *
-art_render_choose_clear_callback (ArtRender *render)
-{
- ArtRenderCallback *clear_callback;
-
- if (render->depth == 8)
- {
- if (render->n_chan == 3 &&
- render->alpha_type == ART_ALPHA_NONE)
- clear_callback = (ArtRenderCallback *)&art_render_clear_rgb8_obj;
- else
- clear_callback = (ArtRenderCallback *)&art_render_clear_8_obj;
- }
-#if ART_MAX_DEPTH >= 16
- else if (render->depth == 16)
- clear_callback = (ArtRenderCallback *)&art_render_clear_16_obj;
-#endif
- else
- {
- art_die ("art_render_choose_clear_callback: inconsistent render->depth = %d\n",
- render->depth);
- }
- return clear_callback;
-}
-
-#if 0
-/* todo: get around to writing this */
-static void
-art_render_composite_render_noa_8_norm (ArtRenderCallback *self, ArtRender *render,
- art_u8 *dest, int y)
-{
- int width = render->x1 - render->x0;
-
-}
-#endif
-
/* This is the most general form of the function. It is slow but
(hopefully) correct. Actually, I'm still worried about roundoff
errors in the premul case - it seems to me that an off-by-one could
@@ -882,27 +740,6 @@ const ArtRenderCallback art_render_composite_8_opt2_obj =
};
-/* todo: inline */
-static ArtRenderCallback *
-art_render_choose_compositing_callback (ArtRender *render)
-{
- if (render->depth == 8 && render->buf_depth == 8)
- {
- if (render->n_chan == 3 &&
- render->alpha_buf == NULL &&
- render->alpha_type == ART_ALPHA_SEPARATE)
- {
- if (render->buf_alpha == ART_ALPHA_NONE)
- return (ArtRenderCallback *)&art_render_composite_8_opt1_obj;
- else if (render->buf_alpha == ART_ALPHA_PREMUL)
- return (ArtRenderCallback *)&art_render_composite_8_opt2_obj;
- }
-
- return (ArtRenderCallback *)&art_render_composite_8_obj;
- }
- return (ArtRenderCallback *)&art_render_composite_obj;
-}
-
/**
* art_render_invoke_callbacks: Invoke the callbacks in the render object.
* @render: The render object.
@@ -930,184 +767,6 @@ art_render_invoke_callbacks (ArtRender *render, art_u8 *dest, int y)
}
/**
- * art_render_invoke: Perform the requested rendering task.
- * @render: The render object.
- *
- * Invokes the renderer and all sources associated with it, to perform
- * the requested rendering task.
- **/
-void
-art_render_invoke (ArtRender *render)
-{
- ArtRenderPriv *priv = (ArtRenderPriv *)render;
- int width;
- int best_driver, best_score;
- int i;
- int n_callbacks, n_callbacks_max;
- ArtImageSource *image_source;
- ArtImageSourceFlags image_flags;
- int buf_depth;
- ArtAlphaType buf_alpha;
- art_boolean first = ART_TRUE;
-
- if (render == NULL)
- {
- art_warn ("art_render_invoke: called with render == NULL\n");
- return;
- }
- if (priv->image_source == NULL)
- {
- art_warn ("art_render_invoke: no image source given\n");
- return;
- }
-
- width = render->x1 - render->x0;
-
- render->run = art_new (ArtRenderMaskRun, width + 1);
-
- /* Elect a mask source as driver. */
- best_driver = -1;
- best_score = 0;
- for (i = 0; i < priv->n_mask_source; i++)
- {
- int score;
- ArtMaskSource *mask_source;
-
- mask_source = priv->mask_source[i];
- score = mask_source->can_drive (mask_source, render);
- if (score > best_score)
- {
- best_score = score;
- best_driver = i;
- }
- }
-
- /* Allocate alpha buffer if needed. */
- if (priv->n_mask_source > 1 ||
- (priv->n_mask_source == 1 && best_driver < 0))
- {
- render->alpha_buf = art_new (art_u8, (width * render->depth) >> 3);
- }
-
- /* Negotiate image rendering and compositing. */
- image_source = priv->image_source;
- image_source->negotiate (image_source, render, &image_flags, &buf_depth,
- &buf_alpha);
-
- /* Build callback list. */
- n_callbacks_max = priv->n_mask_source + 3;
- priv->callbacks = art_new (ArtRenderCallback *, n_callbacks_max);
- n_callbacks = 0;
- for (i = 0; i < priv->n_mask_source; i++)
- if (i != best_driver)
- {
- ArtMaskSource *mask_source = priv->mask_source[i];
-
- mask_source->prepare (mask_source, render, first);
- first = ART_FALSE;
- priv->callbacks[n_callbacks++] = &mask_source->super;
- }
-
- if (render->clear && !(image_flags & ART_IMAGE_SOURCE_CAN_CLEAR))
- priv->callbacks[n_callbacks++] =
- art_render_choose_clear_callback (render);
-
- priv->callbacks[n_callbacks++] = &image_source->super;
-
- /* Allocate image buffer and add compositing callback if needed. */
- if (!(image_flags & ART_IMAGE_SOURCE_CAN_COMPOSITE))
- {
- int bytespp = ((render->n_chan + (buf_alpha != ART_ALPHA_NONE)) *
- buf_depth) >> 3;
- render->buf_depth = buf_depth;
- render->buf_alpha = buf_alpha;
- render->image_buf = art_new (art_u8, width * bytespp);
- priv->callbacks[n_callbacks++] =
- art_render_choose_compositing_callback (render);
- }
-
- priv->n_callbacks = n_callbacks;
-
- if (render->need_span)
- render->span_x = art_new (int, width + 1);
-
- /* Invoke the driver */
- if (best_driver >= 0)
- {
- ArtMaskSource *driver;
-
- driver = priv->mask_source[best_driver];
- driver->invoke_driver (driver, render);
- }
- else
- {
- art_u8 *dest_ptr = render->pixels;
- int y;
-
- /* Dummy driver */
- render->n_run = 2;
- render->run[0].x = render->x0;
- render->run[0].alpha = 0x8000 + 0xff * render->opacity;
- render->run[1].x = render->x1;
- render->run[1].alpha = 0x8000;
- if (render->need_span)
- {
- render->n_span = 2;
- render->span_x[0] = render->x0;
- render->span_x[1] = render->x1;
- }
- for (y = render->y0; y < render->y1; y++)
- {
- art_render_invoke_callbacks (render, dest_ptr, y);
- dest_ptr += render->rowstride;
- }
- }
-
- if (priv->mask_source != NULL)
- art_free (priv->mask_source);
-
- /* clean up callbacks */
- for (i = 0; i < priv->n_callbacks; i++)
- {
- ArtRenderCallback *callback;
-
- callback = priv->callbacks[i];
- callback->done (callback, render);
- }
-
- /* Tear down object */
- if (render->alpha_buf != NULL)
- art_free (render->alpha_buf);
- if (render->image_buf != NULL)
- art_free (render->image_buf);
- art_free (render->run);
- if (render->span_x != NULL)
- art_free (render->span_x);
- art_free (priv->callbacks);
- art_free (render);
-}
-
-/**
- * art_render_mask_solid: Add a solid translucent mask.
- * @render: The render object.
- * @opacity: Opacity in [0..0x10000] form.
- *
- * Adds a translucent mask to the rendering object.
- **/
-void
-art_render_mask_solid (ArtRender *render, int opacity)
-{
- art_u32 old_opacity = render->opacity;
- art_u32 new_opacity_tmp;
-
- if (opacity == 0x10000)
- /* avoid potential overflow */
- return;
- new_opacity_tmp = old_opacity * (art_u32)opacity + 0x8000;
- render->opacity = new_opacity_tmp >> 16;
-}
-
-/**
* art_render_add_mask_source: Add a mask source to the render object.
* @render: Render object.
* @mask_source: Mask source to add.
@@ -1170,214 +829,3 @@ struct _ArtImageSourceSolid {
art_boolean init;
};
-static void
-art_render_image_solid_done (ArtRenderCallback *self, ArtRender *render)
-{
- ArtImageSourceSolid *z = (ArtImageSourceSolid *)self;
-
- if (z->rgbtab != NULL)
- art_free (z->rgbtab);
- art_free (self);
-}
-
-static void
-art_render_image_solid_rgb8_opaq_init (ArtImageSourceSolid *self, ArtRender *render)
-{
- ArtImageSourceSolid *z = (ArtImageSourceSolid *)self;
- ArtPixMaxDepth color_max;
- int r_fg, g_fg, b_fg;
- int r_bg, g_bg, b_bg;
- int r, g, b;
- int dr, dg, db;
- int i;
- int tmp;
- art_u32 *rgbtab;
-
- rgbtab = art_new (art_u32, 256);
- z->rgbtab = rgbtab;
-
- color_max = self->color[0];
- r_fg = ART_PIX_8_FROM_MAX (color_max);
- color_max = self->color[1];
- g_fg = ART_PIX_8_FROM_MAX (color_max);
- color_max = self->color[2];
- b_fg = ART_PIX_8_FROM_MAX (color_max);
-
- color_max = render->clear_color[0];
- r_bg = ART_PIX_8_FROM_MAX (color_max);
- color_max = render->clear_color[1];
- g_bg = ART_PIX_8_FROM_MAX (color_max);
- color_max = render->clear_color[2];
- b_bg = ART_PIX_8_FROM_MAX (color_max);
-
- r = (r_bg << 16) + 0x8000;
- g = (g_bg << 16) + 0x8000;
- b = (b_bg << 16) + 0x8000;
- tmp = ((r_fg - r_bg) << 16) + 0x80;
- dr = (tmp + (tmp >> 8)) >> 8;
- tmp = ((g_fg - g_bg) << 16) + 0x80;
- dg = (tmp + (tmp >> 8)) >> 8;
- tmp = ((b_fg - b_bg) << 16) + 0x80;
- db = (tmp + (tmp >> 8)) >> 8;
-
- for (i = 0; i < 256; i++)
- {
- rgbtab[i] = (r & 0xff0000) | ((g & 0xff0000) >> 8) | (b >> 16);
- r += dr;
- g += dg;
- b += db;
- }
-}
-
-static void
-art_render_image_solid_rgb8_opaq (ArtRenderCallback *self, ArtRender *render,
- art_u8 *dest, int y)
-{
- ArtImageSourceSolid *z = (ArtImageSourceSolid *)self;
- ArtRenderMaskRun *run = render->run;
- int n_run = render->n_run;
- art_u32 *rgbtab = z->rgbtab;
- art_u32 rgb;
- int x0 = render->x0;
- int x1 = render->x1;
- int run_x0, run_x1;
- int i;
- int ix;
-
- if (n_run > 0)
- {
- run_x1 = run[0].x;
- if (run_x1 > x0)
- {
- rgb = rgbtab[0];
- art_rgb_fill_run (dest,
- rgb >> 16, (rgb >> 8) & 0xff, rgb & 0xff,
- run_x1 - x0);
- }
- for (i = 0; i < n_run - 1; i++)
- {
- run_x0 = run_x1;
- run_x1 = run[i + 1].x;
- rgb = rgbtab[(run[i].alpha >> 16) & 0xff];
- ix = (run_x0 - x0) * 3;
-#define OPTIMIZE_LEN_1
-#ifdef OPTIMIZE_LEN_1
- if (run_x1 - run_x0 == 1)
- {
- dest[ix] = rgb >> 16;
- dest[ix + 1] = (rgb >> 8) & 0xff;
- dest[ix + 2] = rgb & 0xff;
- }
- else
- {
- art_rgb_fill_run (dest + ix,
- rgb >> 16, (rgb >> 8) & 0xff, rgb & 0xff,
- run_x1 - run_x0);
- }
-#else
- art_rgb_fill_run (dest + ix,
- rgb >> 16, (rgb >> 8) & 0xff, rgb & 0xff,
- run_x1 - run_x0);
-#endif
- }
- }
- else
- {
- run_x1 = x0;
- }
- if (run_x1 < x1)
- {
- rgb = rgbtab[0];
- art_rgb_fill_run (dest + (run_x1 - x0) * 3,
- rgb >> 16, (rgb >> 8) & 0xff, rgb & 0xff,
- x1 - run_x1);
- }
-}
-
-static void
-art_render_image_solid_rgb8 (ArtRenderCallback *self, ArtRender *render,
- art_u8 *dest, int y)
-{
- ArtImageSourceSolid *z = (ArtImageSourceSolid *)self;
- int width = render->x1 - render->x0;
- art_u8 r, g, b;
- ArtPixMaxDepth color_max;
-
- /* todo: replace this simple test with real sparseness */
- if (z->init)
- return;
- z->init = ART_TRUE;
-
- color_max = z->color[0];
- r = ART_PIX_8_FROM_MAX (color_max);
- color_max = z->color[1];
- g = ART_PIX_8_FROM_MAX (color_max);
- color_max = z->color[2];
- b = ART_PIX_8_FROM_MAX (color_max);
-
- art_rgb_fill_run (render->image_buf, r, g, b, width);
-}
-
-static void
-art_render_image_solid_negotiate (ArtImageSource *self, ArtRender *render,
- ArtImageSourceFlags *p_flags,
- int *p_buf_depth, ArtAlphaType *p_alpha)
-{
- ArtImageSourceSolid *z = (ArtImageSourceSolid *)self;
- ArtImageSourceFlags flags = 0;
- static void (*render_cbk) (ArtRenderCallback *self, ArtRender *render,
- art_u8 *dest, int y);
-
- render_cbk = NULL;
-
- if (render->depth == 8 && render->n_chan == 3 &&
- render->alpha_type == ART_ALPHA_NONE)
- {
- if (render->clear)
- {
- render_cbk = art_render_image_solid_rgb8_opaq;
- flags |= ART_IMAGE_SOURCE_CAN_CLEAR | ART_IMAGE_SOURCE_CAN_COMPOSITE;
- art_render_image_solid_rgb8_opaq_init (z, render);
- }
- }
- if (render_cbk == NULL)
- {
- if (render->depth == 8)
- {
- render_cbk = art_render_image_solid_rgb8;
- *p_buf_depth = 8;
- *p_alpha = ART_ALPHA_NONE; /* todo */
- }
- }
- /* todo: general case */
- self->super.render = render_cbk;
- *p_flags = flags;
-}
-
-/**
- * art_render_image_solid: Add a solid color image source.
- * @render: The render object.
- * @color: Color.
- *
- * Adds an image source with the solid color given by @color. The
- * color need not be retained in memory after this call.
- **/
-void
-art_render_image_solid (ArtRender *render, ArtPixMaxDepth *color)
-{
- ArtImageSourceSolid *image_source;
- int i;
-
- image_source = art_new (ArtImageSourceSolid, 1);
- image_source->super.super.render = NULL;
- image_source->super.super.done = art_render_image_solid_done;
- image_source->super.negotiate = art_render_image_solid_negotiate;
-
- for (i = 0; i < render->n_chan; i++)
- image_source->color[i] = color[i];
-
- image_source->rgbtab = NULL;
- image_source->init = ART_FALSE;
-
- art_render_add_image_source (render, &image_source->super);
-}