static void
profile_palette_notify_colorpickers_cb (GSettings *profile,
                                        const char *key,
                                        GtkWidget *editor)
{
  GtkWidget *w;
  GtkBuilder *builder;
  gs_free GdkRGBA *colors;
  gsize n_colors, i;

  g_assert (strcmp (key, TERMINAL_PROFILE_PALETTE_KEY) == 0);

  builder = g_object_get_data (G_OBJECT (editor), "builder");
  g_assert (builder != NULL);

  colors = terminal_g_settings_get_rgba_palette (profile, TERMINAL_PROFILE_PALETTE_KEY, &n_colors);

  n_colors = MIN (n_colors, TERMINAL_PALETTE_SIZE);
  for (i = 0; i < n_colors; i++)
    {
      char name[32];
      GdkRGBA old_color;

      g_snprintf (name, sizeof (name), "palette-colorpicker-%" G_GSIZE_FORMAT, i + 1);
      w = (GtkWidget *) gtk_builder_get_object  (builder, name);

      gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (w), &old_color);
      if (!rgba_equal (&old_color, &colors[i]))
        {
          g_signal_handlers_block_by_func (w, G_CALLBACK (palette_color_notify_cb), profile);
          gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (w), &colors[i]);
          g_signal_handlers_unblock_by_func (w, G_CALLBACK (palette_color_notify_cb), profile);
        }
    }
}
static gboolean
palette_cmp (const GdkRGBA *ca,
             const GdkRGBA *cb)
{
  guint i;

  for (i = 0; i < TERMINAL_PALETTE_SIZE; ++i)
    if (!rgba_equal (&ca[i], &cb[i]))
      return FALSE;

  return TRUE;
}
static void
profile_colors_notify_scheme_combo_cb (GSettings *profile,
                                       const char *key,
                                       GtkComboBox *combo)
{
  GdkRGBA fg, bg;
  guint i;

  terminal_g_settings_get_rgba (profile, TERMINAL_PROFILE_FOREGROUND_COLOR_KEY, &fg);
  terminal_g_settings_get_rgba (profile, TERMINAL_PROFILE_BACKGROUND_COLOR_KEY, &bg);

  for (i = 0; i < G_N_ELEMENTS (color_schemes); ++i)
    {
      if (rgba_equal (&fg, &color_schemes[i].foreground) &&
          rgba_equal (&bg, &color_schemes[i].background))
        break;
    }
  /* If we didn't find a match, then we get the last combo box item which is "custom" */

  g_signal_handlers_block_by_func (combo, G_CALLBACK (color_scheme_combo_changed_cb), profile);
  gtk_combo_box_set_active (GTK_COMBO_BOX (combo), i);
  g_signal_handlers_unblock_by_func (combo, G_CALLBACK (color_scheme_combo_changed_cb), profile);
}
/*
 * Test reading back a luminance texture via FBO + glReadPixels as RGBA.
 */
static bool
test_fbo_readpixels_lum_as_rgba(void)
{
	static const GLfloat lumImage[2*2] = { 0.25, 0.25, 0.25, 0.25 };
	static const GLfloat rgbaImage[4] = { 0.25, 0.0, 0.0, 1.0 };
	GLuint tex, fbo;
	GLfloat test[2*2*4];
	GLenum status;

	if (!piglit_is_extension_supported("GL_ARB_framebuffer_object"))
		return true;

	/* create 2x2 GL_LUMINANCE texture */
	glGenTextures(1, &tex);
	glBindTexture(GL_TEXTURE_2D, tex);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 2, 2, 0,
		     GL_LUMINANCE, GL_FLOAT, lumImage);

	/* create an FBO to wrap the texture so we can read it back
	 * with glReadPixels
	 */
	glGenFramebuffers(1, &fbo);
	glBindFramebuffer(GL_FRAMEBUFFER, fbo);
	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT,
			       GL_TEXTURE_2D, tex, 0);

	status = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
	if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
		/* can't test glReadPixels from a luminance fbo/texture */
		if (!piglit_automatic) {
			printf("Skipping FBO ReadPixels test\n");
		}
		return true;
	}

	/* get rgba image (only red should have the lum value) */
	glReadPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, test);
	if (!rgba_equal(rgbaImage, test)) {
		printf("%s: glReadPixels(GL_LUMINANCE as GL_RGBA) failed\n",
		       TestName);
		printf("  Expected %g, %g, %g, %g  Found %g, %g, %g, %g\n",
		       rgbaImage[0], rgbaImage[1], rgbaImage[2], rgbaImage[3],
		       test[0], test[1], test[2], test[3]);
		return false;
	}

	return true;
}
/*
 * Test reading back a luminance texture as luminance and RGBA.
 */
