lib/pdf/wrapper/text.rb in pdf-wrapper-0.1.3 vs lib/pdf/wrapper/text.rb in pdf-wrapper-0.2.0

- old
+ new

@@ -1,11 +1,38 @@ module PDF class Wrapper - # change the default font size + # Change the default font size + # + # If no block is provided, the change is permanent. If a block + # is provided, the change will revert at the end of the block + # + # Permanant change: + # + # pdf.font_size 10 + # + # Temporary change: + # + # pdf.font_size 20 + # pdf.text "This text is size 20" + # pdf.font_size(10) do + # pdf.text "This text is size 20" + # end + # pdf.text "This text is size 20" + # def font_size(size) - @default_font_size = size.to_i unless size.nil? + new_size = size.to_i + raise ArgumentError, 'font size must be > 0' if new_size <= 0 + + if block_given? + orig_size = @default_font_size + @default_font_size = new_size + yield + @default_font_size = orig_size + else + @default_font_size = new_size + end end alias font_size= font_size # change the default font to write with def font(fontname, style = nil, weight = nil) @@ -63,20 +90,20 @@ layout = build_pango_layout(str.to_s, textw, options) color(options[:color]) if options[:color] # draw the context on our cairo layout - render_layout(layout, options[:padding], options[:padding], texth, :auto_new_page => false) + render_layout(layout, options[:padding], options[:padding], texth) end end end # Write text to the page # # By default the text will be rendered using all the space within the margins and using - # the default font styling set by default_font(), default_font_size, etc + # the default font styling set by font(), font_size, etc # # There is no way to place a bottom bound (or height) onto the text. Text will wrap as # necessary and take all the room it needs. For finer grained control of text boxes, see the # cell method. # @@ -108,18 +135,19 @@ # Full details on the Pango markup language are avaialble at http://ruby-gnome2.sourceforge.jp/hiki.cgi?pango-markup # # The format is vaguely XML-like. # # Bold: "Some of this text is <b>bold</b>." - # Italics: "Some of this text is in <b>italics</b>." + # Italics: "Some of this text is in <i>italics</i>." # Strikethrough: "My name is <s>Bob</s>James." # Monospace Font: "Code:\n<tt>puts 1</tt>." # # For more advanced control, use span tags # # Big and Bold: Some of this text is <span weight="bold" font_desc="20">bold</span>. # Stretched: Some of this text is <span stretch="extraexpanded">funny looking</span>. + # def text(str, opts={}) # TODO: add converters from various markup languages to pango markup. (markdown, textile, etc) # TODO: add a wrap option so wrapping can be disabled # # the non pango way to add text to the cairo context, not particularly useful for @@ -139,11 +167,11 @@ layout = build_pango_layout(str.to_s, options[:width], options) color(options[:color]) if options[:color] # draw the context on our cairo layout - y = render_layout(layout, options[:left], options[:top], points_to_bottom_margin(options[:top]), :auto_new_page => true) + y = render_layout(layout, options[:left], options[:top]) move_to(options[:left], y) end # Returns the amount of vertical space needed to display the supplied text at the requested width @@ -173,11 +201,11 @@ end private # takes a string and a range of options and creates a pango layout for us. Pango - # does all the hard work of calculating text layout, wrapping, fonts, sizes, + # does all the hard work of calculating text layout, wrapping, fonts, sizes, # direction and more. Thank $diety. # # The string should be encoded using utf-8. If you get unexpected characters in the # rendered output, check the string encoding. Under Ruby 1.9 compatible VMs, any # non utf-8 strings will be automatically converted if possible. @@ -285,17 +313,22 @@ # renders a pango layout onto our main context # based on a function of the same name found in the text2.rb sample file # distributed with rcairo - it's still black magic to me and has a few edge # cases where it doesn't work too well. Needs to be improved. - def render_layout(layout, x, y, h, opts = {}) + # + # If h is specified, lines of text will be rendered up to that height, and + # the rest will be ignored. + # + # If h is nil, lines will be rendered until the bottom margin is hit, then + # a new page will be started and lines will continue being rendered at the + # top of the new page. + def render_layout(layout, x, y, h = nil) # we can't use context.show_pango_layout, as that won't start # a new page if the layout hits the bottom margin. Instead, # we iterate over each line of text in the layout and add it to # the canvas, page breaking as necessary - options = {:auto_new_page => true } - options.merge!(opts) offset = 0 baseline = 0 spacing = layout.spacing / Pango::SCALE @@ -306,20 +339,18 @@ # calculate the relative starting co-ords of this line baseline = iter.baseline / Pango::SCALE linex = logical_rect.x / Pango::SCALE - if baseline - offset >= h - # our text is using the maximum amount of vertical space we want it to - if options[:auto_new_page] - # create a new page and we can continue adding text - offset = baseline - start_new_page - else - # the user doesn't want us to continue on the next page, so - # stop adding lines to the canvas - break - end + if h && baseline - offset >= h + # the user doesn't want us to continue on the next page, so + # stop adding lines to the canvas + break + elsif h.nil? && (y + baseline - offset + spacing) >= self.absolute_bottom_margin + # create a new page and we can continue adding text + offset = baseline + start_new_page + y = self.y end # move to the start of this line @context.move_to(x + linex, y + baseline - offset + spacing)