Skip to content

Commit

Permalink
resolves asciidoctor#651 take fallback font into account when calcula…
Browse files Browse the repository at this point in the history
…ting width of string

- introduce rendered_width_of_string and rendered_width_of_char methods
- take width of char from fallback font into account if not glyph not present in font
- calculate width of conum using correct font
  • Loading branch information
mojavelinux committed Mar 27, 2017
1 parent e1a6a6f commit d246224
Showing 1 changed file with 43 additions and 14 deletions.
57 changes: 43 additions & 14 deletions lib/asciidoctor-pdf/converter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ def convert_admonition node
if (transform = @text_transform) && transform != 'none'
label_text = transform_text label_text, transform
end
label_width = width_of label_text
label_width = rendered_width_of_string label_text
label_width = label_min_width if label_min_width && label_min_width > label_width
end
end
Expand Down Expand Up @@ -779,13 +779,15 @@ def convert_colist node
end

def convert_colist_item node
marker_width = width_of %(#{conum_glyph 1}x)

float do
bounding_box [0, cursor], width: marker_width do
@list_numbers << (index = @list_numbers.pop).next
theme_font :conum do
layout_prose index, align: :center, line_height: @theme.conum_line_height, inline_format: false, margin: 0
marker_width = nil
theme_font :conum do
marker_width = rendered_width_of_string %(#{conum_glyph 1}x)
float do
bounding_box [0, cursor], width: marker_width do
@list_numbers << (index = @list_numbers.pop).next
theme_font :conum do
layout_prose index, align: :center, line_height: @theme.conum_line_height, inline_format: false, margin: 0
end
end
end
end
Expand Down Expand Up @@ -900,7 +902,7 @@ def convert_outline_list node
list_indent = 0
elsif (list_indent = @theme.outline_list_indent) > 0
# no-bullet aligns text with left-hand side of bullet position (as though there's no bullet)
list_indent = [list_indent - (width_of %(\u2022x)), 0].max
list_indent = [list_indent - (rendered_width_of_string %(\u2022x)), 0].max
end
else
list_indent = @theme.outline_list_indent
Expand Down Expand Up @@ -944,8 +946,8 @@ def convert_outline_list_item node, complex = false
end

if marker
marker_width = width_of marker
start_position = -marker_width + -(width_of 'x')
marker_width = rendered_width_of_string marker
start_position = -marker_width + -(rendered_width_of_char 'x')
float do
flow_bounding_box start_position, width: marker_width do
layout_prose marker,
Expand Down Expand Up @@ -2267,10 +2269,10 @@ def layout_toc doc, num_levels = 2, toc_page_number = 2, num_front_matter_pages
levels: ((dot_leader_l = @theme.toc_dot_leader_levels) == 'none' ? ::Set.new :
(dot_leader_l && dot_leader_l != 'all' ? dot_leader_l.to_s.split.map(&:to_i).to_set : (0..num_levels).to_set)),
text: (dot_leader_text = @theme.toc_dot_leader_content || DotLeaderTextDefault),
width: dot_leader_text.empty? ? 0 : (width_of dot_leader_text),
width: dot_leader_text.empty? ? 0 : (rendered_width_of_string dot_leader_text),
# TODO spacer gives a little bit of room between dots and page number
spacer: { text: NoBreakSpace, size: (spacer_font_size = @font_size * 0.25) },
spacer_width: (width_of NoBreakSpace, size: spacer_font_size)
spacer_width: (rendered_width_of_char NoBreakSpace, size: spacer_font_size)
}
end
line_metrics = calc_line_metrics @theme.toc_line_height
Expand Down Expand Up @@ -2321,7 +2323,8 @@ def layout_toc_level sections, num_levels, line_metrics, dot_leader, num_front_m
move_cursor_to start_cursor
if dot_leader[:width] > 0 && (dot_leader[:levels].include? sect.level)
pgnum_label_font_settings = { color: @font_color, font: font_family, size: @font_size, styles: font_styles }
pgnum_label_width = width_of pgnum_label
pgnum_label_width = rendered_width_of_string pgnum_label
# WARNING width_of is not accurate if string must use characters from fallback font
sect_title_width = width_of sect_title, inline_format: true
save_font do
# NOTE the same font is used for dot leaders throughout toc
Expand Down Expand Up @@ -2932,6 +2935,32 @@ def width_of_fragments fragments
line_widths.max
end

# Compute the rendered width of a string, taking fallback fonts into account
def rendered_width_of_string str, opts = {}
if str.length == 1
rendered_width_of_char str, opts
elsif (chars = str.each_char).all? {|char| font.glyph_present? char }
width_of_string str, opts
else
char_widths = chars.map {|char| rendered_width_of_char char, opts }
char_widths.reduce(&:+) + (char_widths.length * character_spacing)
end
end

# Compute the rendered width of a char, taking fallback fonts into account
def rendered_width_of_char char, opts = {}
if (font.glyph_present? char) || @fallback_fonts.empty?
width_of_string char, opts
else
@fallback_fonts.each do |fallback_font|
font fallback_font do
return width_of_string char, opts if font.glyph_present? char
end
end
width_of_string char, opts
end
end

# TODO document me, esp the first line formatting functionality
def typeset_text string, line_metrics, opts = {}
move_down line_metrics.padding_top
Expand Down

0 comments on commit d246224

Please sign in to comment.