You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

185 lines
5.7 KiB

require 'pango'
module Squib
class Card
# :nodoc:
# @api private
def draw_text_hint(cc,x,y,layout, color,angle)
color = @deck.text_hint if color.eql? 'off' and not @deck.text_hint.to_s.eql? 'off'
return if color.to_s.eql? 'off' or color.nil?
# when w,h < 0, it was never set. extents[1] are ink extents
w = layout.width / Pango::SCALE
w = layout.extents[1].width / Pango::SCALE if w < 0
h = layout.height / Pango::SCALE
h = layout.extents[1].height / Pango::SCALE if h < 0
cc.rounded_rectangle(0, 0, w, h, 0, 0)
cc.set_source_color(color)
cc.set_line_width(2.0)
cc.stroke
end
# :nodoc:
# @api private
def set_ellipsize!(layout, ellipsize)
case ellipsize.to_s.downcase
when 'none', 'false'
layout.ellipsize = Pango::Layout::ELLIPSIZE_NONE
when 'start'
layout.ellipsize = Pango::Layout::ELLIPSIZE_START
when 'middle'
layout.ellipsize = Pango::Layout::ELLIPSIZE_MIDDLE
when 'end', 'true'
layout.ellipsize = Pango::Layout::ELLIPSIZE_END
end
end
# :nodoc:
# @api private
def set_wrap!(layout, wrap)
case wrap.to_s.downcase
when 'word'
layout.wrap = Pango::Layout::WRAP_WORD
when 'char'
layout.wrap = Pango::Layout::WRAP_CHAR
when 'word_char', 'true'
layout.wrap = Pango::Layout::WRAP_WORD_CHAR
end
end
# :nodoc:
# @api private
def set_align!(layout, align)
case align.to_s.downcase
when 'left'
layout.alignment = Pango::ALIGN_LEFT
when 'right'
layout.alignment = Pango::ALIGN_RIGHT
when 'center'
layout.alignment = Pango::ALIGN_CENTER
end
end
# :nodoc:
# @api private
def compute_valign(layout, valign)
return 0 unless layout.height > 0
ink_extents = layout.extents[1]
case valign.to_s.downcase
when 'middle'
Pango.pixels( (layout.height - ink_extents.height) / 2)
when 'bottom'
Pango.pixels(layout.height - ink_extents.height)
else
0
end
end
# :nodoc:
# @api private
def set_wh!(layout, width, height)
layout.width = width * Pango::SCALE unless width.nil? || width == :native
layout.height = height * Pango::SCALE unless height.nil? || height == :native
end
# :nodoc:
# @api private
def next_embed(keys, str)
ret = nil
ret_key = nil
keys.each do |key|
i = str.index(key)
ret ||= i
unless i.nil? || i > ret
ret = i
ret_key = key
end
end
ret_key
end
# :nodoc:
# @api private
def process_embeds(embed, str, layout, vertical_start)
return unless embed.rules.any?
layout.markup = str
clean_str = layout.text
while (key = next_embed(embed.rules.keys, clean_str)) != nil
rule = embed.rules[key]
spacing = rule[:width] * Pango::SCALE
index = clean_str.index(key)
str.sub!(key, "<span letter_spacing=\"#{spacing.to_i}\"> </span>")
layout.markup = str
clean_str = layout.text
rect = layout.index_to_pos(index)
iter = layout.iter
while iter.next_char! && iter.index < index; end
letter_width = iter.char_extents.width - spacing # the width of our inserted space char
case layout.alignment
when Pango::Layout::Alignment::CENTER,
Pango::Layout::Alignment::RIGHT
Squib.logger.warn "Center- or right-aligned text do not always embed properly. This is a known issue with a workaround. See https://github.com/andymeneely/squib/issues/46"
end
x = Pango.pixels(rect.x + (letter_width / 2)) + rule[:dx]
y = Pango.pixels(rect.y) + rule[:dy] + vertical_start
puts <<-EOS
Embed: #{key}
Index: #{index}
Spacing: #{spacing} or #{Pango.pixels(spacing)}px
Markup string: #{str}
index_to_pos: #{rect.x},#{rect.y} or #{Pango.pixels(rect.x)},#{Pango.pixels(rect.y)}
Computed x,y: #{x},#{y}
=================
EOS
rule[:draw].call(self, x, y)
end
end
# :nodoc:
# @api private
def text(embed,str, font, font_size, color,
x, y, width, height,
markup, justify, wrap, ellipsize,
spacing, align, valign, hint, angle)
Squib.logger.debug {"Placing '#{str}'' with font '#{font}' @ #{x}, #{y}, color: #{color}, angle: #{angle} etc."}
extents = nil
str = str.to_s
use_cairo do |cc|
cc.set_source_squibcolor(color)
cc.translate(x,y)
cc.rotate(angle)
cc.move_to(0, 0)
font_desc = Pango::FontDescription.new(font)
font_desc.size = font_size * Pango::SCALE unless font_size.nil?
layout = cc.create_pango_layout
layout.font_description = font_desc
layout.text = str
layout.markup = str if markup
set_wh!(layout, width, height)
set_wrap!(layout, wrap)
set_ellipsize!(layout, ellipsize)
set_align!(layout, align)
layout.justify = justify unless justify.nil?
layout.spacing = spacing * Pango::SCALE unless spacing.nil?
cc.update_pango_layout(layout)
vertical_start = compute_valign(layout, valign)
process_embeds(embed, str, layout, vertical_start)
cc.move_to(0, vertical_start)
cc.update_pango_layout(layout)
cc.show_pango_layout(layout)
draw_text_hint(cc,x,y,layout,hint,angle)
extents = { width: layout.extents[1].width / Pango::SCALE,
height: layout.extents[1].height / Pango::SCALE }
end
return extents
end
end
end