f.edit.cc (fotoxx-23.0) | : | f.edit.cc (fotoxx-23.1) | ||
---|---|---|---|---|
/******************************************************************************* * | /******************************************************************************* * | |||
Fotoxx edit photos and manage collections | Fotoxx - edit photos and manage collections | |||
Copyright 2007-2023 Michael Cornelison | Copyright 2007-2023 Michael Cornelison | |||
source code URL: https://kornelix.net | source code URL: https://kornelix.net | |||
contact: mkornelix@gmail.com | contact: mkornelix@gmail.com | |||
This program is free software: you can redistribute it and/or modify | This program is free software: you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation, either version 3 of the License, or | the Free Software Foundation, either version 3 of the License, or | |||
(at your option) any later version. See https://www.gnu.org/licenses | (at your option) any later version. See https://www.gnu.org/licenses | |||
skipping to change at line 30 | skipping to change at line 30 | |||
Fotoxx image edit - Edit menu functions | Fotoxx image edit - Edit menu functions | |||
get_edit_pixels get pixels from image, area, mouse | get_edit_pixels get pixels from image, area, mouse | |||
m_paint_edits set up edit via mouse painting | m_paint_edits set up edit via mouse painting | |||
m_rotate rotate or level an image | m_rotate rotate or level an image | |||
m_crop crop image margins | m_crop crop image margins | |||
m_retouch brightness, contrast, color ... | m_retouch brightness, contrast, color ... | |||
blackbodyRGB convert deg. K to RGB factors | blackbodyRGB convert deg. K to RGB factors | |||
m_resize resize (rescale) image | m_resize resize (rescale) image | |||
m_upright auto upright based on EXIF orientation data | m_upright auto upright based on metadata orientation | |||
m_mirror horizontal or vertical mirror image | m_mirror horizontal or vertical mirror image | |||
m_markup draw on image image: text, line, box, oval | m_markup draw on image image: text, line, box, oval | |||
m_draw_text draw text on image | m_draw_text draw text on image | |||
m_draw_line draw line/arrow on image | m_draw_line draw line/arrow on image | |||
m_draw_box draw box on image | m_draw_box draw box on image | |||
m_draw_oval draw oval on image | m_draw_oval draw oval on image | |||
m_color_mode convert: B&W, color, sepia, positive, negative | m_color_mode convert: B&W, color, sepia, positive, negative | |||
m_paint_image paint on the image with a color | m_paint_image paint on the image with a color | |||
RGB_chooser select RGB color or use color chooser file | RGB_chooser select RGB color or use color chooser file | |||
HSL_chooser select HSL color | HSL_chooser select HSL color | |||
skipping to change at line 91 | skipping to change at line 91 | |||
subsequent calls (pixel processing loop) | subsequent calls (pixel processing loop) | |||
stat = get_edit_pixels(int thread, int &px, int &py, float &blend) | stat = get_edit_pixels(int thread, int &px, int &py, float &blend) | |||
stat = 0 next pixel is returned | stat = 0 next pixel is returned | |||
1 finished, no more pixels | 1 finished, no more pixels | |||
****/ | ****/ | |||
namespace get_edit_pixels_names | namespace get_edit_pixels_names | |||
{ | { | |||
int Nt; | int Nt; | |||
int FTF[max_threads]; | int FTF[NWT]; | |||
int Eww, Ehh; | int Eww, Ehh; | |||
int pxlo, pxhi, pylo, pyhi; | int pxlo, pxhi, pylo, pyhi; | |||
float Cpow, Epow; | float Cpow, Epow; | |||
} | } | |||
// setups for returning pixels to the edit threads | // setups for returning pixels to the edit threads | |||
void get_edit_pixels_init(int Nthreads, int margin) | void get_edit_pixels_init(int Nthreads, int margin) | |||
{ | { | |||
using namespace get_edit_pixels_names; | using namespace get_edit_pixels_names; | |||
int cc; | int cc; | |||
if (! CEF) zappcrash("no edit function active"); | if (! CEF) zappcrash("no edit function active"); | |||
if (! E3pxm) zappcrash("no E3pxm"); | if (! E3pxm) zappcrash("no E3pxm"); | |||
cc = max_threads * sizeof(int); // set first time flags for all threads | cc = NWT * sizeof(int); // set first time flags for all threads | |||
memset(FTF,1,cc); | memset(FTF,1,cc); | |||
if (! Nthreads) return; // re-initz. same area | if (! Nthreads) return; // re-initz. same area | |||
Nt = Nthreads; // edit thread count | Nt = Nthreads; // edit thread count | |||
Eww = E3pxm->ww; | Eww = E3pxm->ww; | |||
Ehh = E3pxm->hh; | Ehh = E3pxm->hh; | |||
if (Fpaintedits) // paint_edit() is active, | if (Fpaintedits) // paint_edit() is active, | |||
skipping to change at line 276 | skipping to change at line 276 | |||
hh = pyhi - pylo; | hh = pyhi - pylo; | |||
PXM_copy_area(pxm1,pxm2,pxlo,pylo,ww,hh); | PXM_copy_area(pxm1,pxm2,pxlo,pylo,ww,hh); | |||
return; | return; | |||
} | } | |||
/******************************************************************************* */ | /******************************************************************************* */ | |||
// Current edit function is applied to areas painted with the mouse. | // Current edit function is applied to areas painted with the mouse. | |||
// Mouse can be weak or strong, and edits are applied incrementally. | // Mouse can be weak or strong, and edits are applied incrementally. | |||
void m_paint_edits(GtkWidget *, cchar *) // menu function | void m_paint_edits(GtkWidget *, ch *) // menu function | |||
{ | { | |||
int paint_edits_dialog_event(zdialog *, cchar *event); // dialog event function | int paint_edits_dialog_event(zdialog *, ch *event); // dialog event function | |||
void paint_edits_mousefunc(); // mouse function | void paint_edits_mousefunc(); // mouse function | |||
cchar *title = "Paint Edits"; | ch *title = "Paint Edits"; | |||
F1_help_topic = "paint edits"; | F1_help_topic = "paint edits"; | |||
Plog(1,"m_paint_edits \n"); | Plog(1,"m_paint_edits \n"); | |||
if (! CEF) { // edit func must be active | if (! CEF) { // edit func must be active | |||
zmessageACK(Mwin,"Edit function must be active"); | zmessageACK(Mwin,"Edit function must be active"); | |||
return; | return; | |||
} | } | |||
skipping to change at line 346 | skipping to change at line 346 | |||
zdialog_fetch(zd,"edge",MEpower); | zdialog_fetch(zd,"edge",MEpower); | |||
zdialog_run(zd,paint_edits_dialog_event,"save"); // run dialog - parallel | zdialog_run(zd,paint_edits_dialog_event,"save"); // run dialog - parallel | |||
Fpaintedits = 1; | Fpaintedits = 1; | |||
return; | return; | |||
} | } | |||
// dialog event and completion function | // dialog event and completion function | |||
int paint_edits_dialog_event(zdialog *zd, cchar *event) | int paint_edits_dialog_event(zdialog *zd, ch *event) | |||
{ | { | |||
void paint_edits_mousefunc(); // mouse function | void paint_edits_mousefunc(); // mouse function | |||
if (strmatch(event,"escape")) zd->zstat = -2; // escape key | if (strmatch(event,"escape")) zd->zstat = -2; // escape key | |||
if (strmatch(event,"focus")) // toggle mouse capture | if (strmatch(event,"focus")) // toggle mouse capture | |||
{ | { | |||
if (CEF && CEF->Fpaintedits) { // check edit function OK | if (CEF && CEF->Fpaintedits) { // check edit function OK | |||
takeMouse(paint_edits_mousefunc,0); | takeMouse(paint_edits_mousefunc,0); | |||
Fpaintedits = 1; | Fpaintedits = 1; | |||
skipping to change at line 426 | skipping to change at line 426 | |||
editfunc EFrotateimage; | editfunc EFrotateimage; | |||
zdialog *zd; | zdialog *zd; | |||
double Zratio; // E0 size / E3 size >= 1.0 | double Zratio; // E0 size / E3 size >= 1.0 | |||
double rotate_goal, rotate_angle; // target and actual rotation | double rotate_goal, rotate_angle; // target and actual rotation | |||
int E0ww, E0hh, E3ww, E3hh; // full size image and preview size | int E0ww, E0hh, E3ww, E3hh; // full size image and preview size | |||
int Ftimer1; | int Ftimer1; | |||
double Ftimer2; | double Ftimer2; | |||
int timerfunc(void *); | int timerfunc(void *); | |||
int dialog_event(zdialog *zd, cchar *event); | int dialog_event(zdialog *zd, ch *event); | |||
void mousefunc(); | void mousefunc(); | |||
void KBfunc(int key); | void KBfunc(int key); | |||
void rotate_final(); | void rotate_final(); | |||
void rotate_func(int fast); | void rotate_func(int fast); | |||
void drawlines(cairo_t *cr); | void drawlines(cairo_t *cr); | |||
} | } | |||
// menu function | // menu function | |||
void m_rotate(GtkWidget *, cchar *menu) | void m_rotate(GtkWidget *, ch *menu) | |||
{ | { | |||
using namespace rotate_names; | using namespace rotate_names; | |||
cchar *rotate_message = "Drag on image to level image.\n" | ch *rotate_message = "Drag on image to level image.\n" | |||
"Click on image for level lines."; | "Click on image for level lines."; | |||
F1_help_topic = "rotate"; | F1_help_topic = "rotate"; | |||
Plog(1,"m_rotate \n"); | Plog(1,"m_rotate \n"); | |||
EFrotateimage.menufunc = m_rotate; // menu function | EFrotateimage.menufunc = m_rotate; // menu function | |||
EFrotateimage.menuname = "Rotate"; | EFrotateimage.menuname = "Rotate"; | |||
EFrotateimage.Frestart = 1; // allow restart | EFrotateimage.Frestart = 1; // allow restart | |||
EFrotateimage.mousefunc = mousefunc; | EFrotateimage.mousefunc = mousefunc; | |||
EFrotateimage.FprevReq = 1; // use preview (small) size | EFrotateimage.FprevReq = 1; // use preview (small) size | |||
skipping to change at line 499 | skipping to change at line 499 | |||
zdialog_add_widget(zd,"hbox","hbrot","dialog"); | zdialog_add_widget(zd,"hbox","hbrot","dialog"); | |||
zdialog_add_widget(zd,"label","labrotate","hbrot","Rotate Degrees:","space=5" ); | zdialog_add_widget(zd,"label","labrotate","hbrot","Rotate Degrees:","space=5" ); | |||
zdialog_add_widget(zd,"zspin","degrees","hbrot","-180|180|0.1|0"); | zdialog_add_widget(zd,"zspin","degrees","hbrot","-180|180|0.1|0"); | |||
zdialog_add_widget(zd,"imagebutt","-90","hbrot","rotate-left.png","size=32|sp ace=12"); | zdialog_add_widget(zd,"imagebutt","-90","hbrot","rotate-left.png","size=32|sp ace=12"); | |||
zdialog_add_widget(zd,"imagebutt","+90","hbrot","rotate-right.png","size=32") ; | zdialog_add_widget(zd,"imagebutt","+90","hbrot","rotate-right.png","size=32") ; | |||
zdialog_add_widget(zd,"hbox","hbauto","dialog",0,"space=5"); | zdialog_add_widget(zd,"hbox","hbauto","dialog",0,"space=5"); | |||
zdialog_add_widget(zd,"button","level","hbauto","Auto Level","space=10"); | zdialog_add_widget(zd,"button","level","hbauto","Auto Level","space=10"); | |||
zdialog_add_widget(zd,"button","upright","hbauto","Auto Upright","space=8"); | zdialog_add_widget(zd,"button","upright","hbauto","Auto Upright","space=8"); | |||
zdialog_add_ttip(zd,"level","use EXIF data if available"); | zdialog_add_ttip(zd,"level","use metadata if available"); | |||
zdialog_add_ttip(zd,"upright","use EXIF data if available"); | zdialog_add_ttip(zd,"upright","use metadata if available"); | |||
takeMouse(mousefunc,dragcursor); // connect mouse function | takeMouse(mousefunc,dragcursor); // connect mouse function | |||
Fzoom = 0; | Fzoom = 0; | |||
zdialog_run(zd,dialog_event,"save"); // run dialog - parallel | zdialog_run(zd,dialog_event,"save"); // run dialog - parallel | |||
g_timeout_add(100,timerfunc,0); // start rotate watchdog | g_timeout_add(100,timerfunc,0); // start rotate watchdog | |||
Ftimer1 = 1; // rotate() active | Ftimer1 = 1; // rotate() active | |||
Ftimer2 = 0; // rotate fix pending | Ftimer2 = 0; // rotate fix pending | |||
skipping to change at line 530 | skipping to change at line 530 | |||
if (! Ftimer2) return 1; // nothing pending | if (! Ftimer2) return 1; // nothing pending | |||
if (get_seconds() - Ftimer2 < 1.0) return 1; // < 1 sec. since last rotate | if (get_seconds() - Ftimer2 < 1.0) return 1; // < 1 sec. since last rotate | |||
Ftimer2 = 0; // reset pending flag | Ftimer2 = 0; // reset pending flag | |||
rotate_angle = 0; | rotate_angle = 0; | |||
rotate_func(0); // high quality rotate | rotate_func(0); // high quality rotate | |||
return 1; | return 1; | |||
} | } | |||
// dialog event and completion callback function | // dialog event and completion callback function | |||
int rotate_names::dialog_event(zdialog *zd, cchar *event) | int rotate_names::dialog_event(zdialog *zd, ch *event) | |||
{ | { | |||
using namespace rotate_names; | using namespace rotate_names; | |||
int angle = 0, Fcrop = 0; | int angle = 0, Fcrop = 0; | |||
cchar *exifkey[1]; | ch *metakey[1]; | |||
char *ppv[1]; | ch *ppv[1]; | |||
if (strmatch(event,"escape")) zd->zstat = -2; // escape key | if (strmatch(event,"escape")) zd->zstat = -2; // escape key | |||
if (strmatch(event,"done")) zd->zstat = 2; // apply and quit | if (strmatch(event,"done")) zd->zstat = 2; // apply and quit | |||
if (strmatch(event,"cancel")) zd->zstat = 3; // cancel | if (strmatch(event,"cancel")) zd->zstat = 3; // cancel | |||
if (strmatch(event,"undo")) // 'undo' button was used | if (strmatch(event,"undo")) // 'undo' button was used | |||
{ | { | |||
Ftimer1 = Ftimer2 = 0; // stop watchdog timer | Ftimer1 = Ftimer2 = 0; // stop watchdog timer | |||
Ntoplines = 0; // remove leveling lines | Ntoplines = 0; // remove leveling lines | |||
edit_cancel(0); | edit_cancel(0); | |||
skipping to change at line 609 | skipping to change at line 609 | |||
if (strmatch(event,"-90")) // 90 deg. CCW | if (strmatch(event,"-90")) // 90 deg. CCW | |||
rotate_goal -= 90; | rotate_goal -= 90; | |||
if (rotate_goal > 180) rotate_goal -= 360; // keep within -180 to +180 deg. | if (rotate_goal > 180) rotate_goal -= 360; // keep within -180 to +180 deg. | |||
if (rotate_goal < -180) rotate_goal += 360; | if (rotate_goal < -180) rotate_goal += 360; | |||
if (fabs(rotate_goal) < 0.01) rotate_goal = 0; // = 0 within my precision | if (fabs(rotate_goal) < 0.01) rotate_goal = 0; // = 0 within my precision | |||
zdialog_stuff(zd,"degrees",rotate_goal); | zdialog_stuff(zd,"degrees",rotate_goal); | |||
rotate_func(0); // high quality rotate | rotate_func(0); // high quality rotate | |||
Fupright = 1; // mark uprighted (for EXIF update) | Fupright = 1; // mark uprighted (for metadata update) | |||
} | } | |||
if (strmatch(event,"upright")) // auto upright button | if (strmatch(event,"upright")) // auto upright button | |||
{ | { | |||
exifkey[0] = exif_orientation_key; | metakey[0] = (ch *) meta_orientation_key; | |||
exif_get(curr_file,exifkey,ppv,1); | meta_get1(curr_file,metakey,ppv,1); | |||
// get EXIF: Orientation | // get metadata Orientation | |||
if (! ppv[0]) { | if (! ppv[0]) { | |||
zmessageACK(Mwin,"no EXIF rotation data"); | zmessageACK(Mwin,"no rotation metadata"); | |||
return 1; | return 1; | |||
} | } | |||
if (*ppv[0] == '6') angle = +90; // rotate clockwise 90 deg. | if (*ppv[0] == '6') angle = +90; // rotate clockwise 90 deg. | |||
if (*ppv[0] == '8') angle = -90; // counterclockwise 90 deg. | if (*ppv[0] == '8') angle = -90; // counterclockwise 90 deg. | |||
if (*ppv[0] == '3') angle = 180; // 180 deg. | if (*ppv[0] == '3') angle = 180; // 180 deg. | |||
zfree(ppv[0]); | zfree(ppv[0]); | |||
rotate_goal += angle; | rotate_goal += angle; | |||
rotate_func(0); // high quality rotate | rotate_func(0); // high quality rotate | |||
Fupright = 1; | Fupright = 1; | |||
// mark uprighted (for EXIF update) | // mark uprighted (for metadata update) | |||
Flevel = 1; | Flevel = 1; | |||
// mark levelled (for EXIF update) | // mark levelled (for metadata update) | |||
} | } | |||
if (strmatch(event,"degrees")) // rotate action | if (strmatch(event,"degrees")) // rotate action | |||
{ | { | |||
zdialog_fetch(zd,"degrees",rotate_goal); | zdialog_fetch(zd,"degrees",rotate_goal); | |||
if (rotate_goal > 180) rotate_goal -= 360; // keep within -180 to +180 deg. | if (rotate_goal > 180) rotate_goal -= 360; // keep within -180 to +180 deg. | |||
if (rotate_goal < -180) rotate_goal += 360; | if (rotate_goal < -180) rotate_goal += 360; | |||
if (fabs(rotate_goal) < 0.01) rotate_goal = 0; // = 0 within my precision | if (fabs(rotate_goal) < 0.01) rotate_goal = 0; // = 0 within my precision | |||
zdialog_stuff(zd,"degrees",rotate_goal); | zdialog_stuff(zd,"degrees",rotate_goal); | |||
rotate_func(1); // fast low quality rotate | rotate_func(1); // fast low quality rotate | |||
Flevel = 1; // mark levelled (for EXIF update) | Flevel = 1; // mark levelled (for metadata update) | |||
} | } | |||
if (strmatch(event,"level")) // auto level using EXIF RollAngle | if (strmatch(event,"level")) // auto level using metadata RollAngle | |||
{ | { | |||
exifkey[0] = exif_rollangle_key; | metakey[0] = (ch *) meta_rollangle_key; | |||
exif_get(curr_file,exifkey,ppv,1); | meta_get1(curr_file,metakey,ppv,1); | |||
if (! ppv[0]) { | if (! ppv[0]) { | |||
zmessageACK(Mwin,"no EXIF level data"); | zmessageACK(Mwin,"no metadata level data"); | |||
return 1; | return 1; | |||
} | } | |||
rotate_goal = atofz(ppv[0]); | rotate_goal = atofz(ppv[0]); | |||
zfree(ppv[0]); | zfree(ppv[0]); | |||
rotate_func(0); // high quality rotate | rotate_func(0); // high quality rotate | |||
Flevel = 1; // mark levelled (for EXIF update) | Flevel = 1; // mark levelled (for metadata update) | |||
} | } | |||
return 1; | return 1; | |||
} | } | |||
// rotate image mouse function | // rotate image mouse function | |||
void rotate_names::mousefunc() | void rotate_names::mousefunc() | |||
{ | { | |||
using namespace rotate_names; | using namespace rotate_names; | |||
skipping to change at line 776 | skipping to change at line 776 | |||
Fbusy = 0; | Fbusy = 0; | |||
return; | return; | |||
} | } | |||
/******************************************************************************* */ | /******************************************************************************* */ | |||
// crop an image (trim margins) | // crop an image (trim margins) | |||
// | // | |||
// fotoxx.h | // fotoxx.h | |||
// int cropx1, cropy1, cropx2, cropy2; // crop rectangle (calling function) | // int cropx1, cropy1, cropx2, cropy2; // crop rectangle (calling function) | |||
// char *cropsizes[10]; | // ch *cropsizes[10]; | |||
// previous crop sizes "NNNNxNNNN" | // previous crop sizes "NNNNxNNNN" | |||
// char *cropbuttons[5]; | // ch *cropbuttons[5]; | |||
// crop dialog button labels | // crop dialog button labels | |||
// char *cropratios[5]; | // ch *cropratios[5]; | |||
// corresponding aspect ratios | // corresponding aspect ratios | |||
namespace crop_names | namespace crop_names | |||
{ | { | |||
editfunc EFcrop; | editfunc EFcrop; | |||
zdialog *zd; | zdialog *zd; | |||
int pcropx1, pcropy1, pcropx2, pcropy2; // prior crop rectangle | int pcropx1, pcropy1, pcropx2, pcropy2; // prior crop rectangle | |||
int cropww, crophh; // crop rectangle width and height | int cropww, crophh; // crop rectangle width and height | |||
int Rlock; // lock width/height ratio | int Rlock; // lock width/height ratio | |||
int Rauto; // margin confine with ratio locked | int Rauto; // margin confine with ratio locked | |||
int E0ww, E0hh, E3ww, E3hh; // full size image and preview size | int E0ww, E0hh, E3ww, E3hh; // full size image and preview size | |||
int Fcorner, Fside, Fmoveall; | int Fcorner, Fside, Fmoveall; | |||
int KBcorner, KBside; | int KBcorner, KBside; | |||
double cropR; // crop ratio, width/height | double cropR; // crop ratio, width/height | |||
double Zratio; // full / preview size >= 1.0 | double Zratio; // full / preview size >= 1.0 | |||
int dialog_event(zdialog *zd, cchar *event); | int dialog_event(zdialog *zd, ch *event); | |||
void prevcrop_menu_event(GtkWidget *, cchar *menu); | void prevcrop_menu_event(GtkWidget *, ch *menu); | |||
void update_prev_cropsize(); | void update_prev_cropsize(); | |||
void mousefunc(); | void mousefunc(); | |||
void KBfunc(int key); | void KBfunc(int key); | |||
void crop_limits(); | void crop_limits(); | |||
void crop_darkmargins(); | void crop_darkmargins(); | |||
void crop_final(); | void crop_final(); | |||
void drawlines(cairo_t *cr); | void drawlines(cairo_t *cr); | |||
void autocrop_max(); | void autocrop_max(); | |||
void autocrop_ratio(); | void autocrop_ratio(); | |||
void crop_customize(); | void crop_customize(); | |||
} | } | |||
// menu function | // menu function | |||
void m_crop(GtkWidget *, cchar *menu) // more accurate control of crop size 22.11 | void m_crop(GtkWidget *, ch *menu) // more accurate control of crop size 22.11 | |||
{ | { | |||
using namespace crop_names; | using namespace crop_names; | |||
int ii, xmargin, ymargin; | int ii, xmargin, ymargin; | |||
cchar *crop_message = "Drag margin box middle or edges."; | ch *crop_message = "Drag margin box middle or edges."; | |||
char text[20]; | ch text[20]; | |||
F1_help_topic = "crop"; | F1_help_topic = "crop"; | |||
Plog(1,"m_crop \n"); | Plog(1,"m_crop \n"); | |||
EFcrop.menufunc = m_crop; // menu function | EFcrop.menufunc = m_crop; // menu function | |||
EFcrop.menuname = "Crop"; | EFcrop.menuname = "Crop"; | |||
EFcrop.Frestart = 1; // allow restart | EFcrop.Frestart = 1; // allow restart | |||
EFcrop.mousefunc = mousefunc; | EFcrop.mousefunc = mousefunc; | |||
skipping to change at line 943 | skipping to change at line 943 | |||
zdialog_run(zd,dialog_event,"save"); // run dialog - parallel | zdialog_run(zd,dialog_event,"save"); // run dialog - parallel | |||
if (menu && strmatch(menu,"auto")) // crop after rotate 22.14 | if (menu && strmatch(menu,"auto")) // crop after rotate 22.14 | |||
zdialog_send_event(zd,"max"); | zdialog_send_event(zd,"max"); | |||
return; | return; | |||
} | } | |||
// dialog event and completion callback function | // dialog event and completion callback function | |||
int crop_names::dialog_event(zdialog *zd, cchar *event) | int crop_names::dialog_event(zdialog *zd, ch *event) | |||
{ | { | |||
using namespace crop_names; | using namespace crop_names; | |||
static GtkWidget *popmenu = 0; | static GtkWidget *popmenu = 0; | |||
static int flip = 0; | static int flip = 0; | |||
int ii, Frotate = 0; | int ii, Frotate = 0; | |||
int width, height, delta; | int width, height, delta; | |||
double r1, r2, Fratio = 0; | double r1, r2, Fratio = 0; | |||
char text[20]; | ch text[20]; | |||
cchar *pp; | ch *pp; | |||
if (strmatch(event,"escape")) zd->zstat = -2; // escape key | if (strmatch(event,"escape")) zd->zstat = -2; // escape key | |||
if (strmatch(event,"done")) zd->zstat = 2; // apply and quit | if (strmatch(event,"done")) zd->zstat = 2; // apply and quit | |||
if (strmatch(event,"cancel")) zd->zstat = 3; // cancel | if (strmatch(event,"cancel")) zd->zstat = 3; // cancel | |||
if (strmatch(event,"focus")) { | if (strmatch(event,"focus")) { | |||
takeMouse(mousefunc,dragcursor); // re-connect mouse function | takeMouse(mousefunc,dragcursor); // re-connect mouse function | |||
return 1; | return 1; | |||
} | } | |||
skipping to change at line 1226 | skipping to change at line 1226 | |||
crop_customize(); // customize dialog | crop_customize(); // customize dialog | |||
m_crop(0,0); // restart function | m_crop(0,0); // restart function | |||
return 1; | return 1; | |||
} | } | |||
return 1; | return 1; | |||
} | } | |||
// crop size popup menu event function | // crop size popup menu event function | |||
void crop_names::prevcrop_menu_event(GtkWidget *, cchar *menu) | void crop_names::prevcrop_menu_event(GtkWidget *, ch *menu) | |||
{ | { | |||
using namespace crop_names; | using namespace crop_names; | |||
int nn, width, height; | int nn, width, height; | |||
zdialog *zd; | zdialog *zd; | |||
nn = sscanf(menu,"%dx%d",&width,&height); // chosen crop size, "NNNNxNNNN" | nn = sscanf(menu,"%dx%d",&width,&height); // chosen crop size, "NNNNxNNNN" | |||
if (nn != 2) return; | if (nn != 2) return; | |||
zd = EFcrop.zd; | zd = EFcrop.zd; | |||
skipping to change at line 1255 | skipping to change at line 1255 | |||
return; | return; | |||
} | } | |||
// update memory of previously used crop sizes, for future use | // update memory of previously used crop sizes, for future use | |||
void crop_names::update_prev_cropsize() | void crop_names::update_prev_cropsize() | |||
{ | { | |||
using namespace crop_names; | using namespace crop_names; | |||
int ii; | int ii; | |||
char mysize[20]; | ch mysize[20]; | |||
snprintf(mysize,20,"%dx%d",cropww,crophh); // this crop size used, "NNNNxNNNN" | snprintf(mysize,20,"%dx%d",cropww,crophh); // this crop size used, "NNNNxNNNN" | |||
for (ii = 0; ii < 10; ii++) { | for (ii = 0; ii < 10; ii++) { | |||
if (! cropsizes[ii]) break; // check past sizes list for same size | if (! cropsizes[ii]) break; // check past sizes list for same size | |||
if (strmatch(cropsizes[ii],mysize)) break; | if (strmatch(cropsizes[ii],mysize)) break; | |||
} | } | |||
if (ii < 10 && cropsizes[ii]) { // found in list | if (ii < 10 && cropsizes[ii]) { // found in list | |||
zfree(cropsizes[ii]); // remove from list | zfree(cropsizes[ii]); // remove from list | |||
skipping to change at line 1491 | skipping to change at line 1491 | |||
// check new margins for sanity and enforce locked aspect ratio | // check new margins for sanity and enforce locked aspect ratio | |||
void crop_names::crop_limits() | void crop_names::crop_limits() | |||
{ | { | |||
using namespace crop_names; | using namespace crop_names; | |||
int chop; | int chop; | |||
int ww, hh, ww2, hh2; | int ww, hh, ww2, hh2; | |||
float drr; | float drr; | |||
char text[20]; | ch text[20]; | |||
zdialog *zd = EFcrop.zd; | zdialog *zd = EFcrop.zd; | |||
if (cropx1 > cropx2-10) cropx1 = cropx2-10; // sanity limits | if (cropx1 > cropx2-10) cropx1 = cropx2-10; // sanity limits | |||
if (cropy1 > cropy2-10) cropy1 = cropy2-10; | if (cropy1 > cropy2-10) cropy1 = cropy2-10; | |||
if (Rlock && Fcorner) { // w/h ratio locked | if (Rlock && Fcorner) { // w/h ratio locked | |||
if (Fcorner < 3) | if (Fcorner < 3) | |||
cropy1 = cropy2 - 1.0 * (cropx2 - cropx1) / cropR + 0.5; // round | cropy1 = cropy2 - 1.0 * (cropx2 - cropx1) / cropR + 0.5; // round | |||
else | else | |||
cropy2 = cropy1 + 1.0 * (cropx2 - cropx1) / cropR + 0.5; | cropy2 = cropy1 + 1.0 * (cropx2 - cropx1) / cropR + 0.5; | |||
skipping to change at line 2098 | skipping to change at line 2098 | |||
return; | return; | |||
} | } | |||
// dialog to set custom crop button names and corresponding ratios | // dialog to set custom crop button names and corresponding ratios | |||
void crop_names::crop_customize() | void crop_names::crop_customize() | |||
{ | { | |||
using namespace crop_names; | using namespace crop_names; | |||
char text[20], blab[8], rlab[8]; | ch text[20], blab[8], rlab[8]; | |||
float r1, r2, ratio; | float r1, r2, ratio; | |||
cchar *pp; | ch *pp; | |||
int ii, zstat; | int ii, zstat; | |||
/*** | /*** | |||
___________________________________________________________ | ___________________________________________________________ | |||
| crop Buttons | | | crop Buttons | | |||
| | | | | | |||
| label [ 5:4 ] [ 4:3 ] [ 8:5 ] [ 16:9 ] [ 2:1 ] [ gold ] | | | label [ 5:4 ] [ 4:3 ] [ 8:5 ] [ 16:9 ] [ 2:1 ] [ gold ] | | |||
| ratio [ 5:4 ] [ 4:3 ] [ 8:5 ] [ 16:9 ] [ 2:1 ] [1.62:1] | | | ratio [ 5:4 ] [ 4:3 ] [ 8:5 ] [ 16:9 ] [ 2:1 ] [1.62:1] | | |||
| | | | | | |||
| [ OK ] [Cancel] | | | [ OK ] [Cancel] | | |||
skipping to change at line 2199 | skipping to change at line 2199 | |||
float contrast; // contrast input, -1 ... +1 | float contrast; // contrast input, -1 ... +1 | |||
float colorsat; // saturation input, -1 ... +1 = saturated | float colorsat; // saturation input, -1 ... +1 = saturated | |||
int colortemp; // illumination temp. input, 1K ... 8K | int colortemp; // illumination temp. input, 1K ... 8K | |||
int Fapply; // flag, apply dialog controls to image | int Fapply; // flag, apply dialog controls to image | |||
float whitebalance[4] = { 1.0, 1.0, 1.0, 5000 }; // white balance RGB factors, deg. K | float whitebalance[4] = { 1.0, 1.0, 1.0, 5000 }; // white balance RGB factors, deg. K | |||
int Eww, Ehh; // image dimensions | int Eww, Ehh; // image dimensions | |||
} | } | |||
// menu function | // menu function | |||
void m_retouch(GtkWidget *, cchar *menu) | void m_retouch(GtkWidget *, ch *menu) | |||
{ | { | |||
using namespace retouch_names; | using namespace retouch_names; | |||
void retouch_mousefunc(); | void retouch_mousefunc(); | |||
int retouch_dialog_event(zdialog* zd, cchar *event); | int retouch_dialog_event(zdialog* zd, ch *event); | |||
void retouch_curvedit(int spc); | void retouch_curvedit(int spc); | |||
void * retouch_thread(void *); | void * retouch_thread(void *); | |||
GtkWidget *drawwin_scale; | GtkWidget *drawwin_scale; | |||
F1_help_topic = "retouch"; | F1_help_topic = "retouch"; | |||
Plog(1,"m_retouch \n"); | Plog(1,"m_retouch \n"); | |||
EFretouch.menuname = "Retouch"; | EFretouch.menuname = "Retouch"; | |||
skipping to change at line 2377 | skipping to change at line 2377 | |||
Fapply = 0; | Fapply = 0; | |||
zdialog_resize(zd,350,450); | zdialog_resize(zd,350,450); | |||
zdialog_run(zd,retouch_dialog_event,"save"); // run dialog - parallel | zdialog_run(zd,retouch_dialog_event,"save"); // run dialog - parallel | |||
return; | return; | |||
} | } | |||
// dialog event and completion callback function | // dialog event and completion callback function | |||
int retouch_dialog_event(zdialog *zd, cchar *event) | int retouch_dialog_event(zdialog *zd, ch *event) | |||
{ | { | |||
using namespace retouch_names; | using namespace retouch_names; | |||
void retouch_mousefunc(); | void retouch_mousefunc(); | |||
void retouch_autoWB(); | void retouch_autoWB(); | |||
void retouch_autoBL(); | void retouch_autoBL(); | |||
void retouch_mousefunc(); | void retouch_mousefunc(); | |||
spldat *sd = EFretouch.sd; | spldat *sd = EFretouch.sd; | |||
float bright0, dbrite, cont0, dcont; | float bright0, dbrite, cont0, dcont; | |||
skipping to change at line 2780 | skipping to change at line 2780 | |||
// get nominal white color or black point from mouse click position | // get nominal white color or black point from mouse click position | |||
void retouch_mousefunc() // mouse function | void retouch_mousefunc() // mouse function | |||
{ | { | |||
using namespace retouch_names; | using namespace retouch_names; | |||
int px, py, dx, dy; | int px, py, dx, dy; | |||
float red, green, blue; | float red, green, blue; | |||
float *ppix; | float *ppix; | |||
char mousetext[60]; | ch mousetext[60]; | |||
if (! LMclick) return; | if (! LMclick) return; | |||
LMclick = 0; | LMclick = 0; | |||
px = Mxclick; // mouse click position | px = Mxclick; // mouse click position | |||
py = Myclick; | py = Myclick; | |||
if (px < 2) px = 2; // pull back from edge | if (px < 2) px = 2; // pull back from edge | |||
if (px > Eww-3) px = Eww-3; | if (px > Eww-3) px = Eww-3; | |||
if (py < 2) py = 2; | if (py < 2) py = 2; | |||
skipping to change at line 3072 | skipping to change at line 3072 | |||
{ | { | |||
editfunc EFresize; | editfunc EFresize; | |||
int width, height; // new image size | int width, height; // new image size | |||
int orgwidth, orgheight; // original image size | int orgwidth, orgheight; // original image size | |||
int pctwidth, pctheight; // percent of original size | int pctwidth, pctheight; // percent of original size | |||
int Fnewwidth, Fnewheight; // flags, width or height was changed | int Fnewwidth, Fnewheight; // flags, width or height was changed | |||
int Flockratio; // flag, W/H ratio is locked | int Flockratio; // flag, W/H ratio is locked | |||
float WHratio; | float WHratio; | |||
} | } | |||
void m_resize(GtkWidget *, cchar *menu) | void m_resize(GtkWidget *, ch *menu) | |||
{ | { | |||
using namespace resize_names; | using namespace resize_names; | |||
int resize_dialog_event(zdialog *zd, cchar *event); | int resize_dialog_event(zdialog *zd, ch *event); | |||
void * resize_thread(void *); | void * resize_thread(void *); | |||
F1_help_topic = "resize"; | F1_help_topic = "resize"; | |||
Plog(1,"m_resize \n"); | Plog(1,"m_resize \n"); | |||
char rtext[12]; | ch rtext[12]; | |||
EFresize.menuname = "Resize"; | EFresize.menuname = "Resize"; | |||
EFresize.menufunc = m_resize; | EFresize.menufunc = m_resize; | |||
EFresize.Frestart = 1; // allow restart | EFresize.Frestart = 1; // allow restart | |||
EFresize.Fscript = 1; // script supported | EFresize.Fscript = 1; // script supported | |||
EFresize.threadfunc = resize_thread; // thread function | EFresize.threadfunc = resize_thread; // thread function | |||
if (! edit_setup(EFresize)) return; // setup edit | if (! edit_setup(EFresize)) return; // setup edit | |||
/**** | /**** | |||
__________________________________________________ | __________________________________________________ | |||
skipping to change at line 3181 | skipping to change at line 3181 | |||
zdialog_stuff(zd,"1/2",0); | zdialog_stuff(zd,"1/2",0); | |||
zdialog_stuff(zd,"1/3",0); | zdialog_stuff(zd,"1/3",0); | |||
zdialog_stuff(zd,"1/4",0); | zdialog_stuff(zd,"1/4",0); | |||
zdialog_run(zd,resize_dialog_event,"save"); // run dialog | zdialog_run(zd,resize_dialog_event,"save"); // run dialog | |||
return; | return; | |||
} | } | |||
// dialog event and completion callback function | // dialog event and completion callback function | |||
int resize_dialog_event(zdialog *zd, cchar *event) | int resize_dialog_event(zdialog *zd, ch *event) | |||
{ | { | |||
using namespace resize_names; | using namespace resize_names; | |||
int nn; | int nn; | |||
double memreq, memavail; | double memreq, memavail; | |||
char rtext[12]; | ch rtext[12]; | |||
int pixcc = 4 * sizeof(float); // pixel size, RGBA | int pixcc = 4 * sizeof(float); // pixel size, RGBA | |||
if (strmatch(event,"escape")) zd->zstat = -2; | if (strmatch(event,"escape")) zd->zstat = -2; | |||
if (strmatch(event,"done")) zd->zstat = 1; // apply and quit | if (strmatch(event,"done")) zd->zstat = 1; // apply and quit | |||
if (strmatch(event,"cancel")) zd->zstat = 2; // cancel | if (strmatch(event,"cancel")) zd->zstat = 2; // cancel | |||
if (strmatch(event,"apply")) { // from script | if (strmatch(event,"apply")) { // from script | |||
zdialog_fetch(zd,"width",width); | zdialog_fetch(zd,"width",width); | |||
zdialog_fetch(zd,"height",height); | zdialog_fetch(zd,"height",height); | |||
thread_signal(); | thread_signal(); | |||
skipping to change at line 3413 | skipping to change at line 3413 | |||
Fpaint2(); | Fpaint2(); | |||
return 0; | return 0; | |||
} | } | |||
/******************************************************************************* */ | /******************************************************************************* */ | |||
// Upright a rotated image: -90, +90, 180 degrees. | // Upright a rotated image: -90, +90, 180 degrees. | |||
// This is not an edit transaction: file is replaced and re-opened. | // This is not an edit transaction: file is replaced and re-opened. | |||
// No loss of resolution. | // No loss of resolution. | |||
void m_upright(GtkWidget *, cchar *menu) | void m_upright(GtkWidget *, ch *menu) | |||
{ | { | |||
int angle, nn; | int angle, nn; | |||
char *ppv[1]; | ch *ppv[1]; | |||
cchar *exifkey[1] = { exif_orientation_key }; | ch *metakey[1] = { meta_orientation_key }; | |||
cchar *message = "rotation unknown"; | ch *message = "rotation unknown"; | |||
F1_help_topic = "upright"; | F1_help_topic = "upright"; | |||
Plog(1,"m_upright \n"); | Plog(1,"m_upright \n"); | |||
if (clicked_file) { // use clicked file if present | if (clicked_file) { // use clicked file if present | |||
if (! curr_file || ! strmatch(clicked_file,curr_file)) | if (! curr_file || ! strmatch(clicked_file,curr_file)) | |||
f_open(clicked_file,0,0,1,0); // avoid f_open() re-entry | f_open(clicked_file,0,0,1,0); // avoid f_open() re-entry | |||
clicked_file = 0; | clicked_file = 0; | |||
} | } | |||
if (! curr_file) return; // use current file | if (! curr_file) return; // use current file | |||
if (! strstr(".jpg .png .tif",curr_file_type)) { // cannot upright file on disk 22.18 | if (! strstr(".jpg .png .tif",curr_file_type)) { // cannot upright file on disk 22.18 | |||
m_rotate(0,0); // use rotate function instead | m_rotate(0,0); // use rotate function instead | |||
return; | return; | |||
} | } | |||
angle = 0; | angle = 0; | |||
exif_get(curr_file,exifkey,ppv,1); // get EXIF: Orientation | meta_get1(curr_file,(ch **) metakey,ppv,1); // get metadata Orientation | |||
if (ppv[0]) { | if (ppv[0]) { | |||
if (*ppv[0] == '6') angle = +90; // rotate clockwise 90 deg. | if (*ppv[0] == '6') angle = +90; // rotate clockwise 90 deg. | |||
if (*ppv[0] == '8') angle = -90; // counterclockwise 90 deg. | if (*ppv[0] == '8') angle = -90; // counterclockwise 90 deg. | |||
if (*ppv[0] == '3') angle = 180; // 180 deg. | if (*ppv[0] == '3') angle = 180; // 180 deg. | |||
zfree(ppv[0]); | zfree(ppv[0]); | |||
} | } | |||
if (! angle) { | if (! angle) { | |||
nn = zdialog_choose(Mwin,"mouse",message,"-90°","+90°","180°","quit",null) ; | nn = zdialog_choose(Mwin,"mouse",message,"-90°","+90°","180°","quit",null) ; | |||
if (nn == 1) angle = -90; | if (nn == 1) angle = -90; | |||
skipping to change at line 3464 | skipping to change at line 3464 | |||
if (Fblock("upright","block edits")) return; // check pending, block | if (Fblock("upright","block edits")) return; // check pending, block | |||
E0pxm = PXM_load(curr_file,1); // load poss. 16-bit image | E0pxm = PXM_load(curr_file,1); // load poss. 16-bit image | |||
if (E0pxm) { | if (E0pxm) { | |||
E3pxm = PXM_rotate(E0pxm,angle); // rotate (threaded) | E3pxm = PXM_rotate(E0pxm,angle); // rotate (threaded) | |||
PXM_free(E0pxm); | PXM_free(E0pxm); | |||
E0pxm = E3pxm; | E0pxm = E3pxm; | |||
E3pxm = 0; | E3pxm = 0; | |||
} | } | |||
Fupright = 1; // mark uprighted (for EXIF update) | Fupright = 1; // mark uprighted (for metadata update) | |||
f_save(curr_file,curr_file_type,curr_file_bpc,0,1); // replace file | f_save(curr_file,curr_file_type,curr_file_bpc,0,1); // replace file | |||
Fblock("upright",0); | Fblock("upright",0); | |||
f_open(curr_file); | f_open(curr_file); | |||
gallery(curr_file,"paint",0); // repaint gallery | gallery(curr_file,"paint",0); // repaint gallery | |||
return; | return; | |||
} | } | |||
/******************************************************************************* */ | /******************************************************************************* */ | |||
// mirror an image horizontally or vertically | // mirror an image horizontally or vertically | |||
editfunc EFmirror; | editfunc EFmirror; | |||
void m_mirror(GtkWidget *, cchar *menu) | void m_mirror(GtkWidget *, ch *menu) | |||
{ | { | |||
int mirror_dialog_event(zdialog *zd, cchar *event); | int mirror_dialog_event(zdialog *zd, ch *event); | |||
F1_help_topic = "mirror"; | F1_help_topic = "mirror"; | |||
Plog(1,"m_mirror \n"); | Plog(1,"m_mirror \n"); | |||
EFmirror.menuname = "Mirror"; | EFmirror.menuname = "Mirror"; | |||
EFmirror.menufunc = m_mirror; | EFmirror.menufunc = m_mirror; | |||
EFmirror.Fscript = 1; // allow scripting | EFmirror.Fscript = 1; // allow scripting | |||
EFmirror.Frestart = 1; // allow restart | EFmirror.Frestart = 1; // allow restart | |||
if (! edit_setup(EFmirror)) return; // setup edit | if (! edit_setup(EFmirror)) return; // setup edit | |||
skipping to change at line 3519 | skipping to change at line 3519 | |||
zdialog_add_widget(zd,"check","horz","hb1","horizontal","space=5"); | zdialog_add_widget(zd,"check","horz","hb1","horizontal","space=5"); | |||
zdialog_add_widget(zd,"check","vert","hb1","vertical","space=5"); | zdialog_add_widget(zd,"check","vert","hb1","vertical","space=5"); | |||
zdialog_run(zd,mirror_dialog_event,"save"); // run dialog, parallel | zdialog_run(zd,mirror_dialog_event,"save"); // run dialog, parallel | |||
return; | return; | |||
} | } | |||
// dialog event and completion callback function | // dialog event and completion callback function | |||
int mirror_dialog_event(zdialog *zd, cchar *event) | int mirror_dialog_event(zdialog *zd, ch *event) | |||
{ | { | |||
int mirror_horz(void); | int mirror_horz(void); | |||
int mirror_vert(void); | int mirror_vert(void); | |||
int nn; | int nn; | |||
if (strmatch(event,"escape")) zd->zstat = -2; // escape key | if (strmatch(event,"escape")) zd->zstat = -2; // escape key | |||
if (strmatch(event,"focus")) return 1; | if (strmatch(event,"focus")) return 1; | |||
if (strmatch(event,"done")) zd->zstat = 1; // apply and quit | if (strmatch(event,"done")) zd->zstat = 1; // apply and quit | |||
if (strmatch(event,"cancel")) zd->zstat = 2; // cancel | if (strmatch(event,"cancel")) zd->zstat = 2; // cancel | |||
skipping to change at line 3607 | skipping to change at line 3607 | |||
CEF->Fmods++; | CEF->Fmods++; | |||
CEF->Fsaved = 0; | CEF->Fsaved = 0; | |||
Fpaint2(); | Fpaint2(); | |||
return 0; | return 0; | |||
} | } | |||
/******************************************************************************* */ | /******************************************************************************* */ | |||
// draw on image: text, line/arrow, box, oval | // draw on image: text, line/arrow, box, oval | |||
void m_markup(GtkWidget *widget, cchar *menu) | void m_markup(GtkWidget *widget, ch *menu) | |||
{ | { | |||
int markup_dialog_event(zdialog *zd, cchar *event); | int markup_dialog_event(zdialog *zd, ch *event); | |||
zdialog *zd; | zdialog *zd; | |||
F1_help_topic = "markup"; | F1_help_topic = "markup"; | |||
Plog(1,"m_markup \n"); | Plog(1,"m_markup \n"); | |||
/*** | /*** | |||
___________________________________ | ___________________________________ | |||
| Image Markup | | | Image Markup | | |||
skipping to change at line 3648 | skipping to change at line 3648 | |||
zdialog_stuff(zd,"line",0); | zdialog_stuff(zd,"line",0); | |||
zdialog_stuff(zd,"box",0); | zdialog_stuff(zd,"box",0); | |||
zdialog_stuff(zd,"oval",0); | zdialog_stuff(zd,"oval",0); | |||
zdialog_run(zd,markup_dialog_event,"save"); | zdialog_run(zd,markup_dialog_event,"save"); | |||
return; | return; | |||
} | } | |||
// dialog event and completion function | // dialog event and completion function | |||
int markup_dialog_event(zdialog *zd, cchar *event) | int markup_dialog_event(zdialog *zd, ch *event) | |||
{ | { | |||
if (strmatch(event,"escape")) zd->zstat = -2; // escape key | if (strmatch(event,"escape")) zd->zstat = -2; // escape key | |||
if (zd->zstat) { | if (zd->zstat) { | |||
zdialog_free(zd); | zdialog_free(zd); | |||
return 1; | return 1; | |||
} | } | |||
if (strmatch(event,"text")) m_draw_text(0,0); | if (strmatch(event,"text")) m_draw_text(0,0); | |||
if (strmatch(event,"line")) m_draw_line(0,0); | if (strmatch(event,"line")) m_draw_line(0,0); | |||
skipping to change at line 3675 | skipping to change at line 3675 | |||
} | } | |||
/******************************************************************************* */ | /******************************************************************************* */ | |||
// add text on top of the image | // add text on top of the image | |||
namespace drawtext_names | namespace drawtext_names | |||
{ | { | |||
textattr_t attr; // text attributes and image | textattr_t attr; // text attributes and image | |||
char file[1000] = ""; | ch file[1000] = ""; | |||
// file for write_text data | // file for write_text data | |||
char metakey[60] = ""; | ch metakey[60] = ""; | |||
int Tpx, Tpy; // text position on image | int Tpx, Tpy; // text position on image | |||
int textpresent; // flag, text present on image | int textpresent; // flag, text present on image | |||
int dialog_event(zdialog *zd, cchar *event); // dialog event function | int dialog_event(zdialog *zd, ch *event); // dialog event function | |||
void mousefunc(); // mouse event function | void mousefunc(); // mouse event function | |||
void write(int mode); // write text on image | void write(int mode); // write text on image | |||
editfunc EFdrawtext; | editfunc EFdrawtext; | |||
} | } | |||
// menu function | // menu function | |||
void m_draw_text(GtkWidget *, cchar *menu) | void m_draw_text(GtkWidget *, ch *menu) | |||
{ | { | |||
using namespace drawtext_names; | using namespace drawtext_names; | |||
cchar *title = "Draw text on image"; | ch *title = "Draw text on image"; | |||
cchar *tip = "Enter text, click/drag on image, right click to remove"; | ch *tip = "Enter text, click/drag on image, right click to remove"; | |||
Plog(1,"m_draw_text \n"); | Plog(1,"m_draw_text \n"); | |||
EFdrawtext.menufunc = m_draw_text; | EFdrawtext.menufunc = m_draw_text; | |||
EFdrawtext.menuname = "Markup Text"; | EFdrawtext.menuname = "Markup Text"; | |||
EFdrawtext.Farea = 1; // select area ignored | EFdrawtext.Farea = 1; // select area ignored | |||
EFdrawtext.Frestart = 1; // allow restart | EFdrawtext.Frestart = 1; // allow restart | |||
EFdrawtext.mousefunc = mousefunc; | EFdrawtext.mousefunc = mousefunc; | |||
if (! edit_setup(EFdrawtext)) return; // setup edit | if (! edit_setup(EFdrawtext)) return; // setup edit | |||
skipping to change at line 3853 | skipping to change at line 3853 | |||
takeMouse(mousefunc,dragcursor); // connect mouse function | takeMouse(mousefunc,dragcursor); // connect mouse function | |||
textpresent = 0; // no text on image yet | textpresent = 0; // no text on image yet | |||
zdialog_run(zd,dialog_event,"save"); // run dialog, parallel | zdialog_run(zd,dialog_event,"save"); // run dialog, parallel | |||
if (*metakey) zdialog_send_event(zd,"Fetch"); // metadata key active, get text | if (*metakey) zdialog_send_event(zd,"Fetch"); // metadata key active, get text | |||
return; | return; | |||
} | } | |||
// dialog event and completion callback function | // dialog event and completion callback function | |||
int drawtext_names::dialog_event(zdialog *zd, cchar *event) | int drawtext_names::dialog_event(zdialog *zd, ch *event) | |||
{ | { | |||
using namespace drawtext_names; | using namespace drawtext_names; | |||
GtkWidget *font_dialog; | GtkWidget *font_dialog; | |||
char font[100]; // font name and size | ch font[100]; // font name and size | |||
int size, err; | int size, err; | |||
char *newfilename, *pp; | ch *newfilename, *pp; | |||
cchar *keyname[1]; | ch *keyname[1]; | |||
char *keyvals[1]; | ch *keyvals[1]; | |||
if (strmatch(event,"escape")) zd->zstat = -2; // escape key | if (strmatch(event,"escape")) zd->zstat = -2; // escape key | |||
if (strmatch(event,"done")) zd->zstat = 6; // apply and quit | if (strmatch(event,"done")) zd->zstat = 6; // apply and quit | |||
if (strmatch(event,"cancel")) zd->zstat = 7; // cancel | if (strmatch(event,"cancel")) zd->zstat = 7; // cancel | |||
if (zd->zstat) | if (zd->zstat) | |||
{ | { | |||
if (zd->zstat < 0 || zd->zstat > 7) zd->zstat = 7; // cancel | if (zd->zstat < 0 || zd->zstat > 7) zd->zstat = 7; // cancel | |||
if (zd->zstat == 1) { // clear all inputs | if (zd->zstat == 1) { // clear all inputs | |||
skipping to change at line 3972 | skipping to change at line 3972 | |||
if (strmatch(event,"Save")) { // save zdialog fields to file | if (strmatch(event,"Save")) { // save zdialog fields to file | |||
save_text(zd); | save_text(zd); | |||
return 1; | return 1; | |||
} | } | |||
if (strmatch(event,"Fetch")) { // load text from metadata keyname | if (strmatch(event,"Fetch")) { // load text from metadata keyname | |||
zdialog_fetch(zd,"metakey",metakey,60); | zdialog_fetch(zd,"metakey",metakey,60); | |||
if (*metakey < ' ') return 1; | if (*metakey < ' ') return 1; | |||
keyname[0] = metakey; | keyname[0] = metakey; | |||
exif_get(curr_file,keyname,keyvals,1); | meta_get1(curr_file,keyname,keyvals,1); | |||
if (! keyvals[0]) return 1; | if (! keyvals[0]) return 1; | |||
if (strlen(keyvals[0]) > 999) keyvals[0][999] = 0; | if (strlen(keyvals[0]) > 999) keyvals[0][999] = 0; | |||
repl_1str(keyvals[0],attr.text,"\\n","\n"); // replace "\n" with newlines | repl_1str(keyvals[0],attr.text,"\\n","\n"); // replace "\n" with newlines | |||
zfree(keyvals[0]); | zfree(keyvals[0]); | |||
zdialog_stuff(zd,"text",attr.text); // stuff dialog with metadata | zdialog_stuff(zd,"text",attr.text); // stuff dialog with metadata | |||
} | } | |||
if (strmatch(event,"text")) // get text from dialog | if (strmatch(event,"text")) // get text from dialog | |||
zdialog_fetch(zd,"text",attr.text,1000); | zdialog_fetch(zd,"text",attr.text,1000); | |||
skipping to change at line 4261 | skipping to change at line 4261 | |||
hh1 = hh2; | hh1 = hh2; | |||
return; | return; | |||
} | } | |||
// load text and attributes into dialog from a file | // load text and attributes into dialog from a file | |||
void load_text(zdialog *zd) | void load_text(zdialog *zd) | |||
{ | { | |||
FILE *fid; | FILE *fid; | |||
int err, nn; | int err, nn; | |||
char *pp, *pp2, *file, buff[1200]; | ch *pp, *pp2, *file, buff[1200]; | |||
cchar *dialogtitle = "load text data from a file"; | ch *dialogtitle = "load text data from a file"; | |||
textattr_t attr; | textattr_t attr; | |||
file = zgetfile(dialogtitle,MWIN,"file",markup_folder); // get input file from user | file = zgetfile(dialogtitle,MWIN,"file",markup_folder); // get input file from user | |||
if (! file) return; | if (! file) return; | |||
fid = fopen(file,"r"); // open for read | fid = fopen(file,"r"); // open for read | |||
if (! fid) { | if (! fid) { | |||
zmessageACK(Mwin,strerror(errno)); | zmessageACK(Mwin,strerror(errno)); | |||
zfree(file); | zfree(file); | |||
return; | return; | |||
skipping to change at line 4287 | skipping to change at line 4287 | |||
if (! strmatchN(pp,"text string: ",13)) goto badfile; | if (! strmatchN(pp,"text string: ",13)) goto badfile; | |||
pp += 13; | pp += 13; | |||
if (strlen(pp) < 2) goto badfile; | if (strlen(pp) < 2) goto badfile; | |||
repl_Nstrs(pp,attr.text,"\\n","\n",null); // replace "\n" with newline char. | repl_Nstrs(pp,attr.text,"\\n","\n",null); // replace "\n" with newline char. | |||
pp = fgets_trim(buff,1200,fid); // read font and size | pp = fgets_trim(buff,1200,fid); // read font and size | |||
if (! pp) goto badfile; | if (! pp) goto badfile; | |||
if (! strmatchN(pp,"font: ",6)) goto badfile; | if (! strmatchN(pp,"font: ",6)) goto badfile; | |||
pp += 6; | pp += 6; | |||
strTrim(pp); | strTrim(pp); | |||
pp2 = (char *) zstrstr(pp,"size: "); | pp2 = (ch *) zstrstr(pp,"size: "); | |||
if (! pp2) goto badfile; | if (! pp2) goto badfile; | |||
*pp2 = 0; | *pp2 = 0; | |||
pp2 += 6; | pp2 += 6; | |||
strncpy0(attr.font,pp,80); | strncpy0(attr.font,pp,80); | |||
attr.size = atoi(pp2); | attr.size = atoi(pp2); | |||
if (attr.size < 8) goto badfile; | if (attr.size < 8) goto badfile; | |||
pp = fgets_trim(buff,1200,fid); // read text attributes | pp = fgets_trim(buff,1200,fid); // read text attributes | |||
if (! pp) goto badfile; | if (! pp) goto badfile; | |||
nn = sscanf(pp,"attributes: %f %s %s %s %s %d %d %d %d %d %d %d", | nn = sscanf(pp,"attributes: %f %s %s %s %s %d %d %d %d %d %d %d", | |||
skipping to change at line 4337 | skipping to change at line 4337 | |||
badfile: // project file had a problem | badfile: // project file had a problem | |||
fclose(fid); | fclose(fid); | |||
zmessageACK(Mwin,"text file is defective"); | zmessageACK(Mwin,"text file is defective"); | |||
Plog(0,"buff: %s\n",buff); | Plog(0,"buff: %s\n",buff); | |||
} | } | |||
// save text and attributes from dialog to a file | // save text and attributes from dialog to a file | |||
void save_text(zdialog *zd) | void save_text(zdialog *zd) | |||
{ | { | |||
cchar *dialogtitle = "save text data to a file"; | ch *dialogtitle = "save text data to a file"; | |||
FILE *fid; | FILE *fid; | |||
char *file, text2[1200]; | ch *file, text2[1200]; | |||
textattr_t attr; | textattr_t attr; | |||
file = zgetfile(dialogtitle,MWIN,"save",markup_folder); // get output file from user | file = zgetfile(dialogtitle,MWIN,"save",markup_folder); // get output file from user | |||
if (! file) return; | if (! file) return; | |||
fid = fopen(file,"w"); // open for write | fid = fopen(file,"w"); // open for write | |||
if (! fid) { | if (! fid) { | |||
zmessageACK(Mwin,strerror(errno)); | zmessageACK(Mwin,strerror(errno)); | |||
zfree(file); | zfree(file); | |||
return; | return; | |||
skipping to change at line 4389 | skipping to change at line 4389 | |||
fclose(fid); | fclose(fid); | |||
return; | return; | |||
} | } | |||
/******************************************************************************* * | /******************************************************************************* * | |||
Create a graphic image with text, any color, any font, any angle. | Create a graphic image with text, any color, any font, any angle. | |||
Add outline and shadow colors. Apply transparencies. | Add outline and shadow colors. Apply transparencies. | |||
struct textattr_t // attributes for gent ext() function | struct textattr_t // attributes for gent ext() function | |||
char text[1000]; // text to generate im | ch text[1000]; // text to generate im | |||
age from | age from | |||
char font[80]; // font name | ch font[80]; // font name | |||
int size; // font size | int size; // font size | |||
int tww, thh; // generated image siz e, unrotated | int tww, thh; // generated image siz e, unrotated | |||
float angle; // text angle, degrees | float angle; // text angle, degrees | |||
float sinT, cosT; // trig funcs for text angle | float sinT, cosT; // trig funcs for text angle | |||
char color[4][20]; // text, backing, outl ine, shadow "R|G|B" | ch color[4][20]; // text, backing, outl ine, shadow "R|G|B" | |||
int transp[4]; // corresponding trans parencies 0-255 | int transp[4]; // corresponding trans parencies 0-255 | |||
int towidth; // outline width, pixe ls | int towidth; // outline width, pixe ls | |||
int shwidth; // shadow width | int shwidth; // shadow width | |||
int shangle; // shadow angle -180.. .+180 | int shangle; // shadow angle -180.. .+180 | |||
PXB *pxb_text; // output image with t ext/outline/shadow | PXB *pxb_text; // output image with t ext/outline/shadow | |||
************************************/ | ************************************/ | |||
int gentext(textattr_t *attr) | int gentext(textattr_t *attr) | |||
{ | { | |||
skipping to change at line 4425 | skipping to change at line 4425 | |||
int txred, txgreen, txblue; | int txred, txgreen, txblue; | |||
int bgred, bggreen, bgblue; | int bgred, bggreen, bgblue; | |||
int tored, togreen, toblue; | int tored, togreen, toblue; | |||
int shred, shgreen, shblue; | int shred, shgreen, shblue; | |||
float txtransp, bgtransp, totransp, shtransp; | float txtransp, bgtransp, totransp, shtransp; | |||
PXB *pxb_temp1, *pxb_temp2; | PXB *pxb_temp1, *pxb_temp2; | |||
uint8 *cairo_data, *cpix; | uint8 *cairo_data, *cpix; | |||
uint8 *pix1, *pix2; | uint8 *pix1, *pix2; | |||
int px, py, ww, hh; | int px, py, ww, hh; | |||
char font[100]; // font name and size | ch font[100]; // font name and size | |||
int red, green, blue; | int red, green, blue; | |||
float txpart, topart, shpart, bgpart; | float txpart, topart, shpart, bgpart; | |||
if (! *attr->text) strcpy(attr->text," "); // no text | if (! *attr->text) strcpy(attr->text," "); // no text | |||
if (attr->pxb_text) PXB_free(attr->pxb_text); | if (attr->pxb_text) PXB_free(attr->pxb_text); | |||
snprintf(font,100,"%s %d",attr->font,attr->size); // font name and size together | snprintf(font,100,"%s %d",attr->font,attr->size); // font name and size together | |||
angle = attr->angle; // text angle, degrees | angle = attr->angle; // text angle, degrees | |||
attr->sinT = sin(angle/57.296); // trig funcs for text angle | attr->sinT = sin(angle/57.296); // trig funcs for text angle | |||
skipping to change at line 4654 | skipping to change at line 4654 | |||
namespace drawline_names | namespace drawline_names | |||
{ | { | |||
lineattr_t attr; // line/arrow attributes and image | lineattr_t attr; // line/arrow attributes and image | |||
int mpx, mpy; // mouse position on image | int mpx, mpy; // mouse position on image | |||
int linepresent; // flag, line present on image | int linepresent; // flag, line present on image | |||
int orgx1, orgy1, ww1, hh1; // old line image overlap rectangle | int orgx1, orgy1, ww1, hh1; // old line image overlap rectangle | |||
int orgx2, orgy2, ww2, hh2; // new overlap rectangle | int orgx2, orgy2, ww2, hh2; // new overlap rectangle | |||
zdialog *zd; | zdialog *zd; | |||
int dialog_event(zdialog *zd, cchar *event); // dialog event function | int dialog_event(zdialog *zd, ch *event); // dialog event function | |||
void mousefunc(); // mouse event function | void mousefunc(); // mouse event function | |||
void write(int mode); // write line on image | void write(int mode); // write line on image | |||
editfunc EFdrawline; | editfunc EFdrawline; | |||
} | } | |||
void m_draw_line(GtkWidget *, cchar *menu) | void m_draw_line(GtkWidget *, ch *menu) | |||
{ | { | |||
using namespace drawline_names; | using namespace drawline_names; | |||
cchar *intro = "Enter line or arrow properties in dialog, \n" | ch *intro = "Enter line or arrow properties in dialog, \n" | |||
"click/drag on image, right click to remove"; | "click/drag on image, right click to remove"; | |||
Plog(1,"m_draw_line \n"); | Plog(1,"m_draw_line \n"); | |||
EFdrawline.menufunc = m_draw_line; | EFdrawline.menufunc = m_draw_line; | |||
EFdrawline.menuname = "Markup Line"; | EFdrawline.menuname = "Markup Line"; | |||
EFdrawline.Farea = 1; // select area ignored | EFdrawline.Farea = 1; // select area ignored | |||
EFdrawline.mousefunc = mousefunc; | EFdrawline.mousefunc = mousefunc; | |||
if (! edit_setup(EFdrawline)) return; // setup edit | if (! edit_setup(EFdrawline)) return; // setup edit | |||
skipping to change at line 4789 | skipping to change at line 4789 | |||
takeMouse(mousefunc,dragcursor); // connect mouse function | takeMouse(mousefunc,dragcursor); // connect mouse function | |||
linepresent = 0; // no line on image yet | linepresent = 0; // no line on image yet | |||
mpx = mpy = -1; // no position defined yet | mpx = mpy = -1; // no position defined yet | |||
zdialog_run(zd,dialog_event,"save"); // run dialog, parallel | zdialog_run(zd,dialog_event,"save"); // run dialog, parallel | |||
return; | return; | |||
} | } | |||
// dialog event and completion callback function | // dialog event and completion callback function | |||
int drawline_names::dialog_event(zdialog *zd, cchar *event) | int drawline_names::dialog_event(zdialog *zd, ch *event) | |||
{ | { | |||
using namespace drawline_names; | using namespace drawline_names; | |||
if (strmatch(event,"escape")) zd->zstat = -2; // escape key | if (strmatch(event,"escape")) zd->zstat = -2; // escape key | |||
if (strmatch(event,"done")) zd->zstat = 2; // apply and quit | if (strmatch(event,"done")) zd->zstat = 2; // apply and quit | |||
if (strmatch(event,"cancel")) zd->zstat = 3; // cancel | if (strmatch(event,"cancel")) zd->zstat = 3; // cancel | |||
if (zd->zstat) | if (zd->zstat) | |||
{ | { | |||
if (zd->zstat == 1) { // Apply, commit present line to image | if (zd->zstat == 1) { // Apply, commit present line to image | |||
skipping to change at line 5355 | skipping to change at line 5355 | |||
{ | { | |||
editfunc EFdrawbox; | editfunc EFdrawbox; | |||
int RGB[3]; // box line color | int RGB[3]; // box line color | |||
int width; // box line width | int width; // box line width | |||
int bx1, by1, bx2, by2; // box NW and SE corners | int bx1, by1, bx2, by2; // box NW and SE corners | |||
} | } | |||
// menu function | // menu function | |||
void m_draw_box(GtkWidget *, cchar *menu) | void m_draw_box(GtkWidget *, ch *menu) | |||
{ | { | |||
using namespace drawbox_names; | using namespace drawbox_names; | |||
int drawbox_dialog_event(zdialog *zd, cchar *event); | int drawbox_dialog_event(zdialog *zd, ch *event); | |||
void drawbox_mousefunc(); | void drawbox_mousefunc(); | |||
Plog(1,"m_draw_box \n"); | Plog(1,"m_draw_box \n"); | |||
zdialog *zd; | zdialog *zd; | |||
cchar *tip = "drag mouse to draw box \n" | ch *tip = "drag mouse to draw box \n" | |||
"shift + drag center to move box \n" | "shift + drag center to move box \n" | |||
"shift + drag edge to move edge"; | "shift + drag edge to move edge"; | |||
EFdrawbox.menufunc = m_draw_box; | EFdrawbox.menufunc = m_draw_box; | |||
EFdrawbox.menuname = "Markup Box"; | EFdrawbox.menuname = "Markup Box"; | |||
EFdrawbox.mousefunc = drawbox_mousefunc; | EFdrawbox.mousefunc = drawbox_mousefunc; | |||
if (! edit_setup(EFdrawbox)) return; | if (! edit_setup(EFdrawbox)) return; | |||
/*** | /*** | |||
___________________________________ | ___________________________________ | |||
skipping to change at line 5411 | skipping to change at line 5411 | |||
zdialog_run(zd,drawbox_dialog_event,"save"); | zdialog_run(zd,drawbox_dialog_event,"save"); | |||
zdialog_send_event(zd,"init"); | zdialog_send_event(zd,"init"); | |||
takeMouse(drawbox_mousefunc,dragcursor); | takeMouse(drawbox_mousefunc,dragcursor); | |||
bx1 = by1 = bx2 = by2 = 0; // no box yet | bx1 = by1 = bx2 = by2 = 0; // no box yet | |||
return; | return; | |||
} | } | |||
// dialog event and completion function | // dialog event and completion function | |||
int drawbox_dialog_event(zdialog *zd, cchar *event) | int drawbox_dialog_event(zdialog *zd, ch *event) | |||
{ | { | |||
using namespace drawbox_names; | using namespace drawbox_names; | |||
char color[20]; | ch color[20]; | |||
cchar *pp; | ch *pp; | |||
if (strmatch(event,"escape")) zd->zstat = -2; // escape key | if (strmatch(event,"escape")) zd->zstat = -2; // escape key | |||
if (strmatch(event,"done")) zd->zstat = 2; // apply and quit | if (strmatch(event,"done")) zd->zstat = 2; // apply and quit | |||
if (strmatch(event,"cancel")) zd->zstat = 3; // cancel | if (strmatch(event,"cancel")) zd->zstat = 3; // cancel | |||
if (zd->zstat) | if (zd->zstat) | |||
{ | { | |||
if (zd->zstat == 1) { // apply | if (zd->zstat == 1) { // apply | |||
zd->zstat = 0; | zd->zstat = 0; | |||
edit_apply(); | edit_apply(); | |||
skipping to change at line 5557 | skipping to change at line 5557 | |||
int width; // oval line width | int width; // oval line width | |||
int type = 1; // 1/2 = circle/oval | int type = 1; // 1/2 = circle/oval | |||
int mx1, my1, mx2, my2; // mouse drag coordinates | int mx1, my1, mx2, my2; // mouse drag coordinates | |||
float exa, exb; // ellipse axes | float exa, exb; // ellipse axes | |||
float angle; // ellipse angle | float angle; // ellipse angle | |||
int Fupdate; | int Fupdate; | |||
} | } | |||
// menu function | // menu function | |||
void m_draw_oval(GtkWidget *, cchar *menu) | void m_draw_oval(GtkWidget *, ch *menu) | |||
{ | { | |||
using namespace drawoval_names; | using namespace drawoval_names; | |||
int drawoval_dialog_event(zdialog *zd, cchar *event); | int drawoval_dialog_event(zdialog *zd, ch *event); | |||
void drawoval_mousefunc(); | void drawoval_mousefunc(); | |||
Plog(1,"m_draw_oval \n"); | Plog(1,"m_draw_oval \n"); | |||
zdialog *zd; | zdialog *zd; | |||
cchar *tip = "drag mouse down/right to draw oval \n" | ch *tip = "drag mouse down/right to draw oval \n" | |||
"shift + drag center to move oval \n" | "shift + drag center to move oval \n" | |||
"shift + drag lower right edge to change"; | "shift + drag lower right edge to change"; | |||
EFdrawoval.menufunc = m_draw_oval; | EFdrawoval.menufunc = m_draw_oval; | |||
EFdrawoval.menuname = "Markup Oval"; | EFdrawoval.menuname = "Markup Oval"; | |||
EFdrawoval.mousefunc = drawoval_mousefunc; | EFdrawoval.mousefunc = drawoval_mousefunc; | |||
if (! edit_setup(EFdrawoval)) return; | if (! edit_setup(EFdrawoval)) return; | |||
/*** | /*** | |||
_________________________________________ | _________________________________________ | |||
skipping to change at line 5624 | skipping to change at line 5624 | |||
takeMouse(drawoval_mousefunc,dragcursor); | takeMouse(drawoval_mousefunc,dragcursor); | |||
mx1 = my1 = 0; // no oval yet | mx1 = my1 = 0; // no oval yet | |||
Fupdate = 0; | Fupdate = 0; | |||
return; | return; | |||
} | } | |||
// dialog event and completion function | // dialog event and completion function | |||
int drawoval_dialog_event(zdialog *zd, cchar *event) | int drawoval_dialog_event(zdialog *zd, ch *event) | |||
{ | { | |||
using namespace drawoval_names; | using namespace drawoval_names; | |||
void drawoval_mousefunc(); | void drawoval_mousefunc(); | |||
char color[20]; | ch color[20]; | |||
cchar *pp; | ch *pp; | |||
if (strmatch(event,"escape")) zd->zstat = -2; // escape key | if (strmatch(event,"escape")) zd->zstat = -2; // escape key | |||
if (strmatch(event,"done")) zd->zstat = 2; // apply and quit | if (strmatch(event,"done")) zd->zstat = 2; // apply and quit | |||
if (strmatch(event,"cancel")) zd->zstat = 3; // cancel | if (strmatch(event,"cancel")) zd->zstat = 3; // cancel | |||
if (zd->zstat) | if (zd->zstat) | |||
{ | { | |||
if (zd->zstat == 1) { // apply | if (zd->zstat == 1) { // apply | |||
zd->zstat = 0; | zd->zstat = 0; | |||
edit_apply(); | edit_apply(); | |||
skipping to change at line 5934 | skipping to change at line 5934 | |||
namespace colormode_names | namespace colormode_names | |||
{ | { | |||
editfunc EFcolormode; | editfunc EFcolormode; | |||
int mode; | int mode; | |||
float mblend; | float mblend; | |||
} | } | |||
// menu function | // menu function | |||
void m_color_mode(GtkWidget *, cchar *menu) | void m_color_mode(GtkWidget *, ch *menu) | |||
{ | { | |||
using namespace colormode_names; | using namespace colormode_names; | |||
int colormode_dialog_event(zdialog *zd, cchar *event); | int colormode_dialog_event(zdialog *zd, ch *event); | |||
void * colormode_thread(void *); | void * colormode_thread(void *); | |||
F1_help_topic = "color mode"; | F1_help_topic = "color mode"; | |||
Plog(1,"m_color_mode \n"); | Plog(1,"m_color_mode \n"); | |||
EFcolormode.menuname = "Color Mode"; | EFcolormode.menuname = "Color Mode"; | |||
EFcolormode.menufunc = m_color_mode; | EFcolormode.menufunc = m_color_mode; | |||
EFcolormode.threadfunc = colormode_thread; | EFcolormode.threadfunc = colormode_thread; | |||
EFcolormode.FprevReq = 1; // use preview | EFcolormode.FprevReq = 1; // use preview | |||
skipping to change at line 5998 | skipping to change at line 5998 | |||
zdialog_add_widget(zd,"label","lab100","hbmblend","100%","space=5"); | zdialog_add_widget(zd,"label","lab100","hbmblend","100%","space=5"); | |||
zdialog_resize(zd,200,0); | zdialog_resize(zd,200,0); | |||
zdialog_run(zd,colormode_dialog_event,"save"); // run dialog - parallel | zdialog_run(zd,colormode_dialog_event,"save"); // run dialog - parallel | |||
return; | return; | |||
} | } | |||
// dialog event and completion callback function | // dialog event and completion callback function | |||
int colormode_dialog_event(zdialog *zd, cchar *event) | int colormode_dialog_event(zdialog *zd, ch *event) | |||
{ | { | |||
using namespace colormode_names; | using namespace colormode_names; | |||
if (strmatch(event,"escape")) zd->zstat = -2; // escape key | if (strmatch(event,"escape")) zd->zstat = -2; // escape key | |||
if (strmatch(event,"done")) zd->zstat = 1; // from edit_setup() or f_save() | if (strmatch(event,"done")) zd->zstat = 1; // from edit_setup() or f_save() | |||
if (strmatch(event,"cancel")) zd->zstat = 2; // from f_open() | if (strmatch(event,"cancel")) zd->zstat = 2; // from f_open() | |||
if (strmatch(event,"fullsize")) { // from select area | if (strmatch(event,"fullsize")) { // from select area | |||
edit_fullsize(); // get full size image | edit_fullsize(); // get full size image | |||
thread_signal(); | thread_signal(); | |||
skipping to change at line 6209 | skipping to change at line 6209 | |||
return 0; | return 0; | |||
} | } | |||
/******************************************************************************* */ | /******************************************************************************* */ | |||
// Pixel paint function - paint individual pixels with the mouse. | // Pixel paint function - paint individual pixels with the mouse. | |||
// The mouse circle paints a selected color. | // The mouse circle paints a selected color. | |||
namespace paint_image_names | namespace paint_image_names | |||
{ | { | |||
int paint_dialog_event(zdialog* zd, cchar *event); | int paint_dialog_event(zdialog* zd, ch *event); | |||
void paint_mousefunc(); | void paint_mousefunc(); | |||
void paint_dopixels(int px, int py); // update pixel block | void paint_dopixels(int px, int py); // update pixel block | |||
void paint_savepixB(int px, int py); // save pixel block for poss. undo | void paint_savepixB(int px, int py); // save pixel block for poss. undo | |||
void paint_undolastB(); // undo last pixel block, free memory | void paint_undolastB(); // undo last pixel block, free memory | |||
void paint_freefirstB(); // free memory for first pixel block | void paint_freefirstB(); // free memory for first pixel block | |||
void paint_freeallB(); // free memory for all pixel blocks | void paint_freeallB(); // free memory for all pixel blocks | |||
uint8 RGB[3] = { 0, 0, 0 }; // color to paint | uint8 RGB[3] = { 0, 0, 0 }; // color to paint | |||
int mode; // 1/2 = paint / erase | int mode; // 1/2 = paint / erase | |||
int Mrad; // mouse radius | int Mrad; // mouse radius | |||
skipping to change at line 6248 | skipping to change at line 6248 | |||
pixBmem_t **pixBmem = 0; // *pixBmem_t[] | pixBmem_t **pixBmem = 0; // *pixBmem_t[] | |||
int pixBmem_cc = 12; // all except pixel array + pad | int pixBmem_cc = 12; // all except pixel array + pad | |||
int pcc4 = 4 * sizeof(float); // pixel cc: RGBA = 4 channels | int pcc4 = 4 * sizeof(float); // pixel cc: RGBA = 4 channels | |||
editfunc EFpaint; | editfunc EFpaint; | |||
} | } | |||
// menu function | // menu function | |||
void m_paint_image(GtkWidget *, cchar *menu) // separate paint and copy | void m_paint_image(GtkWidget *, ch *menu) // separate paint and copy | |||
{ | { | |||
using namespace paint_image_names; | using namespace paint_image_names; | |||
cchar *mess1 = "shift + left click: pick color from image \n" | ch *mess1 = "shift + left click: pick color from image \n" | |||
"left drag: paint color on image \n" // remove click actions | "left drag: paint color on image \n" // remove click actions | |||
"right drag: restore original image"; | "right drag: restore original image"; | |||
cchar *dash = " \xcc\xb6 "; | ch *dash = " \xcc\xb6 "; | |||
F1_help_topic = "paint image"; | F1_help_topic = "paint image"; | |||
Plog(1,"m_paint_image \n"); | Plog(1,"m_paint_image \n"); | |||
EFpaint.menufunc = m_paint_image; | EFpaint.menufunc = m_paint_image; | |||
EFpaint.menuname = "Paint Image"; | EFpaint.menuname = "Paint Image"; | |||
EFpaint.Farea = 2; // select area OK | EFpaint.Farea = 2; // select area OK | |||
EFpaint.mousefunc = paint_mousefunc; // mouse function | EFpaint.mousefunc = paint_mousefunc; // mouse function | |||
if (! edit_setup(EFpaint)) return; // setup edit | if (! edit_setup(EFpaint)) return; // setup edit | |||
skipping to change at line 6369 | skipping to change at line 6369 | |||
ac = 0; | ac = 0; | |||
nc = E1pxm->nc; // channels, RGBA | nc = E1pxm->nc; // channels, RGBA | |||
if (nc > 3) ac = 1; // alpha channel present | if (nc > 3) ac = 1; // alpha channel present | |||
takeMouse(paint_mousefunc,drawcursor); // connect mouse function | takeMouse(paint_mousefunc,drawcursor); // connect mouse function | |||
return; | return; | |||
} | } | |||
// dialog event and completion callback function | // dialog event and completion callback function | |||
int paint_image_names::paint_dialog_event(zdialog *zd, cchar *event) | int paint_image_names::paint_dialog_event(zdialog *zd, ch *event) | |||
{ | { | |||
using namespace paint_image_names; | using namespace paint_image_names; | |||
cchar *pp; | ch *pp; | |||
char color[20], text[20]; | ch color[20], text[20]; | |||
float opccent, opcedge; // center and edge opacities | float opccent, opcedge; // center and edge opacities | |||
int paint, radius, dx, dy, err; | int paint, radius, dx, dy, err; | |||
float rad, kern; | float rad, kern; | |||
if (strmatch(event,"escape")) zd->zstat = -2; // escape key | if (strmatch(event,"escape")) zd->zstat = -2; // escape key | |||
if (strmatch(event,"done")) zd->zstat = 1; // from edit_setup() or f_save() | if (strmatch(event,"done")) zd->zstat = 1; // from edit_setup() or f_save() | |||
if (strmatch(event,"cancel")) zd->zstat = 2; // from f_open() | if (strmatch(event,"cancel")) zd->zstat = 2; // from f_open() | |||
if (zd->zstat) | if (zd->zstat) | |||
{ | { | |||
skipping to change at line 6484 | skipping to change at line 6484 | |||
} | } | |||
// mouse function | // mouse function | |||
void paint_image_names::paint_mousefunc() // no action on clicks | void paint_image_names::paint_mousefunc() // no action on clicks | |||
{ | { | |||
using namespace paint_image_names; | using namespace paint_image_names; | |||
static int pmxdown = 0, pmydown = 0; | static int pmxdown = 0, pmydown = 0; | |||
static int pmxdrag = 0, pmydrag = 0; | static int pmxdrag = 0, pmydrag = 0; | |||
char color[20]; | ch color[20]; | |||
float *pix3; | float *pix3; | |||
zdialog *zd = EFpaint.zd; | zdialog *zd = EFpaint.zd; | |||
if (Fdrag) return; // pass through to main() | if (Fdrag) return; // pass through to main() | |||
if (LMclick && KBshiftkey) // shift + left mouse click | if (LMclick && KBshiftkey) // shift + left mouse click | |||
{ | { | |||
LMclick = 0; | LMclick = 0; | |||
pix3 = PXMpix(E3pxm,Mxclick,Myclick); // pick new color from image | pix3 = PXMpix(E3pxm,Mxclick,Myclick); // pick new color from image | |||
RGB[0] = pix3[0]; | RGB[0] = pix3[0]; | |||
skipping to change at line 6801 | skipping to change at line 6801 | |||
} | } | |||
/******************************************************************************* */ | /******************************************************************************* */ | |||
// Select a color from a color chooser image file. | // Select a color from a color chooser image file. | |||
// Returns color button in callers zdialog. | // Returns color button in callers zdialog. | |||
// Returns selected RGB color in prgb[3] argument. | // Returns selected RGB color in prgb[3] argument. | |||
namespace RGB_chooser_names | namespace RGB_chooser_names | |||
{ | { | |||
// char *RGB_chooser_file; | // ch *RGB_chooser_file; | |||
// defined in fotoxx.h | // defined in fotoxx.h | |||
char color[20]; | ch color[20]; | |||
zdialog *pzdialog; | zdialog *pzdialog; | |||
cchar *pcolorbutt; | ch *pcolorbutt; | |||
uint8 *pRGB; | uint8 *pRGB; | |||
PIXBUF *pixbuf = 0; | PIXBUF *pixbuf = 0; | |||
GtkWidget *frame, *drawarea; | GtkWidget *frame, *drawarea; | |||
} | } | |||
int RGB_chooser(zdialog *pzd, cchar *pbutt, uint8 prgb[3]) | int RGB_chooser(zdialog *pzd, ch *pbutt, uint8 prgb[3]) | |||
{ | { | |||
using namespace RGB_chooser_names; | using namespace RGB_chooser_names; | |||
int RGB_chooser_dialog_event(zdialog *zd, cchar *event); // dialog events function | int RGB_chooser_dialog_event(zdialog *zd, ch *event); // dialog events function | |||
int RGB_chooser_draw(GtkWidget *window, cairo_t *cr); // window draw function | int RGB_chooser_draw(GtkWidget *window, cairo_t *cr); // window draw function | |||
int RGB_chooser_mouse(GtkWidget *window, GdkEventButton *); // window mouse button event | int RGB_chooser_mouse(GtkWidget *window, GdkEventButton *); // window mouse button event | |||
pzdialog = pzd; // copy args from caller | pzdialog = pzd; // copy args from caller | |||
pcolorbutt = pbutt; | pcolorbutt = pbutt; | |||
pRGB = prgb; | pRGB = prgb; | |||
if (! RGB_chooser_file || ! regfile(RGB_chooser_file)) { // default color chooser file | if (! RGB_chooser_file || ! regfile(RGB_chooser_file)) { // default color chooser file | |||
RGB_chooser_file = (char *) zmalloc(200,"color chooser"); | RGB_chooser_file = (ch *) zmalloc(200,"color chooser"); | |||
snprintf(RGB_chooser_file,200,"%s/colorwheel.jpg",get_zdatadir()); // bugfix 22.14 | snprintf(RGB_chooser_file,200,"%s/colorwheel.jpg",get_zdatadir()); // bugfix 22.14 | |||
} | } | |||
/*** | /*** | |||
____________________________________________ | ____________________________________________ | |||
| Color Chooser | | | Color Chooser | | |||
| | | | | | |||
| click on desired color | | | click on desired color | | |||
| ________________________________________ | | | ________________________________________ | | |||
| | | | | | | | | | |||
skipping to change at line 6877 | skipping to change at line 6877 | |||
gtk_widget_add_events(drawarea,GDK_BUTTON_PRESS_MASK); | gtk_widget_add_events(drawarea,GDK_BUTTON_PRESS_MASK); | |||
zdialog_resize(zd,300,0); | zdialog_resize(zd,300,0); | |||
zdialog_run(zd,RGB_chooser_dialog_event,"save"); | zdialog_run(zd,RGB_chooser_dialog_event,"save"); | |||
return 0; | return 0; | |||
} | } | |||
// dialog event and completion function | // dialog event and completion function | |||
int RGB_chooser_dialog_event(zdialog *zd, cchar *event) | int RGB_chooser_dialog_event(zdialog *zd, ch *event) | |||
{ | { | |||
using namespace RGB_chooser_names; | using namespace RGB_chooser_names; | |||
char *pp; | ch *pp; | |||
if (strmatch(event,"escape")) zd->zstat = -2; // escape key | if (strmatch(event,"escape")) zd->zstat = -2; // escape key | |||
if (strmatch(event,"browse")) | if (strmatch(event,"browse")) | |||
{ | { | |||
pp = navi::galleryname; | pp = navi::galleryname; | |||
if (! pp) pp = topfolders[0]; | if (! pp) pp = topfolders[0]; | |||
pp = gallery_select1(pp); | pp = gallery_select1(pp); | |||
if (! pp) return 1; | if (! pp) return 1; | |||
zdialog_stuff(zd,"file",pp); | zdialog_stuff(zd,"file",pp); | |||
skipping to change at line 6980 | skipping to change at line 6980 | |||
// HSL color chooser function | // HSL color chooser function | |||
// Returns color button in callers zdialog. | // Returns color button in callers zdialog. | |||
// Returns selected RGB color in prgb[3] argument. | // Returns selected RGB color in prgb[3] argument. | |||
namespace HSL_chooser_names | namespace HSL_chooser_names | |||
{ | { | |||
zdialog *HSLzdialog; | zdialog *HSLzdialog; | |||
GtkWidget *RGBframe, *RGBcolor; | GtkWidget *RGBframe, *RGBcolor; | |||
GtkWidget *Hframe, *Hscale; | GtkWidget *Hframe, *Hscale; | |||
zdialog *pzdialog; | zdialog *pzdialog; | |||
cchar *pcolorbutt; | ch *pcolorbutt; | |||
uint8 *pRGB; | uint8 *pRGB; | |||
float H, S, L; // chosen HSL color | float H, S, L; // chosen HSL color | |||
float R, G, B; // corresp. RGB color | float R, G, B; // corresp. RGB color | |||
} | } | |||
int HSL_chooser(zdialog *pzd, cchar *pbutt, uint8 prgb[3]) | int HSL_chooser(zdialog *pzd, ch *pbutt, uint8 prgb[3]) | |||
{ | { | |||
using namespace HSL_chooser_names; | using namespace HSL_chooser_names; | |||
void HSL_chooser_RGB(GtkWidget *drawarea, cairo_t *cr, int *); | void HSL_chooser_RGB(GtkWidget *drawarea, cairo_t *cr, int *); | |||
void HSL_chooser_Hscale(GtkWidget *drawarea, cairo_t *cr, int *); | void HSL_chooser_Hscale(GtkWidget *drawarea, cairo_t *cr, int *); | |||
int HSL_chooser_dialog_event(zdialog *zd, cchar *event); | int HSL_chooser_dialog_event(zdialog *zd, ch *event); | |||
pzdialog = pzd; // copy args from caller | pzdialog = pzd; // copy args from caller | |||
pcolorbutt = pbutt; | pcolorbutt = pbutt; | |||
pRGB = prgb; | pRGB = prgb; | |||
/*** | /*** | |||
________________________________________________ | ________________________________________________ | |||
| | | | | | |||
| [#######] [##############################] | | | [#######] [##############################] | | |||
| Color Hue ================[]============== | | | Color Hue ================[]============== | | |||
skipping to change at line 7056 | skipping to change at line 7056 | |||
} | } | |||
// Paint RGBcolor drawing area with RGB color from chosen HSL color | // Paint RGBcolor drawing area with RGB color from chosen HSL color | |||
void HSL_chooser_RGB(GtkWidget *drawarea, cairo_t *cr, int *) | void HSL_chooser_RGB(GtkWidget *drawarea, cairo_t *cr, int *) | |||
{ | { | |||
using namespace HSL_chooser_names; | using namespace HSL_chooser_names; | |||
int ww, hh; | int ww, hh; | |||
int r, g, b; | int r, g, b; | |||
char color[20]; | ch color[20]; | |||
ww = gtk_widget_get_allocated_width(drawarea); // drawing area size | ww = gtk_widget_get_allocated_width(drawarea); // drawing area size | |||
hh = gtk_widget_get_allocated_height(drawarea); | hh = gtk_widget_get_allocated_height(drawarea); | |||
HSLtoRGB(H,S,L,R,G,B); // RGB color from chosen HSL | HSLtoRGB(H,S,L,R,G,B); // RGB color from chosen HSL | |||
cairo_set_source_rgb(cr,R,G,B); | cairo_set_source_rgb(cr,R,G,B); | |||
cairo_rectangle(cr,0,0,ww-1,hh-1); | cairo_rectangle(cr,0,0,ww-1,hh-1); | |||
cairo_fill(cr); | cairo_fill(cr); | |||
skipping to change at line 7110 | skipping to change at line 7110 | |||
cairo_move_to(cr,px,0); | cairo_move_to(cr,px,0); | |||
cairo_line_to(cr,px,hh-1); | cairo_line_to(cr,px,hh-1); | |||
cairo_stroke(cr); | cairo_stroke(cr); | |||
} | } | |||
return; | return; | |||
} | } | |||
// HSL dialog event and completion function | // HSL dialog event and completion function | |||
int HSL_chooser_dialog_event(zdialog *zd, cchar *event) // HSL dialog event function | int HSL_chooser_dialog_event(zdialog *zd, ch *event) // HSL dialog event function | |||
{ | { | |||
using namespace HSL_chooser_names; | using namespace HSL_chooser_names; | |||
if (strmatch(event,"escape")) zd->zstat = -2; // escape key | if (strmatch(event,"escape")) zd->zstat = -2; // escape key | |||
if (zd->zstat) { // zdialog complete | if (zd->zstat) { // zdialog complete | |||
zdialog_free(zd); | zdialog_free(zd); | |||
freeMouse(); | freeMouse(); | |||
HSLzdialog = 0; | HSLzdialog = 0; | |||
return 1; | return 1; | |||
skipping to change at line 7150 | skipping to change at line 7150 | |||
int Fgrad = 1; // gradual or instant transparency | int Fgrad = 1; // gradual or instant transparency | |||
int Mrad; // mouse radius | int Mrad; // mouse radius | |||
float kernel[400][400]; // radius <= 199 | float kernel[400][400]; // radius <= 199 | |||
int E3ww, E3hh; | int E3ww, E3hh; | |||
editfunc EFpaintransp; | editfunc EFpaintransp; | |||
} | } | |||
// menu function | // menu function | |||
void m_paint_transp(GtkWidget *, cchar *menu) | void m_paint_transp(GtkWidget *, ch *menu) | |||
{ | { | |||
using namespace paint_transp_names; | using namespace paint_transp_names; | |||
int paint_transp_dialog_event(zdialog* zd, cchar *event); | int paint_transp_dialog_event(zdialog* zd, ch *event); | |||
void paint_transp_mousefunc(); | void paint_transp_mousefunc(); | |||
cchar *mess1 = "left drag: add transparency \n" | ch *mess1 = "left drag: add transparency \n" | |||
"right drag: add opacity"; | "right drag: add opacity"; | |||
F1_help_topic = "paint transp"; | F1_help_topic = "paint transp"; | |||
Plog(1,"m_paint_transp \n"); | Plog(1,"m_paint_transp \n"); | |||
EFpaintransp.menufunc = m_paint_transp; | EFpaintransp.menufunc = m_paint_transp; | |||
EFpaintransp.menuname = "Paint Transp"; | EFpaintransp.menuname = "Paint Transp"; | |||
EFpaintransp.Farea = 2; // select area OK | EFpaintransp.Farea = 2; // select area OK | |||
EFpaintransp.mousefunc = paint_transp_mousefunc; // mouse function | EFpaintransp.mousefunc = paint_transp_mousefunc; // mouse function | |||
skipping to change at line 7227 | skipping to change at line 7227 | |||
zdialog_fetch(zd,"Fgrad",Fgrad); // instant/gradual paint | zdialog_fetch(zd,"Fgrad",Fgrad); // instant/gradual paint | |||
mode = 1; // start with paint mode | mode = 1; // start with paint mode | |||
takeMouse(paint_transp_mousefunc,drawcursor); // connect mouse function | takeMouse(paint_transp_mousefunc,drawcursor); // connect mouse function | |||
return; | return; | |||
} | } | |||
// dialog event and completion callback function | // dialog event and completion callback function | |||
int paint_transp_dialog_event(zdialog *zd, cchar *event) | int paint_transp_dialog_event(zdialog *zd, ch *event) | |||
{ | { | |||
using namespace paint_transp_names; | using namespace paint_transp_names; | |||
void paint_transp_mousefunc(); | void paint_transp_mousefunc(); | |||
int radius, dx, dy; | int radius, dx, dy; | |||
float rad, kern, stcent, stedge; | float rad, kern, stcent, stedge; | |||
if (strmatch(event,"escape")) zd->zstat = -2; // escape key | if (strmatch(event,"escape")) zd->zstat = -2; // escape key | |||
if (strmatch(event,"done")) zd->zstat = 1; // from edit_setup() or f_save() | if (strmatch(event,"done")) zd->zstat = 1; // from edit_setup() or f_save() | |||
skipping to change at line 7402 | skipping to change at line 7402 | |||
return; | return; | |||
} | } | |||
/******************************************************************************* */ | /******************************************************************************* */ | |||
// Copy in Image function. | // Copy in Image function. | |||
// Copy from one image area to another with variable opacity. | // Copy from one image area to another with variable opacity. | |||
namespace copy_in_image | namespace copy_in_image | |||
{ | { | |||
int dialog_event(zdialog* zd, cchar *event); | int dialog_event(zdialog* zd, ch *event); | |||
void mousefunc(); | void mousefunc(); | |||
void dopixels(int px, int py); // update pixel block | void dopixels(int px, int py); // update pixel block | |||
void savepixB(int px, int py); // save pixel block for poss. undo | void savepixB(int px, int py); // save pixel block for poss. undo | |||
void undolastB(); // undo last pixel block, free memory | void undolastB(); // undo last pixel block, free memory | |||
void freefirstB(); // free memory for first pixel block | void freefirstB(); // free memory for first pixel block | |||
void freeallB(); // free memory for all pixel blocks | void freeallB(); // free memory for all pixel blocks | |||
int mode; // 1/2 = paint / erase | int mode; // 1/2 = paint / erase | |||
int Mrad; // mouse radius | int Mrad; // mouse radius | |||
int xorg1, yorg1; // source pixel origin | int xorg1, yorg1; // source pixel origin | |||
skipping to change at line 7441 | skipping to change at line 7441 | |||
pixBmem_t **pixBmem = 0; // *pixBmem_t[] | pixBmem_t **pixBmem = 0; // *pixBmem_t[] | |||
int pixBmem_cc = 12; // all except pixel array + pad | int pixBmem_cc = 12; // all except pixel array + pad | |||
int pcc4 = 4 * sizeof(float); // pixel cc: RGBA = 4 channels | int pcc4 = 4 * sizeof(float); // pixel cc: RGBA = 4 channels | |||
editfunc EFcopyinimage; | editfunc EFcopyinimage; | |||
} | } | |||
// menu function | // menu function | |||
void m_copy_in_image(GtkWidget *, cchar *menu) // separate paint and copy | void m_copy_in_image(GtkWidget *, ch *menu) // separate paint and copy | |||
{ | { | |||
using namespace copy_in_image; | using namespace copy_in_image; | |||
cchar *mess1 = "left click: set image source location \n" | ch *mess1 = "left click: set image source location \n" | |||
"right click: set corresponding destination"; | "right click: set corresponding destination"; | |||
cchar *mess2 = "left drag: copy image to mouse position \n" | ch *mess2 = "left drag: copy image to mouse position \n" | |||
"right drag: restore original image"; | "right drag: restore original image"; | |||
F1_help_topic = "copy in image"; | F1_help_topic = "copy in image"; | |||
Plog(1,"m_copy_in_image \n"); | Plog(1,"m_copy_in_image \n"); | |||
EFcopyinimage.menufunc = m_copy_in_image; | EFcopyinimage.menufunc = m_copy_in_image; | |||
EFcopyinimage.menuname = "Copy in Image"; | EFcopyinimage.menuname = "Copy in Image"; | |||
EFcopyinimage.Farea = 2; // select area OK | EFcopyinimage.Farea = 2; // select area OK | |||
EFcopyinimage.mousefunc = mousefunc; // mouse function | EFcopyinimage.mousefunc = mousefunc; // mouse function | |||
skipping to change at line 7532 | skipping to change at line 7532 | |||
ac = 0; | ac = 0; | |||
nc = E1pxm->nc; // channels, RGBA | nc = E1pxm->nc; // channels, RGBA | |||
if (nc > 3) ac = 1; // alpha channel present | if (nc > 3) ac = 1; // alpha channel present | |||
takeMouse(mousefunc,drawcursor); // connect mouse function | takeMouse(mousefunc,drawcursor); // connect mouse function | |||
return; | return; | |||
} | } | |||
// dialog event and completion callback function | // dialog event and completion callback function | |||
int copy_in_image::dialog_event(zdialog *zd, cchar *event) | int copy_in_image::dialog_event(zdialog *zd, ch *event) | |||
{ | { | |||
using namespace copy_in_image; | using namespace copy_in_image; | |||
int radius, dx, dy; | int radius, dx, dy; | |||
float rad, kern, opccent, opcedge; | float rad, kern, opccent, opcedge; | |||
if (strmatch(event,"escape")) zd->zstat = -2; // escape key | if (strmatch(event,"escape")) zd->zstat = -2; // escape key | |||
if (strmatch(event,"done")) zd->zstat = 1; // from edit_setup() or f_save() | if (strmatch(event,"done")) zd->zstat = 1; // from edit_setup() or f_save() | |||
if (strmatch(event,"cancel")) zd->zstat = 2; // from f_open() | if (strmatch(event,"cancel")) zd->zstat = 2; // from f_open() | |||
skipping to change at line 7928 | skipping to change at line 7928 | |||
return; | return; | |||
} | } | |||
/******************************************************************************* */ | /******************************************************************************* */ | |||
// Copy From Image function. | // Copy From Image function. | |||
// 'Paint' a target image with pixels from a different source image. | // 'Paint' a target image with pixels from a different source image. | |||
namespace copy_from_image | namespace copy_from_image | |||
{ | { | |||
int dialog_event(zdialog* zd, cchar *event); | int dialog_event(zdialog* zd, ch *event); | |||
void mousefunc(); // generate mouse circle | void mousefunc(); // generate mouse circle | |||
void dopixels(); // copy pixel block to target | void dopixels(); // copy pixel block to target | |||
void save_pixblock(); // save pixel block for poss. undo | void save_pixblock(); // save pixel block for poss. undo | |||
void undo_lastblock(); // undo last pixel block, free memory | void undo_lastblock(); // undo last pixel block, free memory | |||
void free_firstblock(); // free memory for first pixel block | void free_firstblock(); // free memory for first pixel block | |||
void free_allblocks(); // free memory for all pixel blocks | void free_allblocks(); // free memory for all pixel blocks | |||
editfunc EFcopyfromimage; | editfunc EFcopyfromimage; | |||
int mode; // 1/2 = paint / erase | int mode; // 1/2 = paint / erase | |||
skipping to change at line 7979 | skipping to change at line 7979 | |||
uint16 mrad; // radius of pixel block | uint16 mrad; // radius of pixel block | |||
float pixels[][4]; // array of pixels, rows x cols | float pixels[][4]; // array of pixels, rows x cols | |||
} pixblockmem_t; | } pixblockmem_t; | |||
pixblockmem_t **pixblockmem; | pixblockmem_t **pixblockmem; | |||
int pixblockmem_cc = 12; // all except pixel array + pad | int pixblockmem_cc = 12; // all except pixel array + pad | |||
} | } | |||
// menu function | // menu function | |||
void m_copy_from_image(GtkWidget *, cchar *menu) // split source/target processes | void m_copy_from_image(GtkWidget *, ch *menu) // split source/target processes | |||
{ | { | |||
using namespace copy_from_image; | using namespace copy_from_image; | |||
int err, fd; | int err, fd; | |||
size_t cc; | size_t cc; | |||
Plog(1,"m_copy_from_image \n"); | Plog(1,"m_copy_from_image \n"); | |||
fd = shm_open("/fotoxx_copy_from_image",O_RDWR+O_CREAT,0600); // identify memory mapped region | fd = shm_open("/fotoxx_copy_from_image",O_RDWR+O_CREAT,0600); // identify memory mapped region | |||
if (fd < 0) { | if (fd < 0) { | |||
skipping to change at line 8051 | skipping to change at line 8051 | |||
| opacity center [____] [undo all] | | | opacity center [____] [undo all] | | |||
| opacity edge [____] | | | opacity edge [____] | | |||
| | | | | | |||
| [x] paint over transparent areas | | | [x] paint over transparent areas | | |||
| | | | | | |||
| [ OK ] [cancel] | | | [ OK ] [cancel] | | |||
|__________________________________________________| | |__________________________________________________| | |||
****/ | ****/ | |||
cchar *mess1 = "shift + left click: synchronize copy position \n" | ch *mess1 = "shift + left click: synchronize copy position \n" | |||
"left drag: copy source image to mouse \n" | "left drag: copy source image to mouse \n" | |||
"right drag: restore original image"; | "right drag: restore original image"; | |||
zdialog *zd = zdialog_new("Copy From Image",Mwin,"OK","Cancel",null); | zdialog *zd = zdialog_new("Copy From Image",Mwin,"OK","Cancel",null); | |||
EFcopyfromimage.zd = zd; | EFcopyfromimage.zd = zd; | |||
zdialog_add_widget(zd,"hbox","hbr","dialog",0,"space=3"); | zdialog_add_widget(zd,"hbox","hbr","dialog",0,"space=3"); | |||
zdialog_add_widget(zd,"label","labm","dialog",mess1,"space=5"); | zdialog_add_widget(zd,"label","labm","dialog",mess1,"space=5"); | |||
zdialog_add_widget(zd,"hbox","hbsc","dialog",0,"space=5"); | zdialog_add_widget(zd,"hbox","hbsc","dialog",0,"space=5"); | |||
zdialog_add_widget(zd,"label","labsc","hbsc","source image scale","space=3"); | zdialog_add_widget(zd,"label","labsc","hbsc","source image scale","space=3"); | |||
skipping to change at line 8097 | skipping to change at line 8097 | |||
takeMouse(mousefunc,drawcursor); // connect mouse function | takeMouse(mousefunc,drawcursor); // connect mouse function | |||
save_params(); // communicate current file | save_params(); // communicate current file | |||
new_session("-x1 -m \"Copy From Image Slave\" "); // slave process for source image | new_session("-x1 -m \"Copy From Image Slave\" "); // slave process for source image | |||
return; | return; | |||
} | } | |||
// dialog event and completion callback function | // dialog event and completion callback function | |||
int copy_from_image::dialog_event(zdialog *zd, cchar *event) | int copy_from_image::dialog_event(zdialog *zd, ch *event) | |||
{ | { | |||
using namespace copy_from_image; | using namespace copy_from_image; | |||
int dx, dy; | int dx, dy; | |||
float rad, kern, opccent, opcedge; | float rad, kern, opccent, opcedge; | |||
if (strmatch(event,"escape")) zd->zstat = -2; // escape key | if (strmatch(event,"escape")) zd->zstat = -2; // escape key | |||
if (strmatch(event,"done")) zd->zstat = 1; // from edit_setup() or f_save() | if (strmatch(event,"done")) zd->zstat = 1; // from edit_setup() or f_save() | |||
if (strmatch(event,"cancel")) zd->zstat = 2; // from f_open() | if (strmatch(event,"cancel")) zd->zstat = 2; // from f_open() | |||
skipping to change at line 8525 | skipping to change at line 8525 | |||
float Fscale; // source image scale factor | float Fscale; // source image scale factor | |||
int Freq; // source/target coord. flag | int Freq; // source/target coord. flag | |||
float pixels[402*402*4]; // pixel block, max. mrad = 200 | float pixels[402*402*4]; // pixel block, max. mrad = 200 | |||
} mmap_data_t; | } mmap_data_t; | |||
mmap_data_t *mmap_data; // shared memory pointer | mmap_data_t *mmap_data; // shared memory pointer | |||
} | } | |||
// menu function | // menu function | |||
void m_copy_from_image_slave(GtkWidget *, cchar *) // split source/target processes | void m_copy_from_image_slave(GtkWidget *, ch *) // split source/target processes | |||
{ | { | |||
using namespace copy_from_image_slave; | using namespace copy_from_image_slave; | |||
int err, fd; | int err, fd; | |||
int pmpx = 0, pmpy = 0, pmrad = 0; | int pmpx = 0, pmpy = 0, pmrad = 0; | |||
size_t cc; | size_t cc; | |||
F1_help_topic = "copy from image"; | F1_help_topic = "copy from image"; | |||
Plog(1,"m_copy_from_image_slave \n"); | Plog(1,"m_copy_from_image_slave \n"); | |||
skipping to change at line 8556 | skipping to change at line 8556 | |||
zmessageACK(Mwin,"ftruncate() failure: %s",strerror(errno)); | zmessageACK(Mwin,"ftruncate() failure: %s",strerror(errno)); | |||
return; | return; | |||
} | } | |||
mmap_data = (mmap_data_t *) mmap(0,cc,PROT_WRITE,MAP_SHARED,fd,0); // create memory mapped region | mmap_data = (mmap_data_t *) mmap(0,cc,PROT_WRITE,MAP_SHARED,fd,0); // create memory mapped region | |||
if (mmap_data == (void *) -1) { | if (mmap_data == (void *) -1) { | |||
zmessageACK(Mwin,"mmap() failure: %s",strerror(errno)); | zmessageACK(Mwin,"mmap() failure: %s",strerror(errno)); | |||
return; | return; | |||
} | } | |||
char *Pcurr_file = 0; | ch *Pcurr_file = 0; | |||
int Frefresh = 1; | int Frefresh = 1; | |||
int ww, hh; | int ww, hh; | |||
int mpx2, mpy2, mrad2; | int mpx2, mpy2, mrad2; | |||
mrad = 50; | mrad = 50; | |||
while (true) | while (true) | |||
{ | { | |||
zsleep(0.01); | zsleep(0.01); | |||
zmainloop(); | zmainloop(); | |||
skipping to change at line 8702 | skipping to change at line 8702 | |||
{ | { | |||
int Eww, Ehh; | int Eww, Ehh; | |||
int radius; | int radius; | |||
int cpower; | int cpower; | |||
int epower; | int epower; | |||
editfunc EFcopy_prior_edit; | editfunc EFcopy_prior_edit; | |||
} | } | |||
// menu function | // menu function | |||
void m_copy_prior_edit(GtkWidget *, cchar *menu) // menu function | void m_copy_prior_edit(GtkWidget *, ch *menu) // menu function | |||
{ | { | |||
using namespace copy_prior_edit_names; | using namespace copy_prior_edit_names; | |||
int copy_prior_edit_dialog_event(zdialog *, cchar *event); // dialog event function | int copy_prior_edit_dialog_event(zdialog *, ch *event); // dialog event function | |||
void copy_prior_edit_mousefunc(); // mouse function | void copy_prior_edit_mousefunc(); // mouse function | |||
zdialog *zd; | zdialog *zd; | |||
char text[40]; | ch text[40]; | |||
F1_help_topic = "copy prior edit"; | F1_help_topic = "copy prior edit"; | |||
Plog(1,"m_copy_prior_edit \n"); | Plog(1,"m_copy_prior_edit \n"); | |||
if (CEF) { | if (CEF) { | |||
zmessageACK(Mwin,"finish current edit first"); | zmessageACK(Mwin,"finish current edit first"); | |||
return; | return; | |||
} | } | |||
skipping to change at line 8785 | skipping to change at line 8785 | |||
radius = 100; | radius = 100; | |||
cpower = 50; | cpower = 50; | |||
epower = 0; | epower = 0; | |||
zdialog_run(zd,copy_prior_edit_dialog_event,"save"); // run dialog - parallel | zdialog_run(zd,copy_prior_edit_dialog_event,"save"); // run dialog - parallel | |||
return; | return; | |||
} | } | |||
// dialog event and completion function | // dialog event and completion function | |||
int copy_prior_edit_dialog_event(zdialog *zd, cchar *event) | int copy_prior_edit_dialog_event(zdialog *zd, ch *event) | |||
{ | { | |||
using namespace copy_prior_edit_names; | using namespace copy_prior_edit_names; | |||
void copy_prior_edit_mousefunc(); | void copy_prior_edit_mousefunc(); | |||
char text[40]; | ch text[40]; | |||
int nn; | int nn; | |||
if (strmatch(event,"escape")) zd->zstat = -2; // escape key | if (strmatch(event,"escape")) zd->zstat = -2; // escape key | |||
if (strmatch(event,"done")) zd->zstat = 1; // apply and quit | if (strmatch(event,"done")) zd->zstat = 1; // apply and quit | |||
if (strmatch(event,"cancel")) zd->zstat = 2; // cancel | if (strmatch(event,"cancel")) zd->zstat = 2; // cancel | |||
if (zd->zstat) // done or cancel | if (zd->zstat) // done or cancel | |||
{ | { | |||
if (zd->zstat == 1) edit_done(0); // complete edit | if (zd->zstat == 1) edit_done(0); // complete edit | |||
else edit_cancel(0); | else edit_cancel(0); | |||
skipping to change at line 8951 | skipping to change at line 8951 | |||
return; | return; | |||
} | } | |||
/******************************************************************************* */ | /******************************************************************************* */ | |||
// Plugin menu functions | // Plugin menu functions | |||
namespace plugins_names | namespace plugins_names | |||
{ | { | |||
int Nplugins; // plugin menu items | int Nplugins; // plugin menu items | |||
char **plugins = 0; | ch **plugins = 0; | |||
GtkWidget *popup_plugmenu = 0; | GtkWidget *popup_plugmenu = 0; | |||
editfunc EFplugin; | editfunc EFplugin; | |||
} | } | |||
// edit plugins menu or choose and run a plugin function | // edit plugins menu or choose and run a plugin function | |||
void m_plugins(GtkWidget *, cchar *) | void m_plugins(GtkWidget *, ch *) | |||
{ | { | |||
using namespace plugins_names; | using namespace plugins_names; | |||
void m_edit_plugins(GtkWidget *, cchar *); | void m_edit_plugins(GtkWidget *, ch *); | |||
void m_run_plugin(GtkWidget *, cchar *); | void m_run_plugin(GtkWidget *, ch *); | |||
char plugfile[200]; | ch plugfile[200]; | |||
FILE *fid; | FILE *fid; | |||
int ii; | int ii; | |||
F1_help_topic = "plugins"; | F1_help_topic = "plugins"; | |||
Plog(1,"m_plugins \n"); | Plog(1,"m_plugins \n"); | |||
snprintf(plugfile,200,"%s/plugins",get_zhomedir()); // plugins file | snprintf(plugfile,200,"%s/plugins",get_zhomedir()); // plugins file | |||
if (! regfile(plugfile)) { | if (! regfile(plugfile)) { | |||
fid = fopen(plugfile,"w"); // not found, create default | fid = fopen(plugfile,"w"); // not found, create default | |||
skipping to change at line 8993 | skipping to change at line 8993 | |||
Nplugins = zreadfile(plugfile,plugins); // read plugins file | Nplugins = zreadfile(plugfile,plugins); // read plugins file | |||
if (Nplugins < 1) return; | if (Nplugins < 1) return; | |||
popup_plugmenu = create_popmenu(); // create popup menu for plugins | popup_plugmenu = create_popmenu(); // create popup menu for plugins | |||
add_popmenu_item(popup_plugmenu, "Edit Plugins", // 1st entry is Edit Plugins | add_popmenu_item(popup_plugmenu, "Edit Plugins", // 1st entry is Edit Plugins | |||
m_edit_plugins, 0, "Edit plugins menu"); | m_edit_plugins, 0, "Edit plugins menu"); | |||
for (ii = 0; ii < Nplugins; ii++) // add the plugin menu functions | for (ii = 0; ii < Nplugins; ii++) // add the plugin menu functions | |||
{ | { | |||
char *pp = strstr(plugins[ii]," = "); | ch *pp = strstr(plugins[ii]," = "); | |||
if (! pp) { | if (! pp) { | |||
Plog(0,"plugin bad format: %s \n",plugins[ii]); | Plog(0,"plugin bad format: %s \n",plugins[ii]); | |||
continue; | continue; | |||
} | } | |||
*pp = 0; | *pp = 0; | |||
add_popmenu_item(popup_plugmenu, plugins[ii], m_run_plugin, 0, | add_popmenu_item(popup_plugmenu, plugins[ii], m_run_plugin, 0, | |||
"Run as Fotoxx edit function"); | "Run as Fotoxx edit function"); | |||
*pp = ' '; | *pp = ' '; | |||
} | } | |||
popup_menu(Mwin,popup_plugmenu); // popup the menu | popup_menu(Mwin,popup_plugmenu); // popup the menu | |||
return; | return; | |||
} | } | |||
/******************************************************************************* */ | /******************************************************************************* */ | |||
// edit plugins menu | // edit plugins menu | |||
// edit the plugins file in /home/<user>/.fotoxx/plugins | // edit the plugins file in /home/<user>/.fotoxx/plugins | |||
void m_edit_plugins(GtkWidget *, cchar *) | void m_edit_plugins(GtkWidget *, ch *) | |||
{ | { | |||
F1_help_topic = "plugins"; | F1_help_topic = "plugins"; | |||
Plog(1,"m_edit_plugins \n"); | Plog(1,"m_edit_plugins \n"); | |||
if (FGWM != 'F' && FGWM != 'G') return; | if (FGWM != 'F' && FGWM != 'G') return; | |||
zshell("ack","xdg-open %s/plugins",get_zhomedir()); | zshell("ack","xdg-open %s/plugins",get_zhomedir()); | |||
return; | return; | |||
} | } | |||
/******************************************************************************* */ | /******************************************************************************* */ | |||
// process plugin menu selection | // process plugin menu selection | |||
// execute corresponding command using current image file | // execute corresponding command using current image file | |||
void m_run_plugin(GtkWidget *, cchar *menu) | void m_run_plugin(GtkWidget *, ch *menu) | |||
{ | { | |||
using namespace plugins_names; | using namespace plugins_names; | |||
int ii, jj, err; | int ii, jj, err; | |||
char *pp = 0; | ch *pp = 0; | |||
char plugincommand[200], pluginfile[100]; | ch plugincommand[200], pluginfile[100]; | |||
PXM *pxmtemp; | PXM *pxmtemp; | |||
zdialog *zd = 0; | zdialog *zd = 0; | |||
STATB statB; | STATB statB; | |||
time_t modtime1, modtime2; | time_t modtime1, modtime2; | |||
F1_help_topic = "plugins"; | F1_help_topic = "plugins"; | |||
Plog(1,"m_run_plugin \n"); | Plog(1,"m_run_plugin \n"); | |||
Plog(1,"run plugin: %s \n",menu); | Plog(1,"run plugin: %s \n",menu); | |||
skipping to change at line 9127 | skipping to change at line 9127 | |||
RETURN: | RETURN: | |||
if (zd) zdialog_free(zd); | if (zd) zdialog_free(zd); | |||
return; | return; | |||
} | } | |||
/******************************************************************************* */ | /******************************************************************************* */ | |||
// menu function: open a camera RAW file and edit with the Raw Therapee | // menu function: open a camera RAW file and edit with the Raw Therapee | |||
// opens 'clicked_file' if not null, else 'curr_file' if not null | // opens 'clicked_file' if not null, else 'curr_file' if not null | |||
void m_rawtherapee(GtkWidget *, cchar *menu) | void m_rawtherapee(GtkWidget *, ch *menu) | |||
{ | { | |||
char * raw_findexport(cchar *rawfile, time_t RTtime); | ch * raw_findexport(ch *rawfile, time_t RTtime); | |||
char *rawfile = 0, *imagefile = 0; | ch *rawfile = 0, *imagefile = 0; | |||
time_t RTtime; | time_t RTtime; | |||
int err; | int err; | |||
F1_help_topic = "raw therapee"; | F1_help_topic = "raw therapee"; | |||
Plog(1,"m_rawtherapee \n"); | Plog(1,"m_rawtherapee \n"); | |||
if (! Frawtherapee) { | if (! Frawtherapee) { | |||
zmessageACK(Mwin,"Raw Therapee not installed"); | zmessageACK(Mwin,"Raw Therapee not installed"); | |||
return; | return; | |||
skipping to change at line 9192 | skipping to change at line 9192 | |||
Fblock("rawtherapee",0); | Fblock("rawtherapee",0); | |||
m_viewmode(0,"F"); | m_viewmode(0,"F"); | |||
return; | return; | |||
} | } | |||
/******************************************************************************* */ | /******************************************************************************* */ | |||
// menu function: open a camera RAW file and edit with Darktable | // menu function: open a camera RAW file and edit with Darktable | |||
// opens 'clicked_file' if not null, else 'curr_file' if not null | // opens 'clicked_file' if not null, else 'curr_file' if not null | |||
void m_darktable(GtkWidget *, cchar *menu) | void m_darktable(GtkWidget *, ch *menu) | |||
{ | { | |||
char * raw_findexport(cchar *rawfile, time_t RTtime); | ch * raw_findexport(ch *rawfile, time_t RTtime); | |||
char *rawfile = 0, *imagefile = 0; | ch *rawfile = 0, *imagefile = 0; | |||
time_t RTtime; | time_t RTtime; | |||
int err; | int err; | |||
F1_help_topic = "darktable"; | F1_help_topic = "darktable"; | |||
Plog(1,"m_darktable \n"); | Plog(1,"m_darktable \n"); | |||
if (! Fdarktable) { | if (! Fdarktable) { | |||
zmessageACK(Mwin,"Darktable not installed"); | zmessageACK(Mwin,"Darktable not installed"); | |||
return; | return; | |||
skipping to change at line 9258 | skipping to change at line 9258 | |||
m_viewmode(0,"F"); | m_viewmode(0,"F"); | |||
return; | return; | |||
} | } | |||
/******************************************************************************* */ | /******************************************************************************* */ | |||
// Find RT output file: IMAGE file, mod time > RT start time. | // Find RT output file: IMAGE file, mod time > RT start time. | |||
// Search the RAW file folder first, then all image folders. | // Search the RAW file folder first, then all image folders. | |||
// Returned filename is subject for zfree(). | // Returned filename is subject for zfree(). | |||
char * raw_findexport(cchar *rawfile, time_t RTtime) | ch * raw_findexport(ch *rawfile, time_t RTtime) | |||
{ | { | |||
int ii; | int ii; | |||
char command[500], buff[500]; | ch command[500], buff[500]; | |||
char *patt1, *patt2, *pp; | ch *patt1, *patt2, *pp; | |||
STATB statB; | STATB statB; | |||
FILE *fid; | FILE *fid; | |||
Plog(1,"raw_findexport() \n"); | Plog(1,"raw_findexport() \n"); | |||
patt1 = zstrdup(rawfile,"RT findexport",100); // escape blanks for poor find program | patt1 = zstrdup(rawfile,"RT findexport",100); // escape blanks for poor find program | |||
repl_1str(rawfile,patt1," ","\\ "); // (enclosing in quotes does not work) | repl_1str(rawfile,patt1," ","\\ "); // (enclosing in quotes does not work) | |||
pp = strrchr(patt1,'/'); | pp = strrchr(patt1,'/'); | |||
if (! pp) return 0; | if (! pp) return 0; | |||
skipping to change at line 9314 | skipping to change at line 9314 | |||
if (pp) return zstrdup(pp,"RT findexport"); | if (pp) return zstrdup(pp,"RT findexport"); | |||
} | } | |||
return 0; | return 0; | |||
} | } | |||
/******************************************************************************* */ | /******************************************************************************* */ | |||
// extract left and right images from current file, .MPO type | // extract left and right images from current file, .MPO type | |||
void m_extract_mpo(GtkWidget *, cchar *) | void m_extract_mpo(GtkWidget *, ch *) | |||
{ | { | |||
char *pp, *mpofile; | ch *pp, *mpofile; | |||
char *Lfile = 0, *Rfile = 0; | ch *Lfile = 0, *Rfile = 0; | |||
F1_help_topic = "Extract MPO Files"; | F1_help_topic = "Extract MPO Files"; | |||
Plog(1,"m_extract_mpo \n"); | Plog(1,"m_extract_mpo \n"); | |||
mpofile = clicked_file; // use clicked file or current file | mpofile = clicked_file; // use clicked file or current file | |||
clicked_file = 0; | clicked_file = 0; | |||
if (! mpofile) { | if (! mpofile) { | |||
if (! curr_file) goto err1; | if (! curr_file) goto err1; | |||
mpofile = zstrdup(curr_file,"extract MPO"); | mpofile = zstrdup(curr_file,"extract MPO"); | |||
End of changes. 142 change blocks. | ||||
177 lines changed or deleted | 177 lines changed or added |