diff options
-rw-r--r-- | src/x11_cairo.c | 45 |
1 files changed, 35 insertions, 10 deletions
diff --git a/src/x11_cairo.c b/src/x11_cairo.c index be9ae09..eabf46f 100644 --- a/src/x11_cairo.c +++ b/src/x11_cairo.c @@ -1,6 +1,7 @@ -// Copyright 2012-2022 David Robillard <d@drobilla.net> +// Copyright 2012-2023 David Robillard <d@drobilla.net> // SPDX-License-Identifier: ISC +#include "macros.h" #include "types.h" #include "x11.h" @@ -11,7 +12,6 @@ #include <cairo-xlib.h> #include <cairo.h> -#include <math.h> #include <stdlib.h> typedef struct { @@ -20,6 +20,24 @@ typedef struct { cairo_t* cr; } PuglX11CairoSurface; +static PuglViewSize +puglX11CairoGetViewSize(const PuglView* const view) +{ + PuglViewSize size = {0U, 0U}; + + if (view->lastConfigure.type == PUGL_CONFIGURE) { + // Use the size of the last configured frame + size.width = view->lastConfigure.width; + size.height = view->lastConfigure.height; + } else { + // Use the default size + size.width = view->sizeHints[PUGL_DEFAULT_SIZE].width; + size.height = view->sizeHints[PUGL_DEFAULT_SIZE].height; + } + + return size; +} + static void puglX11CairoClose(PuglView* view) { @@ -32,14 +50,10 @@ puglX11CairoClose(PuglView* view) } static PuglStatus -puglX11CairoOpen(PuglView* view, - const double expose_width, - const double expose_height) +puglX11CairoOpen(PuglView* view, const PuglSpan width, const PuglSpan height) { PuglInternals* const impl = view->impl; PuglX11CairoSurface* const surface = (PuglX11CairoSurface*)impl->surface; - const int width = (int)ceil(expose_width); - const int height = (int)ceil(expose_height); surface->back = cairo_xlib_surface_create( view->world->impl->display, impl->win, impl->vi->visual, width, height); @@ -83,9 +97,20 @@ puglX11CairoEnter(PuglView* view, const PuglExposeEvent* expose) PuglX11CairoSurface* const surface = (PuglX11CairoSurface*)impl->surface; PuglStatus st = PUGL_SUCCESS; - if (expose && !(st = puglX11CairoOpen(view, expose->width, expose->height))) { - surface->cr = cairo_create(surface->front); - st = cairo_status(surface->cr) ? PUGL_CREATE_CONTEXT_FAILED : PUGL_SUCCESS; + if (expose) { + const PuglViewSize viewSize = puglX11CairoGetViewSize(view); + const PuglSpan right = expose->x + expose->width; + const PuglSpan bottom = expose->y + expose->height; + const PuglSpan surfaceWidth = MAX(right, viewSize.width); + const PuglSpan surfaceHeight = MAX(bottom, viewSize.height); + if (!(st = puglX11CairoOpen(view, surfaceWidth, surfaceHeight))) { + surface->cr = cairo_create(surface->front); + if (cairo_status(surface->cr)) { + cairo_destroy(surface->cr); + surface->cr = NULL; + st = PUGL_CREATE_CONTEXT_FAILED; + } + } } return st; |