static bool
test_luminance(void)
{
	static const GLfloat lumImage[2*2] = { 0.25, 0.25, 0.25, 0.25 };
	static const GLfloat rgbaImage[4] = { 0.25, 0.0, 0.0, 1.0 };
	GLuint tex;
	GLfloat test[2*2*4];

	/* create 2x2 GL_LUMINANCE texture */
	glGenTextures(1, &tex);
	glBindTexture(GL_TEXTURE_2D, tex);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 2, 2, 0,
		     GL_LUMINANCE, GL_FLOAT, lumImage);

	/* Get and check luminance image */
	glGetTexImage(GL_TEXTURE_2D, 0, GL_LUMINANCE, GL_FLOAT, test);
	if (!lum_equal(lumImage, test)) {
		printf("%s: glGetTexImage(GL_LUMINANCE as"
		       " GL_LUMINANCE) failed\n", TestName);
		printf("  Expected %g  Found %g\n", lumImage[0], test[0]);
		return false;
	}

	/* Get and check rgba image */
	glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, &test);
	if (!rgba_equal(rgbaImage, test)) {
		printf("%s: glGetTexImage(GL_LUMINANCE as GL_RGBA) failed\n",
		       TestName);
		printf("  Expected %g, %g, %g, %g  Found %g, %g, %g, %g\n",
		       rgbaImage[0], rgbaImage[1], rgbaImage[2], rgbaImage[3],
		       test[0], test[1], test[2], test[3]);
		return false;
	}

	return true;
}
Exemplo n.º 6
0
static int calculate_gradient(const image *image, gradient *g)
{
	rgba tl, tr, bl, br, mid, avg;
	png_uint_32 i, l, base, min, max;
	png_uint_32 xy[2][2] = {{0, 0},{0, 0}};

	tl = getpixel(image, 0, 0);
	tr = getpixel(image, image->image.width-1, 0);
	bl = getpixel(image, 0, image->image.height-1);
	br = getpixel(image, image->image.width-1, image->image.height-1);

	if(rgba_equal(tl, tr)) {
		g->start = top;
		l=image->image.height;
		if(l % 2 == 1) {
			mid = getpixel(image, 0, l/2);
		}
		else {
			mid = rgba_avg(getpixel(image, 0, l/2), getpixel(image, 0, l/2-1));
		}
	}
	else if(rgba_equal(tl, bl)) {
		g->start = left;
		l=image->image.width;
		if(l % 2 == 1) {
			mid = getpixel(image, l/2, 0);
		}
		else {
			mid = rgba_avg(getpixel(image, l/2, 0), getpixel(image, l/2-1, 0));
		}
	}
	else if(rgba_equal(tr, bl) && !rgba_equal(tl, br)) {
		g->start = top_left;
		l=image->image.height;
	}
	else if(rgba_equal(tl, br) && !rgba_equal(tr, bl)) {
		g->start = top_right;
		l=image->image.height;
		tl = tr;
		br = bl;
	}
	else { /* Defaulting to vertical gradient */
		g->start = top;
		l=image->image.height;
		if(l % 2 == 1) {
			mid = getpixel(image, 0, l/2);
		}
		else {
			mid = rgba_avg(getpixel(image, 0, l/2), getpixel(image, 0, l/2-1));
		}
	}

	g->colors = (rgba *)calloc(2, sizeof(rgba));
	g->colors[0] = tl;
	g->colors[1] = br;
	g->ncolors = 2;

	/* If it's a diagonal, we only support 2 colours */
	/* If it's horizontal or vertical and the middle colour is the avg of the ends, then
	 * we only need two colours */
	/* Also, if the image is less than 3 pixels in the direction of the gradient, then you
	 * really cannot have more than 2 colours */
	if(g->start == top_left || g->start == top_right || l < 3
		|| rgba_equal(mid, rgba_avg(tl, br))) {

		return 0;
	}

	/* Now we come to the complicated part where there are more than 2 colours 
	 * The good thing though is that it's either horizontal or vertical at this point
	 * and that it is at least 3 pixels long in the direction of the gradient
	 *
	 * So this is what we'll do.
	 * - take a slice of the image from the top (or left) and see if the mid pixel matches
	 *   the average of the two ends.  we start at 3 pixels.
	 * - if it does, then double the size of the slice and retry (until you reach the end of the image)
	 * - if it does not match, then reduce until it does match this is the first stop
	 */

	min = base = 0;
	xy[0][g->start] = base;
	max = i = 2;

	while(i+base<l) {
		xy[1][g->start] = i+base;
		avg = rgba_avg(getpixel(image, xy[0][0], xy[0][1]), getpixel(image, xy[1][0], xy[1][1]));
		if((i+base) % 2 == 0) {
			mid = getpixel(image, (xy[1][0]+xy[0][0])/2, (xy[1][1]+xy[0][1])/2);
		}
		else {
			mid = rgba_avg(
					getpixel(image, (xy[1][0]+xy[0][0])/2, (xy[1][1]+xy[0][1])/2),
					getpixel(image, (xy[1][0]+xy[0][0])/2+1, (xy[1][1]+xy[0][1])/2+1)
				     );
		}


		if(!rgba_equal(avg, mid)) {
			if(min == max) {
				min++;
				max=i=min+2;
			}
			else {
				max = i;
				i = (i+min)/2;
			}
		}
		else if(max-i<=1 && i-min<=1) {
			/* We've converged */
			if(base+i >= l-1) {
				/* This is the same as the end point, so skip */
				i++;
			}
			else {
				/* If current and previous positions are not the same */
				if (g->colors[g->ncolors - 2].pos != (i + base) * 100 / l &&
					(i + base) * 100 / l != 0) {
					g->ncolors++;
					g->colors = (rgba *)realloc(g->colors, sizeof(rgba)*g->ncolors);
					g->colors[g->ncolors-2] = getpixel(image, xy[1][0], xy[1][1]);
					g->colors[g->ncolors-2].pos = (i+base)*100/l;
				}

				if (i == 0) /* Needed to avoid infinite loop */
					base += i + 1;
				else
					base += i;

				min = 0;
				max = i = l-base-1;
				xy[0][g->start] = base;
			}
		}
		else {
			min = i;
			if(i == max) {
				i*=2;
				if(i+base >= l)
					i = l-base-1;
				max = i;
			}
			else {
				i = (i+max)/2;
			}
		}
	}
	g->colors[g->ncolors-1] = br;

	if(g->colors == 0)
		return 0;
	else
		return 1;
}