static int dt_circle_get_area(dt_iop_module_t *module, dt_dev_pixelpipe_iop_t *piece, dt_masks_form_t *form, int *width, int *height, int *posx, int *posy) { // we get the circle values dt_masks_point_circle_t *circle = (dt_masks_point_circle_t *)(g_list_first(form->points)->data); float wd = piece->pipe->iwidth, ht = piece->pipe->iheight; float r = (circle->radius + circle->border) * MIN(wd, ht); int l = (int)(2.0 * M_PI * r); // buffer allocations float *points = calloc(2 * (l + 1), sizeof(float)); // now we set the points points[0] = circle->center[0] * wd; points[1] = circle->center[1] * ht; for(int i = 1; i < l + 1; i++) { float alpha = (i - 1) * 2.0 * M_PI / (float)l; points[i * 2] = points[0] + r * cosf(alpha); points[i * 2 + 1] = points[1] + r * sinf(alpha); } // and we transform them with all distorted modules if(!dt_dev_distort_transform_plus(module->dev, piece->pipe, 0, module->priority, points, l + 1)) { free(points); return 0; } // now we search min and max float xmin, xmax, ymin, ymax; xmin = ymin = FLT_MAX; xmax = ymax = FLT_MIN; for(int i = 1; i < l + 1; i++) { xmin = fminf(points[i * 2], xmin); xmax = fmaxf(points[i * 2], xmax); ymin = fminf(points[i * 2 + 1], ymin); ymax = fmaxf(points[i * 2 + 1], ymax); } free(points); // and we set values *posx = xmin; *posy = ymin; *width = (xmax - xmin); *height = (ymax - ymin); return 1; }
static int dt_gradient_get_area(dt_iop_module_t *module, dt_dev_pixelpipe_iop_t *piece, dt_masks_form_t *form, int *width, int *height, int *posx, int *posy) { float wd = piece->pipe->iwidth, ht = piece->pipe->iheight; float points[8]; // now we set the points points[0] = 0; points[1] = 0; points[2] = wd; points[3] = 0; points[4] = wd; points[5] = ht; points[6] = 0; points[7] = ht; // and we transform them with all distorted modules if(!dt_dev_distort_transform_plus(module->dev, piece->pipe, 0, module->priority, points, 4)) return 0; // now we search min and max float xmin, xmax, ymin, ymax; xmin = ymin = FLT_MAX; xmax = ymax = FLT_MIN; for(int i = 0; i < 4; i++) { xmin = fminf(points[i * 2], xmin); xmax = fmaxf(points[i * 2], xmax); ymin = fminf(points[i * 2 + 1], ymin); ymax = fmaxf(points[i * 2 + 1], ymax); } // and we set values *posx = xmin; *posy = ymin; *width = (xmax - xmin); *height = (ymax - ymin); return 1; }
int dt_dev_distort_transform(dt_develop_t *dev, float *points, int points_count) { return dt_dev_distort_transform_plus(dev,dev->preview_pipe,0,99999,points,points_count); }
static int set_points_from_grad(struct dt_iop_module_t *self, float *xa, float *ya, float *xb, float *yb, float rotation, float offset) { // we get the extremities of the line const float v = (-rotation / 180) * M_PI; const float sinv = sin(v); float pts[4]; dt_dev_pixelpipe_iop_t *piece = dt_dev_distort_get_iop_pipe(self->dev, self->dev->preview_pipe, self); if(!piece) return 0; float wp = piece->buf_out.width, hp = piece->buf_out.height; // if sinv=0 then this is just the offset if(sinv == 0) { if(v == 0) { pts[0] = wp * 0.1; pts[2] = wp * 0.9; pts[1] = pts[3] = hp * offset / 100.0; } else { pts[2] = wp * 0.1; pts[0] = wp * 0.9; pts[1] = pts[3] = hp * (1.0 - offset / 100.0); } } else { // otherwise we determine the extremities const float cosv = cos(v); float xx1 = (sinv - cosv + 1.0 - offset / 50.0) * wp * 0.5 / sinv; float xx2 = (sinv + cosv + 1.0 - offset / 50.0) * wp * 0.5 / sinv; float yy1 = 0; float yy2 = hp; float a = hp / (xx2 - xx1); float b = -xx1 * a; // now ensure that the line isn't outside image borders if(xx2 > wp) { yy2 = a * wp + b; xx2 = wp; } if(xx2 < 0) { yy2 = b; xx2 = 0; } if(xx1 > wp) { yy1 = a * wp + b; xx1 = wp; } if(xx1 < 0) { yy1 = b; xx1 = 0; } // we want extremities not to be on image border xx2 -= (xx2 - xx1) * 0.1; xx1 += (xx2 - xx1) * 0.1; yy2 -= (yy2 - yy1) * 0.1; yy1 += (yy2 - yy1) * 0.1; // now we have to decide which point is where, depending of the angle /*xx1 /= wd; xx2 /= wd; yy1 /= ht; yy2 /= ht;*/ if(v < M_PI * 0.5 && v > -M_PI * 0.5) { // we want xa < xb if(xx1 < xx2) { pts[0] = xx1; pts[1] = yy1; pts[2] = xx2; pts[3] = yy2; } else { pts[2] = xx1; pts[3] = yy1; pts[0] = xx2; pts[1] = yy2; } } else { // we want xb < xa if(xx2 < xx1) { pts[0] = xx1; pts[1] = yy1; pts[2] = xx2; pts[3] = yy2; } else { pts[2] = xx1; pts[3] = yy1; pts[0] = xx2; pts[1] = yy2; } } } // now we want that points to take care of distort modules if(!dt_dev_distort_transform_plus(self->dev, self->dev->preview_pipe, self->priority + 1, 999999, pts, 2)) return 0; *xa = pts[0] / self->dev->preview_pipe->backbuf_width; *ya = pts[1] / self->dev->preview_pipe->backbuf_height; *xb = pts[2] / self->dev->preview_pipe->backbuf_width; *yb = pts[3] / self->dev->preview_pipe->backbuf_height; return 1; }
static int dt_ellipse_get_area(dt_iop_module_t *module, dt_dev_pixelpipe_iop_t *piece, dt_masks_form_t *form, int *width, int *height, int *posx, int *posy) { // we get the ellipse values dt_masks_point_ellipse_t *ellipse = (dt_masks_point_ellipse_t *)(g_list_first(form->points)->data); const float wd = piece->pipe->iwidth, ht = piece->pipe->iheight; const float total[2] = { (ellipse->flags & DT_MASKS_ELLIPSE_PROPORTIONAL ? ellipse->radius[0] * (1.0f + ellipse->border) : ellipse->radius[0] + ellipse->border) * MIN(wd, ht), (ellipse->flags & DT_MASKS_ELLIPSE_PROPORTIONAL ? ellipse->radius[1] * (1.0f + ellipse->border) : ellipse->radius[1] + ellipse->border) * MIN(wd, ht) }; const float v1 = ((ellipse->rotation) / 180.0f) * M_PI; const float v2 = ((ellipse->rotation - 90.0f) / 180.0f) * M_PI; float a, b, v; if(total[0] >= total[1]) { a = total[0]; b = total[1]; v = v1; } else { a = total[1]; b = total[0]; v = v2; } const float sinv = sinf(v); const float cosv = cosf(v); // how many points do we need ? const float lambda = (a - b) / (a + b); const int l = (int)(M_PI * (a + b) * (1.0f + (3.0f * lambda * lambda) / (10.0f + sqrtf(4.0f - 3.0f * lambda * lambda)))); // buffer allocations float *points = calloc(2 * (l + 5), sizeof(float)); // now we set the points const float x = points[0] = ellipse->center[0] * wd; const float y = points[1] = ellipse->center[1] * ht; points[2] = x + a * cos(v); points[3] = y + a * sin(v); points[4] = x - a * cos(v); points[5] = y - a * sin(v); points[6] = x + b * cos(v - M_PI / 2.0f); points[7] = y + b * sin(v - M_PI / 2.0f); points[8] = x - b * cos(v - M_PI / 2.0f); points[9] = y - b * sin(v - M_PI / 2.0f); for(int i = 5; i < l + 5; i++) { float alpha = (i - 5) * 2.0 * M_PI / (float)l; points[i * 2] = x + a * cosf(alpha) * cosv - b * sinf(alpha) * sinv; points[i * 2 + 1] = y + a * cosf(alpha) * sinv + b * sinf(alpha) * cosv; } // and we transform them with all distorted modules if(!dt_dev_distort_transform_plus(module->dev, piece->pipe, 0, module->priority, points, l + 5)) { free(points); return 0; } // now we search min and max float xmin, xmax, ymin, ymax; xmin = ymin = FLT_MAX; xmax = ymax = FLT_MIN; for(int i = 5; i < l + 5; i++) { xmin = fminf(points[i * 2], xmin); xmax = fmaxf(points[i * 2], xmax); ymin = fminf(points[i * 2 + 1], ymin); ymax = fmaxf(points[i * 2 + 1], ymax); } free(points); // and we set values *posx = xmin; *posy = ymin; *width = (xmax - xmin); *height = (ymax - ymin); return 1; }