diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h index 250d28dd..2cd4ac5d 100644 --- a/include/wlr/types/wlr_surface.h +++ b/include/wlr/types/wlr_surface.h @@ -262,4 +262,15 @@ void wlr_surface_for_each_surface(struct wlr_surface *surface, void wlr_surface_get_effective_damage(struct wlr_surface *surface, pixman_region32_t *damage); +/** + * Get the source rectangle describing the region of the buffer that needs to + * be sampled to render this surface's current state. The box is in + * buffer-local coordinates. + * + * If the viewport's source rectangle is unset, the position is zero and the + * size is the buffer's. + */ +void wlr_surface_get_buffer_source_box(struct wlr_surface *surface, + struct wlr_fbox *box); + #endif diff --git a/types/wlr_surface.c b/types/wlr_surface.c index ffaa5223..e4207d36 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -1226,3 +1226,26 @@ void wlr_surface_get_effective_damage(struct wlr_surface *surface, surface->previous.width, surface->previous.height); } } + +void wlr_surface_get_buffer_source_box(struct wlr_surface *surface, + struct wlr_fbox *box) { + box->x = box->y = 0; + box->width = surface->current.buffer_width; + box->height = surface->current.buffer_height; + + if (surface->current.viewport.has_src) { + box->x = surface->current.viewport.src.x * surface->current.scale; + box->y = surface->current.viewport.src.y * surface->current.scale; + box->width = surface->current.viewport.src.width * surface->current.scale; + box->height = surface->current.viewport.src.height * surface->current.scale; + if ((surface->current.transform & WL_OUTPUT_TRANSFORM_90) != 0) { + double tmp = box->x; + box->x = box->y; + box->y = tmp; + + tmp = box->width; + box->width = box->height; + box->height = tmp; + } + } +}