diff options
author | Caleb Michael Moore <cmoore@src.gnome.org> | 2005-05-16 14:45:47 +0000 |
---|---|---|
committer | Caleb Michael Moore <cmoore@src.gnome.org> | 2005-05-16 14:45:47 +0000 |
commit | a3613bf39c88d45bb3e69b2007c5f1fbe601560e (patch) | |
tree | 0f4578c2d28ff6c1cdf9b18445e39fd8da64233f /rsvg-filter.c | |
parent | cf2e610b3469e5a29194225accd5c06c225b2047 (diff) | |
download | librsvg-a3613bf39c88d45bb3e69b2007c5f1fbe601560e.tar.gz |
further DOM restructuring
Diffstat (limited to 'rsvg-filter.c')
-rw-r--r-- | rsvg-filter.c | 231 |
1 files changed, 131 insertions, 100 deletions
diff --git a/rsvg-filter.c b/rsvg-filter.c index 91713796..c4102e13 100644 --- a/rsvg-filter.c +++ b/rsvg-filter.c @@ -321,9 +321,9 @@ rsvg_filter_render (RsvgFilter * self, GdkPixbuf * source, GdkPixbuf * output, ctx->lastresult.Aused = 1; ctx->lastresult.bounds = rsvg_filter_primitive_get_bounds (NULL, ctx); - for (i = 0; i < self->primitives->len; i++) + for (i = 0; i < self->super.children->len; i++) { - current = g_ptr_array_index (self->primitives, i); + current = g_ptr_array_index (self->super.children, i); rsvg_filter_primitive_render (current, ctx); } @@ -527,29 +527,6 @@ rsvg_filter_parse (const RsvgDefs * defs, const char *str) return NULL; } -static void -rsvg_filter_add_child (RsvgNode *overself, RsvgNode *child) -{ - RsvgFilter *self = (RsvgFilter *)overself; - g_ptr_array_add (self->primitives, child); -} - -/** - * rsvg_filter_free: Free a filter. - * @dself: The defval to be freed - * - * Frees a filter and all primatives associated with this filter, this is - * to be set as its free function to be used with rsvg defs - **/ -static void -rsvg_filter_free (RsvgNode * dself) -{ - RsvgFilter *self; - - self = (RsvgFilter *) dself; - g_ptr_array_free(self->primitives, FALSE); -} - static void rsvg_filter_set_args (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts) { @@ -605,6 +582,13 @@ rsvg_filter_set_args (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts) } } +static void +rsvg_filter_free (RsvgNode *self) +{ + g_ptr_array_free(self->children, TRUE); + g_free (self); +} + /** * rsvg_new_filter: Creates a black filter * @@ -622,10 +606,11 @@ rsvg_new_filter (void) filter->y = -0.1; filter->width = 1.2; filter->height = 1.2; - filter->primitives = g_ptr_array_new (); + filter->super.children = g_ptr_array_new (); filter->super.type = RSVG_NODE_FILTER; filter->super.free = rsvg_filter_free; - filter->super.add_child = rsvg_filter_add_child; + filter->super.draw = _rsvg_node_draw_nothing; + filter->super.add_child = rsvg_node_add_child; filter->super.set_atts = rsvg_filter_set_args; return &filter->super; } @@ -1819,7 +1804,6 @@ typedef struct _RsvgFilterPrimitiveMerge RsvgFilterPrimitiveMerge; struct _RsvgFilterPrimitiveMerge { RsvgFilterPrimitive super; - GPtrArray *nodes; }; static void @@ -1839,9 +1823,9 @@ rsvg_filter_primitive_merge_render (RsvgFilterPrimitive * self, output = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, ctx->width, ctx->height); - for (i = 0; i < mself->nodes->len; i++) + for (i = 0; i < mself->super.super.children->len; i++) { - in = rsvg_filter_get_in (g_ptr_array_index (mself->nodes, i), ctx); + in = rsvg_filter_get_in (g_ptr_array_index (mself->super.super.children, i), ctx); rsvg_art_alpha_blt (in, boundarys.x1, boundarys.y1, boundarys.x2 - boundarys.x1, boundarys.y2 - boundarys.y1, output, boundarys.x1, boundarys.y1); @@ -1857,14 +1841,11 @@ static void rsvg_filter_primitive_merge_free (RsvgNode * self) { RsvgFilterPrimitiveMerge *mself; - guint i; mself = (RsvgFilterPrimitiveMerge *) self; g_string_free (mself->super.result, TRUE); - for (i = 0; i < mself->nodes->len; i++) - g_string_free (g_ptr_array_index (mself->nodes, i), TRUE); - g_ptr_array_free (mself->nodes, TRUE); + g_ptr_array_free (mself->super.super.children, TRUE); g_free (mself); } @@ -1931,39 +1912,48 @@ rsvg_new_filter_primitive_merge (void) filter = g_new (RsvgFilterPrimitiveMerge, 1); filter->super.result = g_string_new ("none"); filter->super.sizedefaults = 1; - filter->nodes = g_ptr_array_new (); filter->super.render = &rsvg_filter_primitive_merge_render; filter->super.super.free = &rsvg_filter_primitive_merge_free; filter->super.super.type = RSVG_NODE_FILTER_PRIMITIVE; filter->super.super.set_atts = rsvg_filter_primitive_merge_set_atts; + filter->super.super.children = g_ptr_array_new(); + filter->super.super.add_child = rsvg_node_add_child; return (RsvgNode *)filter; } -void -rsvg_start_filter_primitive_merge_node (RsvgHandle * ctx, - RsvgPropertyBag * atts) +static void +rsvg_filter_primitive_merge_node_set_atts (RsvgNode * self, + RsvgHandle * ctx, + RsvgPropertyBag * atts) { - const char *value; - int needdefault = 1; - if (!(ctx && ctx->currentnode)) - return; - + const char * value; if (rsvg_property_bag_size (atts)) { /* see bug 145149 - sodipodi generates bad SVG... */ if ((value = rsvg_property_bag_lookup (atts, "in"))) - { - needdefault = 0; - g_ptr_array_add (((RsvgFilterPrimitiveMerge *) - (ctx->currentnode))-> - nodes, g_string_new (value)); - } + g_string_assign (((RsvgFilterPrimitive *)self)->in, value); } - - if (needdefault) - g_ptr_array_add (((RsvgFilterPrimitiveMerge *) - (ctx->currentnode))-> - nodes, g_string_new ("none")); +} + +static void +rsvg_filter_primitive_merge_node_free (RsvgNode * self) +{ + RsvgFilterPrimitive *mself; + mself = (RsvgFilterPrimitive *) self; + g_string_free (mself->in, TRUE); + g_free (mself); +} + +RsvgNode * +rsvg_new_filter_primitive_merge_node (void) +{ + RsvgFilterPrimitive *filter; + filter = g_new (RsvgFilterPrimitive, 1); + filter->in = g_string_new ("none"); + filter->super.free = rsvg_filter_primitive_merge_node_free; + filter->super.set_atts = rsvg_filter_primitive_merge_node_set_atts; + filter->super.type = RSVG_NODE_FILTER_PRIMITIVE_MERGE_NODE; + return &filter->super; } /*************************************************************/ @@ -4317,10 +4307,11 @@ typedef enum { DISTANTLIGHT, POINTLIGHT, SPOTLIGHT } lightType; -typedef struct _lightSource lightSource; +typedef struct _RsvgNodeLightSource RsvgNodeLightSource; -struct _lightSource +struct _RsvgNodeLightSource { + RsvgNode super; lightType type; gdouble x; /*doubles as azimuth*/ gdouble y; /*dounles as elevation*/ @@ -4333,7 +4324,7 @@ struct _lightSource }; static vector3 -get_light_direction (lightSource source, gdouble x1, gdouble y1, gdouble z, gdouble * affine) +get_light_direction (RsvgNodeLightSource * source, gdouble x1, gdouble y1, gdouble z, gdouble * affine) { vector3 output; @@ -4342,18 +4333,18 @@ get_light_direction (lightSource source, gdouble x1, gdouble y1, gdouble z, gdou x = affine[0] * x1 + affine[2] * y1 + affine[4]; y = affine[1] * x1 + affine[3] * y1 + affine[5]; - switch (source.type) + switch (source->type) { case DISTANTLIGHT: - output.x = cos(source.x)*cos(source.y); - output.y = sin(source.x)*cos(source.y); - output.z = sin(source.y); + output.x = cos(source->x)*cos(source->y); + output.y = sin(source->x)*cos(source->y); + output.z = sin(source->y); break; case POINTLIGHT: case SPOTLIGHT: - output.x = source.x - x; - output.y = source.y - y; - output.z = source.z - z; + output.x = source->x - x; + output.y = source->y - y; + output.z = source->z - z; output = normalise(output); break; } @@ -4361,7 +4352,7 @@ get_light_direction (lightSource source, gdouble x1, gdouble y1, gdouble z, gdou } static vector3 -get_light_colour(lightSource source, vector3 colour, +get_light_colour(RsvgNodeLightSource * source, vector3 colour, gdouble x1, gdouble y1, gdouble z, gdouble * affine) { double base, angle, x, y; @@ -4369,27 +4360,27 @@ get_light_colour(lightSource source, vector3 colour, vector3 L; vector3 output; - if (source.type != SPOTLIGHT) + if (source->type != SPOTLIGHT) return colour; x = affine[0] * x1 + affine[2] * y1 + affine[4]; y = affine[1] * x1 + affine[3] * y1 + affine[5]; - L.x = source.x - x; - L.y = source.y - y; - L.z = source.z - z; + L.x = source->x - x; + L.y = source->y - y; + L.z = source->z - z; L = normalise(L); - s.x = source.pointsAtX - source.x; - s.y = source.pointsAtY - source.y; - s.z = source.pointsAtZ - source.z; + s.x = source->pointsAtX - source->x; + s.y = source->pointsAtY - source->y; + s.z = source->pointsAtZ - source->z; s = normalise(s); base = -dotproduct(L, s); angle = acos(base) * 180.0 / M_PI; - if (base < 0 || angle > source.limitingconeAngle) + if (base < 0 || angle > source->limitingconeAngle) { output.x = 0; output.y = 0; @@ -4397,34 +4388,25 @@ get_light_colour(lightSource source, vector3 colour, return output; } - output.x = colour.x*pow(base, source.specularExponent); - output.y = colour.y*pow(base, source.specularExponent); - output.z = colour.z*pow(base, source.specularExponent); + output.x = colour.x*pow(base, source->specularExponent); + output.y = colour.y*pow(base, source->specularExponent); + output.z = colour.z*pow(base, source->specularExponent); return output; } -void -rsvg_start_filter_primitive_light_source (RsvgHandle * ctx, - RsvgPropertyBag * atts, char type) +static void +rsvg_filter_primitive_light_source_set_atts (RsvgNode * self, + RsvgHandle * ctx, + RsvgPropertyBag * atts) { - lightSource * data; + RsvgNodeLightSource * data; const char *value; double font_size; font_size = rsvg_state_current_font_size (ctx); - data = (lightSource *)ctx->currentnode; - data->specularExponent = 1; - - if (type == 's') - data->type = SPOTLIGHT; - else if (type == 'd') - data->type = DISTANTLIGHT; - else - data->type = POINTLIGHT; - - data->limitingconeAngle = 180; + data = (RsvgNodeLightSource *)self; if (rsvg_property_bag_size (atts)) { @@ -4475,6 +4457,29 @@ rsvg_start_filter_primitive_light_source (RsvgHandle * ctx, } } +static void +rsvg_filter_primitive_light_source_free(RsvgNode * tofree) +{ + g_free(tofree); +} + +RsvgNode * +rsvg_new_filter_primitive_light_source(char type) +{ + RsvgNodeLightSource * data; + data = g_new(RsvgNodeLightSource, 1); + data->super.free = rsvg_filter_primitive_light_source_free; + data->super.set_atts = rsvg_filter_primitive_light_source_set_atts; + data->specularExponent = 1; + if (type == 's') + data->type = SPOTLIGHT; + else if (type == 'd') + data->type = DISTANTLIGHT; + else + data->type = POINTLIGHT; + data->limitingconeAngle = 180; + return &data->super; +} /*************************************************************/ /*************************************************************/ @@ -4487,7 +4492,6 @@ struct _RsvgFilterPrimitiveDiffuseLighting gdouble dx, dy; double diffuseConstant; double surfaceScale; - lightSource source; guint32 lightingcolour; }; @@ -4503,7 +4507,7 @@ rsvg_filter_primitive_diffuse_lighting_render (RsvgFilterPrimitive * self, vector3 lightcolour, L, N; vector3 colour; gdouble iaffine[6]; - + RsvgNodeLightSource * source = NULL; FPBox boundarys; guchar *in_pixels; @@ -4513,7 +4517,18 @@ rsvg_filter_primitive_diffuse_lighting_render (RsvgFilterPrimitive * self, GdkPixbuf *output; GdkPixbuf *in; - + unsigned int i; + + for (i = 0; i < self->super.children->len; i++) + { + RsvgNode * temp; + temp = g_ptr_array_index(self->super.children, i); + if (temp->type == RSVG_NODE_FILTER_PRIMITIVE_MERGE_NODE) + source = (RsvgNodeLightSource *)temp; + } + if (source == NULL) + return; + oself = (RsvgFilterPrimitiveDiffuseLighting *) self; boundarys = rsvg_filter_primitive_get_bounds (self, ctx); @@ -4556,11 +4571,11 @@ rsvg_filter_primitive_diffuse_lighting_render (RsvgFilterPrimitive * self, for (x = boundarys.x1; x < boundarys.x2; x++) { z = surfaceScale * (double)in_pixels[y * rowstride + x * 4 + 3]; - L = get_light_direction(oself->source, x, y, z, iaffine); + L = get_light_direction(source, x, y, z, iaffine); N = get_surface_normal(in_pixels, boundarys, x, y, dx, dy, rawdx, rawdy, oself->surfaceScale, rowstride); - lightcolour = get_light_colour(oself->source, colour, x, y, z, + lightcolour = get_light_colour(source, colour, x, y, z, iaffine); factor = dotproduct(N, L); @@ -4677,6 +4692,8 @@ rsvg_new_filter_primitive_diffuse_lighting (void) filter->super.super.free = &rsvg_filter_primitive_diffuse_lighting_free; filter->super.super.type = RSVG_NODE_FILTER_PRIMITIVE; filter->super.super.set_atts = rsvg_filter_primitive_diffuse_lighting_set_atts; + filter->super.super.children = g_ptr_array_new(); + filter->super.super.add_child = rsvg_node_add_child; return (RsvgNode *)filter; } @@ -4691,7 +4708,6 @@ struct _RsvgFilterPrimitiveSpecularLighting double specularConstant; double specularExponent; double surfaceScale; - lightSource source; guint32 lightingcolour; }; @@ -4708,7 +4724,8 @@ rsvg_filter_primitive_specular_lighting_render (RsvgFilterPrimitive * self, vector3 L; gdouble iaffine[6]; FPBox boundarys; - + RsvgNodeLightSource *source = NULL; + guchar *in_pixels; guchar *output_pixels; @@ -4716,6 +4733,18 @@ rsvg_filter_primitive_specular_lighting_render (RsvgFilterPrimitive * self, GdkPixbuf *output; GdkPixbuf *in; + + unsigned int i; + + for (i = 0; i < self->super.children->len; i++) + { + RsvgNode * temp; + temp = g_ptr_array_index(self->super.children, i); + if (temp->type == RSVG_NODE_FILTER_PRIMITIVE_MERGE_NODE) + source = (RsvgNodeLightSource *)temp; + } + if (source == NULL) + return; oself = (RsvgFilterPrimitiveSpecularLighting *) self; boundarys = rsvg_filter_primitive_get_bounds (self, ctx); @@ -4744,11 +4773,11 @@ rsvg_filter_primitive_specular_lighting_render (RsvgFilterPrimitive * self, for (x = boundarys.x1; x < boundarys.x2; x++) { z = in_pixels[y * rowstride + x * 4 + 3] * surfaceScale; - L = get_light_direction(oself->source, x, y, z, iaffine); + L = get_light_direction(source, x, y, z, iaffine); L.z += 1; L = normalise(L); - lightcolour = get_light_colour(oself->source, colour, x, y, z, + lightcolour = get_light_colour(source, colour, x, y, z, iaffine); base = dotproduct(get_surface_normal(in_pixels, boundarys, x, y, 1, 1, 1.0 / ctx->paffine[0], 1.0 / ctx->paffine[3], @@ -4886,6 +4915,8 @@ rsvg_new_filter_primitive_specular_lighting (void) filter->super.super.free = &rsvg_filter_primitive_specular_lighting_free; filter->super.super.type = RSVG_NODE_FILTER_PRIMITIVE; filter->super.super.set_atts = rsvg_filter_primitive_specular_lighting_set_atts; + filter->super.super.children = g_ptr_array_new(); + filter->super.super.add_child = rsvg_node_add_child; return (RsvgNode *)filter; } |