/* Edouard.Thiel@lif.univ-mrs.fr */ #include #include He_node *princ, *panel1, *panel2, *canvas, *tmp, *mess, *text1, *b_quit, *b_plus, *b_minus; XImage *xi = NULL; int recalc_xi = TRUE; double theV = 1.0; int min (int a, int b) { return (a < b) ? a : b; } void CalcDisque (double V, int width, int height) { int x, y, t, xo = width/2, yo = height/2, r = min(xo,yo) - 10, l; int R, G, B; double H, S; double du1, du2; char bla[200]; HeSetMessageLabel (mess, "Calcul ..."); HeFlushDisplay (); /* Fond blanc */ du1 = HeGetTime(); HeSetXiBg (xi, 255, 255, 255); du1 = HeGetTime() - du1; du2 = HeGetTime(); for (y = -r; y <= 0; y++) { l = sqrt ((double)(r*r - y*y)); for (x = -l; x <= l; x++) { S = sqrt ((double)(x*x + y*y)); /* acos() renvoie angle entre 0 et +PI */ H = (S == 0) ? 0 : acos (x / S) * HE_COLOR_MAXH / (M_PI*2); HeHsvToRgb (H, HE_COLOR_MAXSV * S/r, HE_COLOR_MAXSV * V, &R, &G, &B); t = (yo + y) * width + xo + x; HeSetXiPixel (xi, t, R, G, B); HeHsvToRgb (H+(HE_COLOR_MAXH/2), HE_COLOR_MAXSV * S/r, HE_COLOR_MAXSV * V, &R, &G, &B); t = (yo - y) * width + xo - x; HeSetXiPixel (xi, t, R, G, B); } } du2 = HeGetTime() - du2; sprintf (bla, "Fond %.4f s Calcul %.4f s", du1, du2); HeSetMessageLabel (mess, bla); } void TrouveValeurs (int x, int y, double V, int width, int height) { int R, G, B; double H, S; int xo = width/2, yo = height/2, r = min(xo,yo) - 10, l; char bla[200]; HeSetMessageLabel (mess, ""); x -= xo; y -= yo; if (abs(y) > r) return; l = sqrt ((double)(r*r - y*y)); if (abs(x) > l) return; S = sqrt ((double)(x*x + y*y)); H = (S == 0) ? 0 : acos (x / S) * HE_COLOR_MAXH / (M_PI*2); if (y > 0) H = HE_COLOR_MAXH - H; HeHsvToRgb (H, HE_COLOR_MAXSV * S/r, HE_COLOR_MAXSV * V, &R, &G, &B); sprintf (bla, "RGB = (%d,%d,%d) H = %.1f S = %.3f", R, G, B, H, S/r); HeSetMessageLabel (mess, bla); } void princ_resize (He_node *hn, int width, int height) { /* printf ("princ resizeproc width = %d height = %d\n", width, height); */ HeSetWidth (panel1, width); HeJustify (b_quit, NULL, HE_RIGHT); HeSetWidth (panel2, width); HeJustify (panel2, NULL, HE_BOTTOM); HeExpand (canvas, NULL, HE_RIGHT); HeExpand (canvas, panel2, HE_BOTTOM); } void canvas_resize (He_node *hn, int width, int height) { /* printf ("resize %d %d\n", width, height); */ recalc_xi = TRUE; } void canvas_repaint (He_node *hn, Window win) { /* printf ("repaint %d %d\n", HeGetWidth(canvas), HeGetHeight(canvas)); */ if (recalc_xi == TRUE || xi == NULL) { /* printf (" calcul\n"); */ if (xi != NULL) HeDestroyXi (xi); xi = HeCreateXi (HeGetWidth(hn), HeGetHeight(hn)); CalcDisque (theV, xi->width, xi->height); recalc_xi = FALSE; } HePutXi (win, he_gc, xi, 0, 0); } void canvas_event (He_node_ptr hn, He_event_ptr hev) { switch (hev->type) { case ButtonPress : case MotionNotify : if (hev->sb == 1) TrouveValeurs (hev->sx, hev->sy, theV, xi->width, xi->height); break; } } void grise () { HeSetActive (b_plus, theV<1 ); HeSetActive (b_minus, theV>0 ); } void butt_proc (He_node *hn) { char *name = HeGetButtonLabel (hn); char bla[200]; if (strcmp (name, "Quit") == 0) { HeQuit(0); } else if (strcmp (name, "-") == 0) { if (theV > 0) { theV -= 0.05; if (theV < 0) theV = 0; grise(); sprintf (bla, "%.3f", theV); HeSetTextValue (text1, bla); recalc_xi = TRUE; HePostRepaint(canvas); } } else if (strcmp (name, "+") == 0) { if (theV < 1) { theV += 0.05; if (theV > 1) theV = 1; grise(); sprintf (bla, "%.3f", theV); HeSetTextValue (text1, bla); recalc_xi = TRUE; HePostRepaint(canvas); } } } void text1_proc (He_node *hn) { double tmp = atof (HeGetTextValue(hn)); if (tmp >= 0 && tmp <= 1) { theV = tmp; grise(); recalc_xi = TRUE; HePostRepaint(canvas); } else XBell(he_display, 80); } int main (int argc, char *argv[]) { HeInit (&argc, &argv); princ = HeCreateFrame(); HeSetFrameLabel (princ, "Palette de couleurs HSV"); HeSetFrameResizeProc (princ, princ_resize); panel1 = HeCreatePanel (princ); HeCreateMessageP (panel1, "V:", TRUE); text1 = HeCreateText (panel1); HeSetTextValue (text1, "1.000"); HeSetTextVisibleLen (text1, 6); HeSetTextNotifyProc (text1, text1_proc); HeSetTip (text1, "Value entre 0 et 1"); b_plus = HeCreateButtonP (panel1, "+", butt_proc, NULL); b_minus = HeCreateButtonP (panel1, "-", butt_proc, NULL); grise(); b_quit = HeCreateButtonP (panel1, "Quit", butt_proc, NULL); HeFit(panel1); canvas = HeCreateCanvas (princ); HeSetCanvasRepaintProc (canvas, canvas_repaint); HeSetCanvasResizeProc (canvas, canvas_resize); HeSetCanvasEventProc (canvas, canvas_event); HeJustify (canvas, panel1, HE_TOP); HeSetWidth (canvas, 400); HeSetHeight (canvas, 400); HeSetTip (canvas, "Bouton 1 : affiche les paramètres\n" "R,G,B et H,S du point cliqué."); panel2 = HeCreatePanel (princ); HeJustify (panel2, canvas, HE_TOP); mess = HeCreateMessage (panel2); HeFit(panel2); HeFit (princ); return HeMainLoop (princ); }