int ProcRRSetCrtcTransform (ClientPtr client) { REQUEST(xRRSetCrtcTransformReq); RRCrtcPtr crtc; PictTransform transform; struct pixman_f_transform f_transform, f_inverse; char *filter; int nbytes; xFixed *params; int nparams; REQUEST_AT_LEAST_SIZE(xRRSetCrtcTransformReq); VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); PictTransform_from_xRenderTransform (&transform, &stuff->transform); pixman_f_transform_from_pixman_transform (&f_transform, &transform); if (!pixman_f_transform_invert (&f_inverse, &f_transform)) return BadMatch; filter = (char *) (stuff + 1); nbytes = stuff->nbytesFilter; params = (xFixed *) (filter + pad_to_int32(nbytes)); nparams = ((xFixed *) stuff + client->req_len) - params; if (nparams < 0) return BadLength; return RRCrtcTransformSet (crtc, &transform, &f_transform, &f_inverse, filter, nbytes, params, nparams); }
static void rescale (GtkWidget *may_be_null, app_t *app) { pixman_f_transform_t ftransform; pixman_transform_t transform; double new_width, new_height; double fscale_x, fscale_y; double rotation; pixman_fixed_t *params; int n_params; double sx, sy; pixman_f_transform_init_identity (&ftransform); if (may_be_null && gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON (get_widget (app, "lock_checkbutton")))) { copy_to_counterpart (app, G_OBJECT (may_be_null)); } fscale_x = gtk_adjustment_get_value (app->scale_x_adjustment); fscale_y = gtk_adjustment_get_value (app->scale_y_adjustment); rotation = gtk_adjustment_get_value (app->rotate_adjustment); fscale_x = to_scale (fscale_x); fscale_y = to_scale (fscale_y); new_width = pixman_image_get_width (app->original) * fscale_x; new_height = pixman_image_get_height (app->original) * fscale_y; pixman_f_transform_scale (&ftransform, NULL, fscale_x, fscale_y); pixman_f_transform_translate (&ftransform, NULL, - new_width / 2.0, - new_height / 2.0); rotation = (rotation / 360.0) * 2 * M_PI; pixman_f_transform_rotate (&ftransform, NULL, cos (rotation), sin (rotation)); pixman_f_transform_translate (&ftransform, NULL, new_width / 2.0, new_height / 2.0); pixman_f_transform_invert (&ftransform, &ftransform); compute_extents (&ftransform, &sx, &sy); pixman_transform_from_pixman_f_transform (&transform, &ftransform); pixman_image_set_transform (app->original, &transform); params = pixman_filter_create_separable_convolution ( &n_params, sx * 65536.0 + 0.5, sy * 65536.0 + 0.5, get_value (app, filters, "reconstruct_x_combo_box"), get_value (app, filters, "reconstruct_y_combo_box"), get_value (app, filters, "sample_x_combo_box"), get_value (app, filters, "sample_y_combo_box"), gtk_adjustment_get_value (app->subsample_adjustment), gtk_adjustment_get_value (app->subsample_adjustment)); pixman_image_set_filter (app->original, PIXMAN_FILTER_SEPARABLE_CONVOLUTION, params, n_params); pixman_image_set_repeat ( app->original, get_value (app, repeats, "repeat_combo_box")); free (params); app->scaled_width = ceil (new_width); app->scaled_height = ceil (new_height); gtk_widget_set_size_request ( get_widget (app, "drawing_area"), new_width + 0.5, new_height + 0.5); gtk_widget_queue_draw ( get_widget (app, "drawing_area")); }