Xlib + Cairo сохраняет содержимое путем изменения размера - PullRequest
0 голосов
/ 17 ноября 2018

У меня есть небольшой графический интерфейс, использующий Xlib и Cairo для рисования простых вещей (линии, прямоугольники, текст), и я хочу иметь возможность изменить его размер (сделать его больше, чем раньше) без потери содержимого, как X11 обычно обрабатывает изменения размера.

Каир предоставляет функцию cairo_xlib_surface_set_size () (https://www.cairographics.org/manual/cairo-XLib-Surfaces.html#cairo-xlib-surface-set-size) но это также, кажется, удаляет весь текущий контент.

Я пробовал что-то в этом духе , как сохранить содержимое области рисования после изменения размера окна в cairo , но без эффекта, и я не хочу использовать Gtk, потому что это всего лишь простое приложение.

1-й подход (изменение размера, без сохранения):

XSelectInput(display, window, ExposureMask | StructureNotifyMask);

switch (event.type) {
    case ConfigureNotify:
        onConfigure(event);
        break;
}

с

onConfigure(XEvent e) {
    XLockDisplay(display);

    // if resize
    if (e.xconfigure.width != width && e.xconfigure.height != height){

        width = e.xconfigure.width;
        height = e.xconfigure.height;

        cairo_xlib_surface_set_size (sfc, width, height);
        clear(); //without clear the screen just takes on a random color
    }
    cairo_surface_flush(sfc);
    XUnlockDisplay(display);
}

Я также попытался углубиться в исходный код Cairo, чтобы посмотреть, что должен делать cairo_xlib_surface_set_size, и я ничего не увидел для сохранения контента.

2-й подход (сохранение, без изменения размера):

XSelectInput(display, window, ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask | ResizeRedirectMask);

switch (event.type) {
    case ResizeRequest:
        onResize(event);
        break;
}

с

onConfigure(XEvent e) {
    XLockDisplay(display);

    cairo_surface_flush(sfc);
    cairo_xlib_surface_set_size(sfc, e.xresizerequest.width, e.xresizerequest.height);

    width = e.xresizerequest.width;
    height = e.xresizerequest.height;

    XFlush(display);

    XUnlockDisplay(display);
}

Этот 2-й подход изменяет размер окна и сохраняет содержимое, а также устанавливает размер поверхности. Но по какой-то причине он все-таки обрезается в старом размере. Фиолетовые линии должны идти до нижней / правой стороны, но оставаться на прежнем размере поверхности. Я не очень понимаю, почему второй подход делает то, что делает.

...