Beispiel #1
0
static int merged_svg(gstack_t *ross, svg_t *svg)
{
  svg_stop_t ss;
  rgbop_stop_t ros;

  while (gstack_pop(ross, &ros) == 0)
    {
      ss.colour.red   = svg_it_rgb(ros.r);
      ss.colour.green = svg_it_rgb(ros.g);
      ss.colour.blue  = svg_it_rgb(ros.b);
      ss.opacity      = svg_it_op(ros.op);
      ss.value        = svg_it_z(ros.z);
      svg_append(ss,svg);
    }

  return 0;
}
Beispiel #2
0
static gstack_t* merge(gstack_t *rss, gstack_t *oss)
{
  gstack_t *ross;
  int err = 0;
  size_t n = gstack_size(rss) + gstack_size(oss);

  /* get the first two of each type of stop */

  rgb_stop_t rs0, rs1;

  err += gstack_pop(rss, &rs0);
  err += gstack_pop(rss, &rs1);

  if (err)
    {
      btrace("%i errors rgb", err);
      return NULL;
    }

  op_stop_t os0, os1;

  err += gstack_pop(oss, &os0);
  err += gstack_pop(oss, &os1);

  if (err)
    {
      btrace("%i errors op", err);
      return NULL;
    }

  if ((rs0.z != 0) || (os0.z != 0))
    {
      btrace("nonzero initial stop");
      btrace("RGB     %.3f", svg_it_z(rs0.z));
      btrace("Opacity %.3f", svg_it_z(os0.z));
      return NULL;
    }

  /* merged stack to return */

  if ((ross = gstack_new(sizeof(rgbop_stop_t), n, n)) == NULL)
    return NULL;

  rgbop_stop_t ros;

  while (1)
    {
      ros = stop_merge(rs0, os0);
      gstack_push(ross, &ros);

      if (rs1.z > os1.z)
	{
	  rs0 = rgb_stop_interp(rs0, rs1, os1.z);
	  os0 = os1;

	  if (gstack_pop(oss, &os1) != 0)
	    {
	      btrace("early termination of opacity channel");
	      break;
	    }
	}
      else if (rs1.z < os1.z)
	{
	  os0 = op_stop_interp(os0, os1, rs1.z);
	  rs0 = rs1;

	  if (gstack_pop(rss, &rs1) != 0)
	    {
	      btrace("early termination of rgb channel");
	      break;
	    }
	}
      else
	{
	  rs0 = rs1;
	  os0 = os1;

	  int
            odone = gstack_pop(oss, &os1),
            rdone = gstack_pop(rss, &rs1);

	  if (odone && rdone)
	    {
	      ros = stop_merge(rs0, os0);
	      gstack_push(ross, &ros);
	      gstack_reverse(ross);

	      return ross;
	    }
	  else if (odone && !rdone)
	    {
	      btrace("early termination of opacity channel");
	      break;
	    }
	  else if (rdone && ! odone)
	    {
	      btrace("early termination of rgb channel");
	      break;
	    }
	  else
	    {
	      /* OK, so now we continue */
	    }
	}
    }

  /* something has gone pear-shaped */

  gstack_destroy(ross);

  btrace("merge failed");

  return NULL;
}