class TaskJuggler::Painter::FontMetricsData
The FontMetricsData
objects generate and store the font metrics data for a particular font. The glyph set is currently restricted to US ASCII characters.
Constants
- MAX_GLYPH_INDEX
- MIN_GLYPH_INDEX
Attributes
Public Class Methods
Source
# File lib/taskjuggler/Painter/FontMetricsData.rb, line 33 def initialize(fontName, type = :normal, ptSize = 24, height = nil, wData = nil, kData = nil) @fontName = fontName @type = type @height = height @ptSize = ptSize @averageWidth = 0.0 if wData && kData @charWidth = wData @kerningDelta = kData else generateMetrics end end
The constructor can be used in two different modes. If all font data is supplied, the object just stores the supplied font data. If only the font name is given, the class uses the prawn library to generate the font metrics for the requested font.
Public Instance Methods
Source
# File lib/taskjuggler/Painter/FontMetricsData.rb, line 56 def averageWidth return (@averageWidth * (3.0 / 4.0)).to_i end
The average with of all glyphs.
Source
# File lib/taskjuggler/Painter/FontMetricsData.rb, line 51 def glyphWidth(c) return @charWidth[c] end
Return the width of the glyph c. This must be a single character String
. If the glyph is not known, nil is returned.
Source
# File lib/taskjuggler/Painter/FontMetricsData.rb, line 62 def to_ruby indent = ' ' * 6 s = "#{indent}Font_#{@fontName.gsub(/-/, '_')}_#{@type} = " + "Painter::FontMetricsData.new('#{@fontName}', :#{@type}, " + "#{@ptSize}, #{"%.3f" % @height},\n" s << "#{indent} @charWidth = {" i = 0 @charWidth.each do |c, w| s << (i % 4 == 0 ? "\n#{indent} " : ' ') i += 1 s << "'#{escapedChars(c)}' => #{"%0.3f" % w}," end s << "\n#{indent} },\n" s << "#{indent} @kerningDelta = {" i = 0 @kerningDelta.each do |cp, w| s << (i % 4 == 0 ? "\n#{indent} " : ' ') i += 1 s << "'#{cp}' => #{"%.3f" % w}," end s << "\n#{indent} }\n#{indent})\n" end
Generate the FontMetricsData
initialization code for the particular font. The output will be Ruby syntax.
Private Instance Methods
Source
# File lib/taskjuggler/Painter/FontMetricsData.rb, line 88 def escapedChars(c) c.gsub(/\\/, '\\\\\\\\').gsub(/'/, '\\\\\'') end
Source
# File lib/taskjuggler/Painter/FontMetricsData.rb, line 92 def generateMetrics @pdf = Prawn::Document.new ttfDir = "/usr/share/fonts/truetype/" @pdf.font_families.update( "LiberationSans" => { :bold => "#{ttfDir}LiberationSans-Bold.ttf", :italic => "#{ttfDir}LiberationSans-Italic.ttf", :bold_italic => "#{ttfDir}LiberationSans-BoldItalic.ttf", :normal => "#{ttfDir}LiberationSans-Regular.ttf" } ) @pdf.font(@fontName, :size => @ptSize, :style => @type) # Determine the height of the font. @height = @pdf.height_of("jjggMMWW") @charWidth = {} @averageWidth = 0.0 MIN_GLYPH_INDEX.upto(MAX_GLYPH_INDEX) do |c| char = "" << c begin @charWidth[char] = (w = @pdf.width_of(char)) rescue # the glyph is not in this font. end @averageWidth += w end @averageWidth /= (MAX_GLYPH_INDEX - MIN_GLYPH_INDEX) @kerningDelta = {} MIN_GLYPH_INDEX.upto(MAX_GLYPH_INDEX) do |c1| char1 = "" << c1 next unless (cw1 = glyphWidth(char1)) MIN_GLYPH_INDEX.upto(MAX_GLYPH_INDEX) do |c2| char2 = "" << c2 next unless (cw2 = glyphWidth(char2)) chars = char1 + char2 # The kerneing delta is the difference between the computed width # of the combined characters and the sum of the individual # character widths. delta = @pdf.width_of(chars, :kerning => true) - (cw1 + cw2) # We ususally don't use Strings longer than 100 characters. So we # can ignore kerning deltas below a certain threshhold. if delta.abs > 0.001 @kerningDelta[chars] = delta end end end end