LINUX.ORG.RU

Не понимаю, как работает cairo_mask_surface

 , , , lgi,


0

2

Собственно, суть проблемы в названии.

Копаюсь с настройкой awesome. Для одного конкретного imagebox'а переопределяю функцию отрисовки, и всё неплохо за одним минусом — cairo отказывается использовать маску.

Вероятно, проблема в моей голове или в каком-то невозможно базовом понятии. Поиск ничего не дал, чтение документации тоже.

-- Это обычная функция отрисовки imagebox'а, за исключением конечных строк
function l_box:draw (wibox, cr, width, height)
    if not self._image then return end

    cr:save()

    if not self.resize_forbidden then
        -- Let's scale the image so that it fits into (width, height)
        local w = self._image:get_width()
        local h = self._image:get_height()
        local aspect = width / w
        local aspect_h = height / h
        if aspect > aspect_h then aspect = aspect_h end

        cr:scale(aspect, aspect)
    end

    -- Вот тут и изменения
    if l_box._mask then -- _mask — это просто true/false
        cr:set_source_rgb(0, 0, 0) -- источник заполняем чёрным
        cr:mask_surface(self._image,0,0) -- как я думаю, это должно заставить cairo
                                         -- закрасить чёрным только те области,
                                         -- которые в self._image непрозрачны. Но почему-то,
                                         -- если добавить эту строчку, ничего не рисуется вообще.
                                         -- Если убрать, то, как и надо, область изображения
                                         -- целиком заливается чёрным.
        cr:paint()
    else
        cr:set_source_surface(self._image, 0, 0)
        cr:paint()
    end

    cr:restore()
end
Очень хочется, чтобы всё таки эта маска заработала, однако куда копать, уже просто не знаю.

imgsrf = cairo.ImageSurface.create_from_png("pixmaps/pointer.png")
ctx.set_source_rgb(1,0,0)
ctx.mask_surface(imgsrf,0,0)

В предположении, что ctx — это context, замазывает красным непрозрачное из «pixmaps/pointer.png».

В mask_surface нужно подсовывать surface, а не картинку. И оно само по себе операция, т.ч. paint не нужен.

frob ★★★★★
()
Ответ на: комментарий от frob

Вообще-то, self._image и есть surface. Я считаю, что это так, исходя из того, что функция

cr:set_source_surface(self._image, 0, 0)
работает как надо.

Sullome
() автор топика
Ответ на: комментарий от Sullome

Допустим.

Тогда без paint должно закрасить чёрным то, что непрозрачно в self._image, а с paint — закрасит, а потом поверх зальёт всё чёрным, т.ч. вся масочная часть будет в пролёте.

Сделай set_source_rgba(1,0,0,.5) между mask_source и paint и посмотри чего выйдет.

frob ★★★★★
()
Ответ на: комментарий от frob
cr:set_source_rgba(1,0,0,0.5)
cr:mask_surface(self._image,0,0)

Ничего. Вообще. Просто ничего не рисуется.

Сейчас попробую создать surface, контекст и т.д. из картинки вручную, не полагаясь на стандартные функции виджета.

Sullome
() автор топика
Ответ на: комментарий от Sullome

А, кстати, рисуется это всё не на чёрном фоне, а на #222222. Точнее, виджет с изображением накладывается на панельку этого цвета.

Sullome
() автор топика
Ответ на: комментарий от frob
        local imgsrf = cairo.ImageSurface.create_from_png("/home/sullome/.themes/DarkNeon/awesome/layouts/fairh.png")
        local cr = cairo.Context.create(imgsrf)
        cr:set_source_rgba(1,0,0,0.5)
        cr:mask_surface(imgsrf,0,0)

Всё равно ничего не рисует. Ошибок тоже не выдаёт.

Однако вот так работает:

local imgsrf = cairo.ImageSurface.create_from_png("/home/sullome/.themes/DarkNeon/awesome/layouts/fairh.png")
local cr = cairo.Context.create(imgsrf)
cr:set_source_surface(imgsrf,0,0)
cr:paint()

Sullome
() автор топика
Ответ на: комментарий от Sullome

Аааа... кажется понял... где засада...

Ты на каком контексте рисовать хочешь?

Если у тебя есть DrawingArea (допустим da), то сделай

cr = da.window.cairo_create()
imgsrf = cairo.ImageSurface.create_from_png("/home/sullome/.themes/DarkNeon/awesome/layouts/fairh.png")
cr.set_source_rgb(0,0,0)
cr.mask_surface(imgsrf,0,0)
cr.set_source_rgba(1,0,0,.5)
cr.paint()
frob ★★★★★
()
Ответ на: комментарий от frob

Есть небольшая проблема. Я понятия не имею, что там вообще есть.

cr (контекст) передаётся в функцию вместе с панелькой (wibox) и шириной-высотой для отрисовки.

Отследить, кто вызывает эту функцию, я не могу, похоже, это происходит внутри самого awesome, уже не на Луа.

Sullome
() автор топика
Ответ на: комментарий от Sullome

Ну, это-то пускай. Сбацай из изображения новую cairo.ImageSurface и сделай на полученном откуда-то контексте mask_surface.

Попробуй убрать своё масштабирование и/или подсунь такое изображение, чтобы по-любому чего-нибудь да закрасилось.

frob ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.