Browse Source

Fix index location issue, working on vertical placement

Contributes to #30

Also added little adjusters for the icons in case your icon is a little off.
[skip ci]
dev
Andy Meneely 11 years ago
parent
commit
42ae2144e0
  1. 8
      lib/squib/api/text_embed.rb
  2. 8
      lib/squib/constants.rb
  3. 44
      lib/squib/graphics/text.rb
  4. 40
      samples/embed_text.rb

8
lib/squib/api/text_embed.rb

@ -17,8 +17,10 @@ module Squib
# @option opts id [String] (nil) if set, then only render the SVG element with the given id. Prefix '#' is optional. Note: the x-y coordinates are still relative to the SVG document's page. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} # @option opts id [String] (nil) if set, then only render the SVG element with the given id. Prefix '#' is optional. Note: the x-y coordinates are still relative to the SVG document's page. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}
# @option opts force_id [Boolean] (false) if set, then this svg will not be rendered at all if the id is empty or nil. If not set, the entire SVG is rendered. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} # @option opts force_id [Boolean] (false) if set, then this svg will not be rendered at all if the id is empty or nil. If not set, the entire SVG is rendered. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}
# @option opts layout [String, Symbol] (nil) entry in the layout to use as defaults for this command. See {file:README.md#Custom_Layouts Custom Layouts}. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} # @option opts layout [String, Symbol] (nil) entry in the layout to use as defaults for this command. See {file:README.md#Custom_Layouts Custom Layouts}. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}
# @option opts width [Integer, :native] (:native) the width of the image rendered # @option opts width [Integer, :native] (:native) the width of the image rendered.
# @option opts height [Integer, :native] the height the height of the image rendered # @option opts height [Integer, :native] the height the height of the image rendered.
# @option opts dx [Integer] (0) "delta x", or adjust the icon horizontally by x pixels
# @option opts dy [Integer] (0) "delta y", or adjust the icon vertically by y pixels
# @option opts alpha [Decimal] (1.0) the alpha-transparency percentage used to blend this image. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} # @option opts alpha [Decimal] (1.0) the alpha-transparency percentage used to blend this image. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}
# @option opts blend [:none, :multiply, :screen, :overlay, :darken, :lighten, :color_dodge, :color_burn, :hard_light, :soft_light, :difference, :exclusion, :hsl_hue, :hsl_saturation, :hsl_color, :hsl_luminosity] (:none) the composite blend operator used when applying this image. See Blend Modes at http://cairographics.org/operators. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} # @option opts blend [:none, :multiply, :screen, :overlay, :darken, :lighten, :color_dodge, :color_burn, :hard_light, :soft_light, :difference, :exclusion, :hsl_hue, :hsl_saturation, :hsl_color, :hsl_luminosity] (:none) the composite blend operator used when applying this image. See Blend Modes at http://cairographics.org/operators. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}
# @option opts angle [FixNum] (0) Rotation of the in radians. Note that this rotates around the upper-left corner, making the placement of x-y coordinates slightly tricky. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} # @option opts angle [FixNum] (0) Rotation of the in radians. Note that this rotates around the upper-left corner, making the placement of x-y coordinates slightly tricky. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}
@ -41,6 +43,8 @@ module Squib
# @option opts layout [String, Symbol] (nil) entry in the layout to use as defaults for this command. See {file:README.md#Custom_Layouts Custom Layouts}. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} # @option opts layout [String, Symbol] (nil) entry in the layout to use as defaults for this command. See {file:README.md#Custom_Layouts Custom Layouts}. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}
# @option opts width [Integer, :native] (:native) the width of the image rendered # @option opts width [Integer, :native] (:native) the width of the image rendered
# @option opts height [Integer, :native] the height the height of the image rendered # @option opts height [Integer, :native] the height the height of the image rendered
# @option opts dx [Integer] (0) "delta x", or adjust the icon horizontally by x pixels
# @option opts dy [Integer] (0) "delta y", or adjust the icon vertically by y pixels
# @option opts alpha [Decimal] (1.0) the alpha-transparency percentage used to blend this image. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} # @option opts alpha [Decimal] (1.0) the alpha-transparency percentage used to blend this image. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}
# @option opts blend [:none, :multiply, :screen, :overlay, :darken, :lighten, :color_dodge, :color_burn, :hard_light, :soft_light, :difference, :exclusion, :hsl_hue, :hsl_saturation, :hsl_color, :hsl_luminosity] (:none) the composite blend operator used when applying this image. See Blend Modes at http://cairographics.org/operators. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} # @option opts blend [:none, :multiply, :screen, :overlay, :darken, :lighten, :color_dodge, :color_burn, :hard_light, :soft_light, :difference, :exclusion, :hsl_hue, :hsl_saturation, :hsl_color, :hsl_luminosity] (:none) the composite blend operator used when applying this image. See Blend Modes at http://cairographics.org/operators. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}
# @option opts angle [FixNum] (0) Rotation of the in radians. Note that this rotates around the upper-left corner, making the placement of x-y coordinates slightly tricky. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} # @option opts angle [FixNum] (0) Rotation of the in radians. Note that this rotates around the upper-left corner, making the placement of x-y coordinates slightly tricky. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}

