Пример #1
1
gboolean
rcm_gray_motion_notify_event (GtkWidget      *widget,
			      GdkEventMotion *event,
			      RcmGray        *circle)
{
  gint        x, y;
  GdkGCValues values;

  values.function = GDK_INVERT;
  xor_gc = gdk_gc_new_with_values (Current.From->preview->window,
				   &values,
                                   GDK_GC_FUNCTION);

  if (circle->action_flag == DRAG_START)
    {
      GtkStyle *style = gtk_widget_get_style (circle->preview);

      gtk_widget_queue_draw (circle->preview);
      color_rotate_draw_large_circle (circle->preview->window,
                                      style->black_gc,
                                      circle->gray_sat);

      circle->action_flag = DRAGING;
    }
  else
    {
      color_rotate_draw_little_circle (widget->window, xor_gc,
                                       circle->hue, circle->satur); /* erase */
    }

  x = event->x - GRAY_CENTER - LITTLE_RADIUS;
  y = GRAY_CENTER - event->y + LITTLE_RADIUS;

  circle->hue   = angle_mod_2PI (arctg (y, x));
  circle->satur = sqrt (SQR (x) + SQR (y)) / GRAY_RADIUS;

  if (circle->satur > 1.0)
    circle->satur = 1;

  color_rotate_draw_little_circle (widget->window, xor_gc,
                                   circle->hue, circle->satur);

  gtk_spin_button_set_value (GTK_SPIN_BUTTON (circle->hue_entry),
                             circle->hue * rcm_units_factor(Current.Units));

  gtk_spin_button_set_value (GTK_SPIN_BUTTON (circle->satur_entry),
                             circle->satur);

  if (Current.RealTime)
    rcm_render_preview (Current.Bna->after);

  gdk_event_request_motions (event);

  return TRUE;
}
Пример #2
0
float
rcm_angle_inside_slice (float     angle,
			RcmAngle *slice)
{
  return angle_mod_2PI (slice->cw_ccw * (slice->beta-angle)) /
         angle_mod_2PI (slice->cw_ccw * (slice->beta-slice->alpha));
}
Пример #3
0
static gfloat
angle_inside_slice (gfloat   hue,
                    gfloat   from,
                    gfloat   to,
                    gboolean cl)
{
  gint cw_ccw = cl ? -1 : 1;

  return angle_mod_2PI (cw_ccw * DEG_TO_RAD (to - hue)) /
         angle_mod_2PI (cw_ccw * DEG_TO_RAD (from - to));
}
Пример #4
0
float
min_prox (float alpha,
	  float beta,
	  float angle)
{
  gfloat temp1 = MIN (angle_mod_2PI (alpha - angle),
                      TP - angle_mod_2PI (alpha - angle));
  gfloat temp2 = MIN (angle_mod_2PI (beta - angle),
                      TP - angle_mod_2PI (beta - angle));

  return MIN(temp1, temp2);
}
Пример #5
0
gboolean
rcm_gray_motion_notify_event (GtkWidget      *widget,
			      GdkEventMotion *event,
			      RcmGray        *circle)
{
  gint x, y;

  gtk_widget_queue_draw (circle->preview);

  x = event->x - GRAY_CENTER - LITTLE_RADIUS;
  y = GRAY_CENTER - event->y + LITTLE_RADIUS;

  circle->hue   = angle_mod_2PI (arctg (y, x));
  circle->satur = sqrt (SQR (x) + SQR (y)) / GRAY_RADIUS;

  if (circle->satur > 1.0)
    circle->satur = 1;

  gtk_spin_button_set_value (GTK_SPIN_BUTTON (circle->hue_entry),
                             circle->hue * rcm_units_factor(Current.Units));

  gtk_spin_button_set_value (GTK_SPIN_BUTTON (circle->satur_entry),
                             circle->satur);

  if (Current.RealTime)
    rcm_render_preview (Current.Bna->after);

  gdk_event_request_motions (event);

  return TRUE;
}
Пример #6
0
float*
closest (float *alpha,
	 float *beta,
	 float  angle)
{
  gfloat temp_alpha = MIN (angle_mod_2PI (*alpha-angle),
                           TP - angle_mod_2PI (*alpha-angle));

  gfloat temp_beta  = MIN (angle_mod_2PI (*beta -angle),
                           TP - angle_mod_2PI (*beta -angle));

  if (temp_alpha-temp_beta < 0)
    return alpha;
  else
    return beta;
}
Пример #7
0
gboolean
rcm_motion_notify_event (GtkWidget      *widget,
			 GdkEventMotion *event,
			 RcmCircle      *circle)
{
  gfloat  clicked_angle, delta;

  clicked_angle = angle_mod_2PI (arctg (CENTER - event->y, event->x - CENTER));

  delta = clicked_angle - circle->prev_clicked;
  circle->prev_clicked = clicked_angle;

  if (delta)
    {
      if (circle->mode == EACH)
        {
          *(circle->target) = clicked_angle;
        }
      else
        {
          circle->angle->alpha = angle_mod_2PI (circle->angle->alpha + delta);
          circle->angle->beta  = angle_mod_2PI (circle->angle->beta  + delta);
        }

      gtk_widget_queue_draw (widget);
      gdk_window_process_updates (gtk_widget_get_window (widget), FALSE);

      gtk_spin_button_set_value (GTK_SPIN_BUTTON (circle->alpha_entry),
                                 circle->angle->alpha *
                                 rcm_units_factor(Current.Units));

      gtk_spin_button_set_value (GTK_SPIN_BUTTON (circle->beta_entry),
                                 circle->angle->beta *
                                 rcm_units_factor(Current.Units));

      if (Current.RealTime)
        rcm_render_preview (Current.Bna->after);
    }

  gdk_event_request_motions (event);

  return TRUE;
}
Пример #8
0
gboolean
rcm_button_press_event (GtkWidget      *widget,
			GdkEventButton *event,
			RcmCircle      *circle)
{
  float  clicked_angle;
  float *alpha;
  float *beta;

  alpha  = &circle->angle->alpha;
  beta   = &circle->angle->beta;

  circle->action_flag = DRAG_START;
  clicked_angle = angle_mod_2PI (arctg (CENTER - event->y, event->x - CENTER));
  circle->prev_clicked = clicked_angle;

  if ((sqrt (SQR (event->y - CENTER) +
             SQR (event->x - CENTER)) > RADIUS * EACH_OR_BOTH) &&
      (min_prox (*alpha, *beta, clicked_angle) < G_PI / 12))
    {
      circle->mode = EACH;
      circle->target = closest (alpha, beta, clicked_angle);

      if (*(circle->target) != clicked_angle)
        {
          GtkStyle *style = gtk_widget_get_style (widget);

          *(circle->target) = clicked_angle;
          gtk_widget_queue_draw (circle->preview);
          color_rotate_draw_arrows (widget->window,
                                    style->black_gc,
                                    circle->angle);

          gtk_spin_button_set_value (GTK_SPIN_BUTTON (circle->alpha_entry),
                                     circle->angle->alpha *
                                     rcm_units_factor(Current.Units));

          gtk_spin_button_set_value (GTK_SPIN_BUTTON (circle->beta_entry),
                                     circle->angle->beta *
                                     rcm_units_factor(Current.Units));

          if (Current.RealTime)
            rcm_render_preview (Current.Bna->after);
        }
    }
  else
    circle->mode = BOTH;

  return TRUE;
}
Пример #9
0
static void
color_rotate (GeglProperties *o,
              gfloat         *input,
              gfloat         *output)
{
  gfloat   h, s, v;
  gboolean skip = FALSE;

  rgb_to_hsv (input[0], input[1], input[2],
              &h, &s, &v);

  if (is_gray (s, o->threshold))
    {
      if (o->gray_mode == GEGL_COLOR_ROTATE_GRAY_TREAT_AS)
        {
          if (angle_inside_slice (o->hue, o->src_from, o->src_to,
                                  o->src_clockwise) <= 1)
            {
              h = DEG_TO_RAD (o->hue) / TWO_PI;
              s = o->saturation;
            }
          else
            {
              skip = TRUE;
            }
        }
      else
        {
          skip = TRUE;

          h = DEG_TO_RAD (o->hue) / TWO_PI;
          s = o->saturation;
        }
    }

  if (! skip)
    {
      h = linear (left_end (o->src_from, o->src_to, o->src_clockwise),
                  right_end (o->src_from, o->src_to, o->src_clockwise),
                  left_end (o->dest_from, o->dest_to, o->dest_clockwise),
                  right_end (o->dest_from, o->dest_to, o->dest_clockwise),
                  h * TWO_PI);

      h = angle_mod_2PI (h) / TWO_PI;
    }

  hsv_to_rgb (h, s, v,
              output, output + 1, output + 2);
}
Пример #10
0
gboolean
rcm_gray_button_press_event (GtkWidget      *widget,
			     GdkEventButton *event,
			     RcmGray        *circle)
{
  GtkStyle *style = gtk_widget_get_style (widget);
  int       x, y;

  x = event->x - GRAY_CENTER - LITTLE_RADIUS;
  y = GRAY_CENTER - event->y + LITTLE_RADIUS;

  circle->action_flag = DRAG_START;
  circle->hue         = angle_mod_2PI(arctg(y, x));
  circle->satur       = sqrt (SQR (x) + SQR (y)) / GRAY_RADIUS;

  if (circle->satur > 1.0)
    circle->satur = 1;

  gtk_widget_queue_draw (circle->preview);
  color_rotate_draw_little_circle (widget->window,
                                   style->black_gc,
                                   circle->hue, circle->satur);

  color_rotate_draw_large_circle (circle->preview->window,
                                  gtk_widget_get_style (circle->preview)->black_gc,
                                  circle->gray_sat);

  gtk_spin_button_set_value (GTK_SPIN_BUTTON (circle->hue_entry),
                             circle->hue * rcm_units_factor (Current.Units));

  gtk_spin_button_set_value (GTK_SPIN_BUTTON (circle->satur_entry),
                             circle->satur);

  if (Current.RealTime)
    rcm_render_preview (Current.Bna->after);

  return TRUE;
}
Пример #11
0
gboolean
rcm_motion_notify_event (GtkWidget      *widget,
			 GdkEventMotion *event,
			 RcmCircle      *circle)
{
  gfloat       clicked_angle, delta;
  gfloat      *alpha, *beta;
  gint         cw_ccw;
  GdkGCValues  values;

  alpha  = &(circle->angle->alpha);
  beta   = &(circle->angle->beta);
  cw_ccw = circle->angle->cw_ccw;
  delta  = angle_mod_2PI (cw_ccw * (*beta - *alpha));

  values.function = GDK_INVERT;
  xor_gc = gdk_gc_new_with_values (Current.From->preview->window,
                                   &values,
                                   GDK_GC_FUNCTION);

  clicked_angle = angle_mod_2PI (arctg (CENTER - event->y, event->x - CENTER));

  delta = clicked_angle - circle->prev_clicked;
  circle->prev_clicked = clicked_angle;

  if (delta)
    {
      if (circle->action_flag == DRAG_START)
        {
          gtk_widget_queue_draw (circle->preview);
          circle->action_flag = DRAGING;
        }
      else
        {
          /* this should be erasing entire angle */
          color_rotate_draw_arrows (widget->window, xor_gc, circle->angle);
        }

      if (circle->mode == EACH)
        {
          *(circle->target)=clicked_angle;
        }
      else
        {
          circle->angle->alpha=angle_mod_2PI(circle->angle->alpha + delta);
          circle->angle->beta =angle_mod_2PI(circle->angle->beta  + delta);
        }

      gdk_window_process_updates (widget->window, FALSE);
      color_rotate_draw_arrows (widget->window, xor_gc, circle->angle);

      gtk_spin_button_set_value (GTK_SPIN_BUTTON (circle->alpha_entry),
                                 circle->angle->alpha *
                                 rcm_units_factor(Current.Units));

      gtk_spin_button_set_value (GTK_SPIN_BUTTON (circle->beta_entry),
                                 circle->angle->beta *
                                 rcm_units_factor(Current.Units));

      if (Current.RealTime)
        rcm_render_preview (Current.Bna->after);
    }

  gdk_event_request_motions (event);

  return TRUE;
}
Пример #12
0
static void
color_rotate_row (const guchar *src_row,
                  guchar       *dest_row,
                  gint          row,
                  gint          row_width,
                  gint          bytes)
{
  gint     col, bytenum;
  gdouble  H, S, V;
  guchar   rgb[3];

  for (col = 0; col < row_width; col++)
    {
      gboolean skip = FALSE;

      rgb[0] = src_row[col * bytes + 0];
      rgb[1] = src_row[col * bytes + 1];
      rgb[2] = src_row[col * bytes + 2];

      gimp_rgb_to_hsv4 (rgb, &H, &S, &V);

      if (rcm_is_gray (S))
        {
          if (Current.Gray_to_from == GRAY_FROM)
            {
              if (rcm_angle_inside_slice (Current.Gray->hue,
                                          Current.From->angle) <= 1)
                {
                  H = Current.Gray->hue / TP;
                  S = Current.Gray->satur;
                }
              else
                {
                  skip = TRUE;
                }
            }
          else
            {
              skip = TRUE;
              gimp_hsv_to_rgb4 (rgb, Current.Gray->hue / TP,
                                Current.Gray->satur, V);
            }
        }

      if (! skip)
        {
          H = rcm_linear (rcm_left_end (Current.From->angle),
                          rcm_right_end (Current.From->angle),
                          rcm_left_end (Current.To->angle),
                          rcm_right_end (Current.To->angle),
                          H * TP);

          H = angle_mod_2PI (H) / TP;
          gimp_hsv_to_rgb4 (rgb, H, S, V);
        }

      dest_row[col * bytes + 0] = rgb[0];
      dest_row[col * bytes + 1] = rgb[1];
      dest_row[col * bytes + 2] = rgb[2];

      if (bytes > 3)
        {
          for (bytenum = 3; bytenum < bytes; bytenum++)
            dest_row[col * bytes + bytenum] = src_row[col * bytes + bytenum];
        }
    }
}
Пример #13
0
void
rcm_draw_arrows (GdkWindow *window,
		 GdkGC     *color,
		 RcmAngle  *angle)
{
  gint   dist;
  gfloat alpha, beta, cw_ccw, delta;

  alpha  = angle->alpha;
  beta   = angle->beta;
  cw_ccw = angle->cw_ccw;
  delta  = angle_mod_2PI(beta - alpha);

  if (cw_ccw == -1)
    delta = delta - TP;

  gdk_draw_line (window,color,
                 CENTER,
                 CENTER,
                 ROUND (CENTER + RADIUS * cos(alpha)),
                 ROUND (CENTER - RADIUS * sin(alpha)));

  gdk_draw_line( window,color,
                 CENTER + RADIUS * cos(alpha),
                 CENTER - RADIUS * sin(alpha),
                 ROUND (CENTER + RADIUS * REL * cos(alpha - DEL)),
                 ROUND (CENTER - RADIUS * REL * sin(alpha - DEL)));

  gdk_draw_line (window,color,
                 CENTER + RADIUS * cos(alpha),
                 CENTER - RADIUS * sin(alpha),
                 ROUND (CENTER + RADIUS * REL * cos(alpha + DEL)),
                 ROUND (CENTER - RADIUS * REL * sin(alpha + DEL)));

  gdk_draw_line (window,color,
                 CENTER,
                 CENTER,
                 ROUND (CENTER + RADIUS * cos(beta)),
                 ROUND (CENTER - RADIUS * sin(beta)));

  gdk_draw_line (window,color,
                 CENTER + RADIUS * cos(beta),
                 CENTER - RADIUS * sin(beta),
                 ROUND (CENTER + RADIUS * REL * cos(beta - DEL)),
                 ROUND (CENTER - RADIUS * REL * sin(beta - DEL)));

  gdk_draw_line (window,color,
                 CENTER + RADIUS * cos(beta),
                 CENTER - RADIUS * sin(beta),
                 ROUND (CENTER + RADIUS * REL * cos(beta + DEL)),
                 ROUND (CENTER - RADIUS * REL * sin(beta + DEL)));

  dist   = RADIUS * EACH_OR_BOTH;

  gdk_draw_line (window,color,
                 CENTER + dist * cos(beta),
                 CENTER - dist * sin(beta),
                 ROUND (CENTER + dist * cos(beta) + cw_ccw * TICK * sin(beta)),
                 ROUND (CENTER - dist * sin(beta) + cw_ccw * TICK * cos(beta)));

  alpha *= 180 * 64 / G_PI;
  delta *= 180 * 64 / G_PI;

  gdk_draw_arc (window, color, 0, CENTER - dist, CENTER - dist,
		2*dist, 2*dist,	alpha, delta);
}
Пример #14
0
/* render before/after preview */
void
rcm_render_preview (GtkWidget *preview)
{
  ReducedImage *reduced;
  gint          version;
  gint          RW, RH, bytes, i, j;
  guchar       *a;
  guchar       *rgb_array;
  gdouble      *hsv_array;
  gfloat        degree;

  g_return_if_fail (preview != NULL);

  version = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (preview), "mode"));

  reduced   = Current_c.reduced;
  RW        = reduced->width;
  RH        = reduced->height;
  bytes     = Current_c.drawable->bpp;
  hsv_array = reduced->hsv;
  rgb_array = reduced->rgb;

  a = g_new (guchar, 4 * RW * RH);

  if (version == CURRENT)
    {
      gdouble H, S, V;
      guchar  rgb[3];

      for (i = 0; i < RH; i++)
        {
          for (j = 0; j < RW; j++)
            {
              gboolean unchanged = FALSE;
              gboolean skip      = FALSE;

              H = hsv_array[i*RW*bytes + j*bytes + 0];
              S = hsv_array[i*RW*bytes + j*bytes + 1];
              V = hsv_array[i*RW*bytes + j*bytes + 2];

              if (rcm_is_gray(S) && (reduced->mask[i*RW+j] != 0))
                {
                  switch (Current_c.Gray_to_from)
                    {
                    case GRAY_FROM:
                      if (rcm_angle_inside_slice (Current_c.Gray->hue,
                                                  Current_c.From->angle) <= 1)
                        {
                          H = Current_c.Gray->hue/TP;
                          S = Current_c.Gray->satur;
                        }
                      else
                        skip = TRUE;
                      break;

                    case GRAY_TO:
                      unchanged = FALSE;
                      skip = TRUE;
                      gimp_hsv_to_rgb4 (rgb,
                                        Current_c.Gray->hue/TP,
                                        Current_c.Gray->satur,
                                        V);
                      break;

                    default:
                      break;
                    }
                }

              if (!skip)
                {
                  unchanged = FALSE;
                  H = rcm_linear (rcm_left_end (Current_c.From->angle),
                                  rcm_right_end (Current_c.From->angle),
                                  rcm_left_end (Current_c.To->angle),
                                  rcm_right_end (Current_c.To->angle),
                                  H * TP);

                  H = angle_mod_2PI(H) / TP;
                  gimp_hsv_to_rgb4 (rgb, H,S,V);
                }

              if (unchanged)
                degree = 0;
              else
                degree = reduced->mask[i*RW+j] / 255.0;

              a[(i*RW+j)*4+0] = (1-degree) * rgb_array[i*RW*bytes + j*bytes + 0] + degree * rgb[0];
              a[(i*RW+j)*4+1] = (1-degree) * rgb_array[i*RW*bytes + j*bytes + 1] + degree * rgb[1];
              a[(i*RW+j)*4+2] = (1-degree) * rgb_array[i*RW*bytes + j*bytes + 2] + degree * rgb[2];

              /* apply transparency */
              if (bytes == 4)
                a[(i*RW+j)*4+3] = rgb_array[i*RW*bytes+j*bytes+3];
              else
                a[(i*RW+j)*4+3] = 255;
            }
        }
    }
  else /* ORIGINAL */
    {
      for (i = 0; i < RH; i++)
        {
          for (j = 0; j < RW; j++)
            {
              a[(i*RW+j)*4+0] = rgb_array[i*RW*bytes + j*bytes + 0];
              a[(i*RW+j)*4+1] = rgb_array[i*RW*bytes + j*bytes + 1];
              a[(i*RW+j)*4+2] = rgb_array[i*RW*bytes + j*bytes + 2];

              if (bytes == 4)
                a[(i*RW+j)*4+3] = rgb_array[i*RW*bytes+j*bytes+3];
              else
                a[(i*RW+j)*4+3] = 255;
            }
        }
    }

  gimp_preview_area_draw (GIMP_PREVIEW_AREA (preview),
                          0, 0, RW, RH,
                          GIMP_RGBA_IMAGE,
                          a,
                          RW * 4);
  g_free (a);
}