static void _guides_draw_golden_mean(cairo_t *cr, const float x, const float y, const float w, const float h, const float zoom_scale, void *user_data) { _golden_mean_t *d = (_golden_mean_t *)user_data; // lengths for the golden mean and half the sizes of the region: float w_g = w * INVPHI; float h_g = h * INVPHI; float w_2 = w / 2; float h_2 = h / 2; dt_QRect_t R1, R2, R3, R4, R5, R6, R7; dt_guides_q_rect(&R1, -w_2, -h_2, w_g, h); // w - 2*w_2 corrects for one-pixel difference // so that R2.right() is really at the right end of the region dt_guides_q_rect(&R2, w_g - w_2, h_2 - h_g, w - w_g + 1 - (w - 2 * w_2), h_g); dt_guides_q_rect(&R3, w_2 - R2.width * INVPHI, -h_2, R2.width * INVPHI, h - R2.height); dt_guides_q_rect(&R4, R2.left, R1.top, R3.left - R2.left, R3.height * INVPHI); dt_guides_q_rect(&R5, R4.left, R4.bottom, R4.width * INVPHI, R3.height - R4.height); dt_guides_q_rect(&R6, R5.left + R5.width, R5.bottom - R5.height * INVPHI, R3.left - R5.right, R5.height * INVPHI); dt_guides_q_rect(&R7, R6.right - R6.width * INVPHI, R4.bottom, R6.width * INVPHI, R5.height - R6.height); dt_guides_draw_golden_mean(cr, &R1, &R2, &R3, &R4, &R5, &R6, &R7, d->golden_section, d->golden_triangle, d->golden_spiral_section, d->golden_spiral); }
void gui_post_expose(dt_lib_module_t *self, cairo_t *cr, int32_t width, int32_t height, int32_t pointerx, int32_t pointery) { dt_camera_t *cam = (dt_camera_t*)darktable.camctl->active_camera; dt_lib_live_view_t *lib = self->data; if(cam->is_live_viewing == FALSE || cam->live_view_zoom == TRUE) return; dt_pthread_mutex_lock(&cam->live_view_pixbuf_mutex); if(GDK_IS_PIXBUF(cam->live_view_pixbuf)) { gint pw = gdk_pixbuf_get_width(cam->live_view_pixbuf); gint ph = gdk_pixbuf_get_height(cam->live_view_pixbuf); float w = width-(MARGIN*2.0f); float h = height-(MARGIN*2.0f); float scale = 1.0; // if(cam->live_view_zoom == FALSE) // { if(pw > w) scale = w/pw; if(ph > h) scale = MIN(scale, h/ph); // } float sw = scale*pw; float sh = scale*ph; // draw guides float left = (width - scale*pw)*0.5; float right = left + scale*pw; float top = (height - scale*ph)*0.5; float bottom = top + scale*ph; double dashes = 5.0; cairo_save(cr); cairo_set_dash(cr, &dashes, 1, 0); int which = gtk_combo_box_get_active(GTK_COMBO_BOX(lib->guide_selector)); switch(which) { case GUIDE_GRID: dt_guides_draw_simple_grid(cr, left, top, right, bottom, 1.0); break; case GUIDE_DIAGONAL: dt_guides_draw_diagonal_method(cr, left, top, sw, sh); cairo_stroke (cr); cairo_set_dash (cr, &dashes, 0, 0); cairo_set_source_rgba(cr, .3, .3, .3, .8); dt_guides_draw_diagonal_method(cr, left, top, sw, sh); cairo_stroke (cr); break; case GUIDE_THIRD: dt_guides_draw_rules_of_thirds(cr, left, top, right, bottom, sw/3.0, sh/3.0); cairo_stroke (cr); cairo_set_dash (cr, &dashes, 0, 0); cairo_set_source_rgba(cr, .3, .3, .3, .8); dt_guides_draw_rules_of_thirds(cr, left, top, right, bottom, sw/3.0, sh/3.0); cairo_stroke (cr); break; case GUIDE_TRIANGL: { int dst = (int)((sh*cos(atan(sw/sh)) / (cos(atan(sh/sw))))); // Move coordinates to local center selection. cairo_translate(cr, ((right - left)/2+left), ((bottom - top)/2+top)); // Flip horizontal. if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lib->flipHorGoldenGuide))) cairo_scale(cr, -1, 1); // Flip vertical. if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lib->flipVerGoldenGuide))) cairo_scale(cr, 1, -1); dt_guides_draw_harmonious_triangles(cr, left, top, right, bottom, dst); cairo_stroke (cr); //p.setPen(QPen(d->guideColor, d->guideSize, Qt::DotLine)); cairo_set_dash (cr, &dashes, 0, 0); cairo_set_source_rgba(cr, .3, .3, .3, .8); dt_guides_draw_harmonious_triangles(cr, left, top, right, bottom, dst); cairo_stroke (cr); } break; case GUIDE_GOLDEN: { // Move coordinates to local center selection. cairo_translate(cr, ((right - left)/2+left), ((bottom - top)/2+top)); // Flip horizontal. if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lib->flipHorGoldenGuide))) cairo_scale(cr, -1, 1); // Flip vertical. if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lib->flipVerGoldenGuide))) cairo_scale(cr, 1, -1); float w = sw; float h = sh; // lengths for the golden mean and half the sizes of the region: float w_g = w*INVPHI; float h_g = h*INVPHI; float w_2 = w/2; float h_2 = h/2; dt_QRect_t R1, R2, R3, R4, R5, R6, R7; dt_guides_q_rect (&R1, -w_2, -h_2, w_g, h); // w - 2*w_2 corrects for one-pixel difference // so that R2.right() is really at the right end of the region dt_guides_q_rect (&R2, w_g-w_2, h_2-h_g, w-w_g+1-(w - 2*w_2), h_g); dt_guides_q_rect (&R3, w_2 - R2.width*INVPHI, -h_2, R2.width*INVPHI, h - R2.height); dt_guides_q_rect (&R4, R2.left, R1.top, R3.left - R2.left, R3.height*INVPHI); dt_guides_q_rect (&R5, R4.left, R4.bottom, R4.width*INVPHI, R3.height - R4.height); dt_guides_q_rect (&R6, R5.left + R5.width, R5.bottom - R5.height*INVPHI, R3.left - R5.right, R5.height*INVPHI); dt_guides_q_rect (&R7, R6.right - R6.width*INVPHI, R4.bottom, R6.width*INVPHI, R5.height - R6.height); dt_guides_draw_golden_mean(cr, &R1, &R2, &R3, &R4, &R5, &R6, &R7, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lib->goldenSectionBox)), gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lib->goldenTriangleBox)), gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lib->goldenSpiralSectionBox)), gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lib->goldenSpiralBox)) ); cairo_stroke (cr); cairo_set_dash (cr, &dashes, 0, 0); cairo_set_source_rgba(cr, .3, .3, .3, .8); dt_guides_draw_golden_mean(cr, &R1, &R2, &R3, &R4, &R5, &R6, &R7, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lib->goldenSectionBox)), gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lib->goldenTriangleBox)), gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lib->goldenSpiralSectionBox)), gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lib->goldenSpiralBox)) ); cairo_stroke (cr); } break; } cairo_restore(cr); } dt_pthread_mutex_unlock(&cam->live_view_pixbuf_mutex); }