Skip to content

Commit

Permalink
Crop module gets orientation proxy support
Browse files Browse the repository at this point in the history
While developing an image in darkroom we might have set a cropping area, this commit
implements functionality to keep the cropped area if we change orientation via the
flip module.
Three parts in the codebase required additions without changing existing code.

1. `dt_develop_t` got two additions in cropping proxy,
   `struct dt_iop_module_t *flip_handler` points to the crop module and is setup there.
      We can't use `exposer` as the proxy because that is dynamically set in pixelpipe code
      only if enabled and we want to change crop parameters even if crop is disabled.
   `void (*flip_callback)` is the callback function changing crop parameters, defined in crop.

2. Orientation module uses the `flip_callback(self, orientation)` requesting changes in crop.

3. In crop we have `_crop_handle_flip()` as proxy `flip_callback` with proper logs about action.
   - It gets the data from self `dt_iop_crop_params_t`,
   - does the requested action,
   - updates gui from parameters
   - adds a new history stack entry (respecting the current `crop->enabled` status).
  • Loading branch information
jenshannoschwalm committed Nov 27, 2024
1 parent 6fe9931 commit 12e3a19
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 2 deletions.
7 changes: 6 additions & 1 deletion src/develop/develop.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,11 +289,16 @@ typedef struct dt_develop_t

dt_dev_chroma_t chroma;

// for exposing the crop
// for exposing and handling the crop
struct
{
// set by dt_dev_pixelpipe_synch() if an enabled crop module is included in history
struct dt_iop_module_t *exposer;

// proxy to change crop settings via flip module
struct dt_iop_module_t *flip_handler;
void (*flip_callback)(struct dt_iop_module_t *crop,
const dt_image_orientation_t flipmode);
} cropping;

// for the overexposure indicator
Expand Down
34 changes: 34 additions & 0 deletions src/iop/crop.c
Original file line number Diff line number Diff line change
Expand Up @@ -1117,6 +1117,37 @@ static gchar *_aspect_format(gchar *original,
return g_strdup_printf("%s %4.2f", original, (float)adim / (float)bdim);
}

static void _crop_handle_flip(dt_iop_module_t *self, const dt_image_orientation_t mode)
{
dt_iop_crop_params_t *p = self ? self->params : NULL;
if(!p) return;

// we avoid action if default or fully symmetrical
const gboolean no_action = (p->cx == 1.f - p->ch) && (p->cy == 1.f - p->cw);

dt_print(DT_DEBUG_PIPE, "[crop_handle_flip] origin: %1.3f %1.3f %1.3f %1.3f mode=%s%s%s",
p->cx, 1.0f - p->cw, p->cy, 1.0f - p->ch,
mode == ORIENTATION_ROTATE_CW_90_DEG ? "ROTATE_CW_90_DEG"
: mode == ORIENTATION_ROTATE_CCW_90_DEG ? "ROTATE_CCW_90_DEG"
: mode == ORIENTATION_FLIP_HORIZONTALLY ? "FLIP_HORIZONTALLY"
: mode == ORIENTATION_FLIP_VERTICALLY ? "FLIP_VERTICALLY"
: "UNKNOWN",
self->enabled ? "" : ", crop disabled",
no_action ? ", no action": "");

if(no_action) return;

const float ocx = p->cx;
const float ocy = p->cy;
if(mode == ORIENTATION_FLIP_HORIZONTALLY) {p->cx = 1.f-p->cw; p->cw = 1.f-ocx;}
else if(mode == ORIENTATION_FLIP_VERTICALLY) {p->cy = 1.f-p->ch; p->ch = 1.f-ocy;}
else if(mode == ORIENTATION_ROTATE_CW_90_DEG) {p->cx = 1.f-p->ch; p->ch = p->cw; p->cw = 1.f-p->cy; p->cy = ocx;}
else if(mode == ORIENTATION_ROTATE_CCW_90_DEG) {p->cx = p->cy; p->cy = 1.f-p->cw; p->cw = p->ch; p->ch = 1.f-ocx;}

dt_iop_gui_update(self);
dt_dev_add_history_item(darktable.develop, self, self->enabled);
}

void gui_init(dt_iop_module_t *self)
{
dt_iop_crop_gui_data_t *g = IOP_GUI_ALLOC(crop);
Expand Down Expand Up @@ -1308,6 +1339,9 @@ void gui_init(dt_iop_module_t *self)
_("the bottom margin cannot overlap with the top margin"));

self->widget = box_enabled;

darktable.develop->cropping.flip_handler = self;
darktable.develop->cropping.flip_callback = _crop_handle_flip;
}

static void _aspect_free(gpointer data)
Expand Down
13 changes: 12 additions & 1 deletion src/iop/flip.c
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ void commit_params(dt_iop_module_t *self,
d->orientation = p->orientation;

if(d->orientation == ORIENTATION_NONE)
piece->enabled = 0;
piece->enabled = FALSE;
}

void init_pipe(dt_iop_module_t *self,
Expand Down Expand Up @@ -518,6 +518,14 @@ void reload_defaults(dt_iop_module_t *self)
}
}

static void _crop_callback(const int mode)
{
dt_develop_t *dev = darktable.develop;
dt_iop_module_t *cropper = dev->cropping.flip_handler;
if(cropper && dev->cropping.flip_callback)
dev->cropping.flip_callback(cropper, mode);
}

static void do_rotate(dt_iop_module_t *self, uint32_t cw)
{
dt_iop_flip_params_t *p = self->params;
Expand All @@ -544,6 +552,7 @@ static void do_rotate(dt_iop_module_t *self, uint32_t cw)

p->orientation = orientation;
dt_dev_add_history_item(darktable.develop, self, TRUE);
_crop_callback(cw ? ORIENTATION_ROTATE_CW_90_DEG : ORIENTATION_ROTATE_CCW_90_DEG);
}

static void rotate_cw(GtkWidget *widget, dt_iop_module_t *self)
Expand All @@ -570,6 +579,7 @@ static void _flip_h(GtkWidget *widget, dt_iop_module_t *self)
p->orientation = orientation ^ ORIENTATION_FLIP_HORIZONTALLY;

dt_dev_add_history_item(darktable.develop, self, TRUE);
_crop_callback(ORIENTATION_FLIP_HORIZONTALLY);
}

static void _flip_v(GtkWidget *widget, dt_iop_module_t *self)
Expand All @@ -587,6 +597,7 @@ static void _flip_v(GtkWidget *widget, dt_iop_module_t *self)
p->orientation = orientation ^ ORIENTATION_FLIP_VERTICALLY;

dt_dev_add_history_item(darktable.develop, self, TRUE);
_crop_callback(ORIENTATION_FLIP_VERTICALLY);
}

void gui_init(dt_iop_module_t *self)
Expand Down

0 comments on commit 12e3a19

Please sign in to comment.