diff --git a/main.lua b/main.lua index 046c563..fc58005 100644 --- a/main.lua +++ b/main.lua @@ -77,12 +77,15 @@ local function generate_bait_link() end local function fit_font_to_line_height (font_name, height) + assert(type(font_name) == 'string') + assert(type(height) == 'number') + -- local size_min, size_max = 1, 50 while true do local size_guess = math.floor((size_max + size_min)/2) assert(size_min <= size_guess and size_guess <= size_max) local font = assert(imlib.font.load(font_name..'/'..size_guess)) - if size_guess == size_min then return font end + if size_guess == size_min then return font, size_guess end local text_w, text_h = font:get_size 'k' -- if text_h <= height then size_min = size_guess @@ -92,13 +95,21 @@ local function fit_font_to_line_height (font_name, height) return nil end +local function load_font_of_size (font_name, size) + return assert(imlib.font.load(font_name..'/'..size)) +end + local function determine_required_font_size (font_name, text, width) + assert(type(font_name) == 'string') + assert(type(text) == 'string') + assert(type(width) == 'number') + -- local size_min, size_max = 1, 50 while true do local size_guess = math.floor((size_max + size_min)/2) assert(size_min <= size_guess and size_guess <= size_max) - local font = assert(imlib.font.load(font_name..'/'..size_guess)) - if size_guess == size_min then return font end + local font = load_font_of_size(font_name, size_guess) + if size_guess == size_min then return font, size_guess end local text_w, text_h = font:get_size(text) -- if text_w <= width then size_min = size_guess @@ -147,7 +158,7 @@ end local function determine_font_and_lines_for_box (font_name, text, width, height) local num_lines, last_actual, actual_lines = 1, nil, nil - for iteration = 1, 10 do + for iteration = 1, 100 do local estimate_font = determine_required_font_size(font_name, text, width * num_lines) local line_height = select(2, estimate_font:get_size(text)) @@ -167,9 +178,19 @@ local function determine_font_and_lines_for_box (font_name, text, width, height) end assert(actual_lines) - local actual_font = fit_font_to_line_height(font_name, height / #actual_lines) + -- Find final font size + local _, min_font_size = fit_font_to_line_height(font_name, height / #actual_lines) + for _, line in ipairs(actual_lines) do + min_font_size = math.min(min_font_size, select(2, determine_required_font_size(font_name, line, width))) + end + local actual_font = load_font_of_size(font_name, min_font_size) + + -- Assertions and error correction + if (#actual_lines * select(2, actual_font:get_size(text)) < height) then + io.write(' !! Performed bad fitting of text: '..text..'\n') + actual_font, actual_lines = determine_required_font_size(font_name, text, width), {text} + end - assert(#actual_lines * select(2, actual_font:get_size(text)) < height) return actual_font, actual_lines end @@ -400,6 +421,7 @@ local function generate_brain_explosion_image (topics) assert(type(topics) == 'table' and 1 <= #topics and #topics <= BRAIN_MAX_EXPLOSION_TOPICS) -- local base_img = imlib.image.new(BRAIN_ROW_WIDTH * 2, BRAIN_ROW_HEIGHT * #topics) + base_img:fill_rectangle(0, 0, BRAIN_ROW_WIDTH * 2, BRAIN_ROW_HEIGHT * #topics, COLOR_WHITE) local font_name = choose_random_font() -- for i, topic_info in ipairs(topics) do