diff options
Diffstat (limited to 'osd.lua')
| -rw-r--r-- | osd.lua | 103 |
1 files changed, 61 insertions, 42 deletions
@@ -182,19 +182,38 @@ function mt:load_img() '-background', 'none', '-gravity', 'northwest', '-depth', '8', - '-resize', self.img.cmd.w .. 'x' .. self.img.cmd.h, - '-extent', self.img.cmd.w .. 'x' .. self.img.cmd.h, - 'tmp.bgra'} + '-resize', string.format( + 'x%%[fx:max(%d, min(%d, %d*h/w))]', + self.img.min_h, self.img.max_h, self.img.max_w), + '-print', '%w %h', + 'tmp.bgra' + } print('exec: ' .. mp_utils.to_string(cmd)) local res = mp.command_native({ name = 'subprocess', args = cmd, + capture_stdout = true, playback_only = false, }) + if not res or res.status ~= 0 then + return false + end - local loaded = res and res.status == 0 - self.img.loaded = loaded - return loaded + local w, h = res.stdout:match('(.+) (.+)') + self.img.cmd = { + name = 'overlay-add', + id = 0, + file = 'tmp.bgra', + w = w, + h = h, + x = self.img.right - w, + y = self.img.top, + fmt = 'bgra', + offset = 0, + stride = 4*w, + } + + return true end function mt:clear_img(purge) @@ -213,7 +232,7 @@ function mt:draw_img() return end - if not (self.img.loaded or self:load_img()) then + if not (self.img.cmd or self:load_img()) then self:clear_img() return end @@ -230,50 +249,49 @@ function mt:set_img(path, menu_res) local start = self.scale * menu_res.x1 local fs = self.scale * config.font_size - -- width is generally computed to 2/3 (standard aspect ratio of movie - -- posters) of OSD height. when longer OSD text extends into this area, - -- the remaining space is used, with a minimum font-size-derived value - -- when there is not enough (or any) space left, which may overlap the - -- tail end of text. - -- - -- for consistency, any source images with a different aspect ratio are - -- resized, confining them to the area of a "standard" poster. + -- images are scaled to fit the available OSD area when treated as + -- having the 2:3 aspect ratio of a standard film poster. when this + -- results in an image height less than a minimum font-size-derived + -- value, the image is instead scaled to this minimum height. this + -- ensures that a given screen has all images, regardless of original + -- aspect ratio, scaled to either a common width or a common height. -- -- because we have only the total width of the current OSD text, we -- cannot slightly reduce the image width to avoid overlapping some -- longer line at the bottom, as we do not know where the offending -- line is. if it were possible to place images *under* text, maybe -- we'd allow overlap, but mpv currently hard-codes this order. - local ratio = 2/3 - local w = math.floor(math.max(3 * fs * ratio, - math.min(self.width - start - 2*padding, - (self.height - 2*padding) * ratio))) - local h = math.floor(w / ratio) - local x = math.floor(self.width - padding - w) - local y = math.floor(padding) - - local same = self.img and self.img.loaded and path == self.img.path and - w == self.img.cmd.w and h == self.img.cmd.h - if same and x == self.img.cmd.x and y == self.img.cmd.y then - return + local min_h = math.floor(3 * fs) + local max_h = math.floor(math.min( + self.height - 2*padding, + (self.width - start - 2*padding) * 3/2)) + local max_w = math.floor(max_h * 2/3) + local top = math.floor(padding) + local right = math.floor(self.width - padding) + + if self.img and self.img.cmd and path == self.img.path and + min_h == self.img.min_h and max_h == self.img.max_h and + max_w == self.img.max_w then + if top == self.img.top and right == self.img.right then + return false + end + + self.img.top = top + self.img.cmd.y = top + self.img.right = right + self.img.cmd.x = right - self.img.cmd.w + return true end self.img = { path = path, - cmd = { - name = 'overlay-add', - id = 0, - file = 'tmp.bgra', - w = w, - h = h, - x = x, - y = y, - fmt = 'bgra', - offset = 0, - stride = 4*w, - }, - loaded = same, + min_h = min_h, + max_h = max_h, + max_w = max_w, + top = top, + right = right, } + return true end function mt:draw_scrollbar(state) @@ -367,8 +385,9 @@ function mt:redraw(state) end end) - self:set_img(path, res) - self:draw_img() + if self:set_img(path, res) then + self:draw_img() + end else self:clear_img(true) end |