8
lib/squib/constants.rb

@ -12,6 +12,8 @@ module Squib
:count_format => '%02d', :count_format => '%02d',
:default_font => 'Arial 36', :default_font => 'Arial 36',
:dir => '_output', :dir => '_output',
:dx => 0, # delta
:dy => 0, # delta
:dx1 => 0, :dx1 => 0,
:dx2 => 0, :dx2 => 0,
:dy1 => 0, :dy1 => 0,
@ -147,6 +149,12 @@ module Squib
# value: the user-facing API key (e.g. radius: '1in') # value: the user-facing API key (e.g. radius: '1in')
UNIT_CONVERSION_PARAMS = { UNIT_CONVERSION_PARAMS = {
:circle_radius => :radius, :circle_radius => :radius,
:dx => 0, # delta
:dy => 0, # delta
:dx1 => 0,
:dx2 => 0,
:dy1 => 0,
:dy2 => 0,
:gap => :gap, :gap => :gap,
:height => :height, :height => :height,
:margin => :margin, :margin => :margin,

44
lib/squib/graphics/text.rb

@ -62,15 +62,16 @@ module Squib
# :nodoc: # :nodoc:
# @api private # @api private
def valign!(cc, layout, valign) def compute_valign(layout, valign)
if layout.height > 0 return 0 unless layout.height > 0
ink_extents = layout.extents[1] ink_extents = layout.extents[1]
case valign.to_s.downcase case valign.to_s.downcase
when 'middle' when 'middle'
cc.move_to(0, (layout.height - ink_extents.height) / (2 * Pango::SCALE)) Pango.pixels( (layout.height - ink_extents.height) / 2)
when 'bottom' when 'bottom'
cc.move_to(0, (layout.height - ink_extents.height) / Pango::SCALE) Pango.pixels(layout.height - ink_extents.height)
end else
0
end end
end end
@ -79,7 +80,6 @@ module Squib
def set_wh!(layout, width, height) def set_wh!(layout, width, height)
layout.width = width * Pango::SCALE unless width.nil? || width == :native layout.width = width * Pango::SCALE unless width.nil? || width == :native
layout.height = height * Pango::SCALE unless height.nil? || height == :native layout.height = height * Pango::SCALE unless height.nil? || height == :native
layout
end end
# :nodoc: # :nodoc:
@ -100,15 +100,17 @@ module Squib
# :nodoc: # :nodoc:
# @api private # @api private
def process_embeds(embed, str, layout, cc) def process_embeds(embed, str, layout, vertical_start)
return unless embed.rules.any? return unless embed.rules.any?
while (key = next_embed(embed.rules.keys, str)) != nil layout.markup = str
clean_str = layout.text
while (key = next_embed(embed.rules.keys, clean_str)) != nil
rule = embed.rules[key] rule = embed.rules[key]
spacing = rule[:width] * Pango::SCALE spacing = rule[:width] * Pango::SCALE
index = str.gsub(/<span letter_spacing="\d+"> <\/span>/,' ').index(key) index = clean_str.index(key)
str = str.sub(key, "<span letter_spacing=\"#{spacing.to_i}\"> </span>") str.sub!(key, "<span letter_spacing=\"#{spacing.to_i}\"> </span>")
layout.markup = str layout.markup = str
cc.update_pango_layout(layout) clean_str = layout.text
rect = layout.index_to_pos(index) rect = layout.index_to_pos(index)
iter = layout.iter iter = layout.iter
while iter.next_char! && iter.index < index; end while iter.next_char! && iter.index < index; end
@ -118,8 +120,17 @@ module Squib
Pango::Layout::Alignment::RIGHT 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" 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 end
x = Pango.pixels(rect.x + (letter_width / 2)) x = Pango.pixels(rect.x + (letter_width / 2)) + rule[:dx]
y = Pango.pixels(rect.y) 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) rule[:draw].call(self, x, y)
end end
end end
@ -155,10 +166,13 @@ module Squib
layout.spacing = spacing * Pango::SCALE unless spacing.nil? layout.spacing = spacing * Pango::SCALE unless spacing.nil?
cc.update_pango_layout(layout) cc.update_pango_layout(layout)
valign!(cc, layout, valign) 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.update_pango_layout(layout)
process_embeds(embed, str, layout, cc)
cc.show_pango_layout(layout) cc.show_pango_layout(layout)
draw_text_hint(cc,x,y,layout,hint,angle) draw_text_hint(cc,x,y,layout,hint,angle)
extents = { width: layout.extents[1].width / Pango::SCALE, extents = { width: layout.extents[1].width / Pango::SCALE,

40
samples/embed_text.rb

@ -2,17 +2,47 @@ require 'squib'
Squib::Deck.new do Squib::Deck.new do
background color: :white background color: :white
rect x: 0, y: 0, width: 825, height: 1125 rect x: 0, y: 0, width: 825, height: 1125, stroke_width: 2.0
rect x: 0, y: 0, width: 180, height: 180, stroke_color: :red
embed_text = 'Take 1 :tool:and gain 2 :health:. Take 2 :tool: and gain 3 :purse: if level 2.' embed_text = 'Take 11 :tool: and gain 2 :health:. Take <b>2</b> :tool: <i>and gain 3 :purse: if level 2.</i>'
text(str: embed_text, font: 'Sans 18', text(str: embed_text, font: 'Sans 21',
x: 0, y: 0, width: 180, x: 0, y: 0, width: 180, hint: :red,
align: :left, ellipsize: false, justify: false) do |embed| align: :left, ellipsize: false, justify: false) do |embed|
embed.svg key: ':tool:', width: 28, height: 28, dx: 0, dy: 3, file: 'spanner.svg'
embed.svg key: ':health:', width: 28, height: 28, dx: 2, dy: 3, file: 'glass-heart.svg'
embed.png key: ':purse:', width: 28, height: 28, dx: 0, dy: 3, file: 'shiny-purse.png'
end
embed_text = 'Middle align: Take 1 :tool: and gain 2 :health:. Take 2 :tool: and gain 3 :purse:'
text(str: embed_text, font: 'Sans 21',
x: 200, y: 0, width: 180, height: 300, valign: :middle,
align: :left, ellipsize: false, justify: false, hint: :cyan) do |embed|
embed.svg key: ':tool:', width: 28, height: 28, file: 'spanner.svg'
embed.svg key: ':health:', width: 28, height: 28, file: 'glass-heart.svg'
embed.png key: ':purse:', width: 28, height: 28, file: 'shiny-purse.png'
end
embed_text = 'This :tool: will not align on the bottom properly. :purse:'
text(str: embed_text, font: 'Sans 21',
x: 400, y: 0, width: 180, height: 300, valign: :bottom,
align: :left, ellipsize: false, justify: false, hint: :cyan) do |embed|
embed.svg key: ':tool:', width: 28, height: 28, file: 'spanner.svg' embed.svg key: ':tool:', width: 28, height: 28, file: 'spanner.svg'
embed.svg key: ':health:', width: 28, height: 28, file: 'glass-heart.svg' embed.svg key: ':health:', width: 28, height: 28, file: 'glass-heart.svg'
embed.png key: ':purse:', width: 28, height: 28, file: 'shiny-purse.png' embed.png key: ':purse:', width: 28, height: 28, file: 'shiny-purse.png'
end end
embed_text = 'This :tool: will not align on the bottom properly. :purse:'
text(str: embed_text, font: 'Sans 21',
x: 400, y: 350, width: 180, height: 300, valign: :bottom,
align: :left, ellipsize: false, justify: false, hint: :cyan) do |embed|
# embed.svg key: ':tool:', width: 28, height: 28, file: 'spanner.svg'
# embed.svg key: ':health:', width: 28, height: 28, file: 'glass-heart.svg'
# embed.png key: ':purse:', width: 28, height: 28, file: 'shiny-purse.png'
end
text str: 'But this does align properly', font: 'Sans 21',
x: 600, y: 0, width: 180, height: 300, valign: :bottom,
align: :left, ellipsize: false, justify: false, hint: :cyan
save_png prefix: 'embed_' save_png prefix: 'embed_'
end end
Loading…
Cancel
Save