Browse Source

Respect DPI settings in text, add pt unit

This has the compatibility impact that all font sizes should be divided by 3 to maintain their same sizes.

Based on PR #225. Thanks @felixleong!!

Conflicts:
	bin/squib
	lib/squib/graphics/text.rb
dev
Seh Hui, Leong 8 years ago committed by Andy Meneely
parent
commit
f800c131ff
  1. 3
      CHANGELOG.md
  2. 2
      lib/squib/api/text.rb
  3. 5
      lib/squib/api/units.rb
  4. 2
      lib/squib/args/arg_loader.rb
  5. 2
      lib/squib/args/unit_conversion.rb
  6. 7
      lib/squib/constants.rb
  7. 6
      lib/squib/graphics/save_pdf.rb
  8. 3
      lib/squib/graphics/text.rb
  9. 8
      lib/squib/layouts/economy.yml
  10. 8
      lib/squib/layouts/fantasy.yml
  11. 2
      lib/squib/sample_helpers.rb
  12. 6
      samples/autoscale_font/_autoscale_font.rb
  13. 2
      samples/backend/_backend.rb
  14. 4
      samples/basic.rb
  15. 1
      samples/build_groups/Rakefile
  16. 2
      samples/colors/_colors.rb
  17. 2
      samples/colors/_gradients.rb
  18. 6
      samples/config/config_text_markup.rb
  19. 2
      samples/config/custom_config.rb
  20. 6
      samples/data/_csv.rb
  21. 8
      samples/data/_excel.rb
  22. 4
      samples/images/_images.rb
  23. 4
      samples/images/_unicode.rb
  24. 4
      samples/intro/02_options.rb
  25. 4
      samples/intro/part3_layout.yml
  26. 8
      samples/layouts/builtin_layouts.rb
  27. 2
      samples/layouts/custom-layout2.yml
  28. 4
      samples/layouts/layouts.rb
  29. 4
      samples/proofs/_tgc_proofs.rb
  30. 6
      samples/ranges/_ranges.rb
  31. 2
      samples/saves/_hand.rb
  32. 2
      samples/saves/_saves.rb
  33. 2
      samples/saves/_showcase.rb
  34. 28
      samples/text/_embed_text.rb
  35. 16
      samples/text/_text.rb
  36. 34
      samples/text/_text_options.rb
  37. 10
      spec/api/api_units_spec.rb
  38. 5
      spec/args/unit_conversion_spec.rb
  39. 6
      spec/data/samples/autoscale_font/_autoscale_font.rb.txt
  40. 6
      spec/data/samples/text/_embed_text.rb.txt
  41. 12
      spec/data/samples/text/_text_options.rb.txt
  42. 1
      spec/spec_helper.rb

3
CHANGELOG.md

@ -9,6 +9,9 @@ Features:
* `save_sheet` method now supports `rtl` or "right-to-left", for easier duplex printing of backs (#204, #208) by @sparr
* `yaml` method for reading in data, much like `csv` and `xlsx` by @blinks
Compatibility:
* DPI is correctly respected with font sizes now. To convert to Squib v0.14+, divide your old font sizes by 3. By @felixleong
Chores:
* Going back to our policy of locking in our dependencies so that we don't have new gems breaking things.

2
lib/squib/api/text.rb

@ -17,7 +17,7 @@ module Squib
embed = TextEmbed.new(size, custom_colors, layout, dpi, img_dir)
yield(embed) if block_given? # store the opts for later use
extents = Array.new(@cards.size)
range.each { |i| extents[i] = @cards[i].text(embed, para[i], box[i], trans[i], draw[i]) }
range.each { |i| extents[i] = @cards[i].text(embed, para[i], box[i], trans[i], draw[i], dpi) }
return extents
end

5
lib/squib/api/units.rb

@ -8,6 +8,11 @@ module Squib
@dpi * n.to_f
end
# DSL method. See http://squib.readthedocs.io
def points(n)
@dpi / Squib::POINTS_PER_IN * n.to_f
end
# DSL method. See http://squib.readthedocs.io
def cm(n)
@dpi * Squib::INCHES_IN_CM * n.to_f

2
lib/squib/args/arg_loader.rb

@ -17,7 +17,7 @@ module Squib
args[:layout] = prep_layout_args(args[:layout], expand_by: expand_by)
expand_and_set_and_defaultify(args: args, by: expand_by, layout: layout)
validate
convert_units
convert_units dpi: dpi
self
end

2
lib/squib/args/unit_conversion.rb

@ -13,6 +13,8 @@ module Squib
case arg.to_s.rstrip
when /in$/ # ends with "in"
arg.rstrip[0..-2].to_f * dpi
when /pt$/ # ends with "in"
arg.rstrip[0..-2].to_f * dpi / POINTS_PER_IN
when /cm$/ # ends with "cm"
arg.rstrip[0..-2].to_f * dpi * INCHES_IN_CM
when /mm$/ # ends with "mm"

7
lib/squib/constants.rb

@ -3,10 +3,15 @@ module Squib
# System-wide default font
# :nodoc:
# @api public
DEFAULT_FONT = 'Arial 36'
DEFAULT_FONT = 'Arial 12'
# Used for inch-cm conversion
# :nodoc:
# @api private
INCHES_IN_CM = 0.393700787
# Used for points-inch conversion
# :nodoc:
# @api private
POINTS_PER_IN = 72.0
end

6
lib/squib/graphics/save_pdf.rb

@ -12,7 +12,7 @@ module Squib
# @api private
def render_pdf(range, sheet)
cc = init_cc(sheet)
cc.scale(72.0 / @deck.dpi, 72.0 / @deck.dpi) # for bug #62
cc.scale(POINTS_PER_IN / @deck.dpi, POINTS_PER_IN / @deck.dpi) # for bug #62
x, y = sheet.margin, sheet.margin
card_width = @deck.width - 2 * sheet.trim
card_height = @deck.height - 2 * sheet.trim
@ -59,8 +59,8 @@ module Squib
def init_cc(sheet)
Cairo::Context.new(Cairo::PDFSurface.new(
"#{sheet.dir}/#{sheet.file}",
sheet.width * 72.0 / @deck.dpi, #PDF thinks in 72 DPI "points"
sheet.height * 72.0 / @deck.dpi)
sheet.width * POINTS_PER_IN / @deck.dpi, #PDF thinks in 72 DPI "points"
sheet.height * POINTS_PER_IN / @deck.dpi)
)
end

3
lib/squib/graphics/text.rb

@ -123,7 +123,7 @@ module Squib
# :nodoc:
# @api private
def text(embed, para, box, trans, draw)
def text(embed, para, box, trans, draw, dpi)
Squib.logger.debug {"Rendering text with: \n#{para} \nat:\n #{box} \ndraw:\n #{draw} \ntransform: #{trans}"}
extents = nil
use_cairo do |cc|
@ -137,6 +137,7 @@ module Squib
layout = cc.create_pango_layout
layout.font_description = font_desc
layout.text = para.str.to_s
layout.context.resolution = dpi
if para.markup
para.str = @deck.typographer.process(layout.text)
layout.markup = para.str.to_s

8
lib/squib/layouts/economy.yml

@ -19,7 +19,7 @@ description:
height: 275
valign: middle
align: center
font_size: 18
font_size: 6
desc: # alias
extends: description
@ -35,7 +35,7 @@ lower_right:
y: 975
width: 75
height: 75
font_size: 18
font_size: 6
valign: bottom
align: right
lr: #alias
@ -46,7 +46,7 @@ lower_left:
y: 975
width: 75
height: 75
font_size: 18
font_size: 6
valign: bottom
align: left
ll: # alias
@ -57,7 +57,7 @@ copyright:
y: 1025
width: 675
height: 25
font_size: 16
font_size: 5
align: center
valign: bottom
#aliases for copyright

8
lib/squib/layouts/fantasy.yml

@ -42,7 +42,7 @@ description:
height: 275
valign: middle
align: center
font_size: 18
font_size: 6
desc: # alias
extends: description
@ -51,7 +51,7 @@ lower_right:
y: 975
width: 75
height: 75
font_size: 18
font_size: 6
valign: bottom
align: right
lr: #alias
@ -62,7 +62,7 @@ lower_left:
y: 975
width: 75
height: 75
font_size: 18
font_size: 6
valign: bottom
align: left
ll: # alias
@ -73,7 +73,7 @@ copyright:
y: 1025
width: 675
height: 25
font_size: 16
font_size: 5
align: center
valign: bottom
#aliases for copyright

2
lib/squib/sample_helpers.rb

@ -24,7 +24,7 @@ module Squib
text str: str, x: 460, y: @sample_y - 40,
width: 540, height: 180,
valign: 'middle', align: 'center',
font: 'Times New Roman,Serif 24'
font: 'Times New Roman,Serif 8'
yield @sample_x, @sample_y
@sample_y += 200
end

6
samples/autoscale_font/_autoscale_font.rb

@ -7,11 +7,11 @@ def autoscale(str_array)
str_array.map do | str |
case str.length
when 0..15
32
10.66
when 16..20
18
6
else
12
4
end
end
end

2
samples/backend/_backend.rb

@ -5,7 +5,7 @@ Squib::Deck.new(cards: 2, config: '_backend-config.yml') do
# These are all supported by the SVG backend
background color: :gray
text str: 'Hello, world!', y: 500, width: 825, font: 'Sans bold 72', align: :center
text str: 'Hello, world!', y: 500, width: 825, font: 'Sans bold 24', align: :center
rect x: 38, y: 38, width: 750, height: 1050, x_radius: 38, y_radius: 38
circle x: 100, y: 400, radius: 25
triangle x1: 100, y1: 425, x2: 125, y2: 475, x3: 75, y3: 475

4
samples/basic.rb

@ -8,9 +8,9 @@ Squib::Deck.new(width: 825, height: 1125, cards: 3) do
rect x: 38, y: 38, width: 750, height: 1050, radius: 38
rect x: 75, y: 75, width: 128, height: 128, radius: 25
text str: data['name'], x: 220, y: 78, font: 'Arial 54'
text str: data['name'], x: 220, y: 78, font: 'Arial 18'
text str: data['level'], x: 75, y: 85, width: 128,
font: 'Arial 72', align: :center
font: 'Arial 24', align: :center
png range: [0, 2], file: 'shiny-purse.png', x: 620, y: 75
svg range: 1..2, file: 'spanner.svg', x: 620, y: 218

1
samples/build_groups/Rakefile

@ -1,4 +1,5 @@
# Example Rakefile that makes use of build groups
require 'squib'
desc 'Build black-and-white by default'
task default: [:bw]

2
samples/colors/_colors.rb

@ -26,7 +26,7 @@ Squib::Deck.new(width: 3000, height: 1500) do
x, y, w, h = 0, 0, 300, 50
colors.each_with_index do |color, i|
rect x: x, y: y, width: w, height: h, fill_color: color
text str: color.to_s, x: x + 5, y: y + 13, font: 'Sans Bold 16',
text str: color.to_s, x: x + 5, y: y + 13, font: 'Sans Bold 5',
color: (Cairo::Color.parse(color).to_hsv.v > 0.9) ? '#000' : '#fff'
y += h
if y > @height

2
samples/colors/_gradients.rb

@ -27,7 +27,7 @@ Squib::Deck.new do
radius: 15, stroke_color: '#0000'
# Alpha transparency can be used too
text str: 'Hello, world!', x: 75, y: 700, font: 'Sans Bold 72',
text str: 'Hello, world!', x: 75, y: 700, font: 'Sans Bold 24',
color: '(0,0)(825,0) #000f@0.0 #0000@1.0'
save_png prefix: 'gradient_'

6
samples/config/config_text_markup.rb

@ -3,18 +3,18 @@ require 'squib'
Squib::Deck.new(config: 'config_text_markup.yml') do
background color: :white
text str: %{"'Yaml ain't markup', he says"},
x: 10, y: 10, width: 300, height: 200, font: 'Serif 20',
x: 10, y: 10, width: 300, height: 200, font: 'Serif 7',
markup: true, hint: :cyan
text str: 'Notice also the antialiasing method.',
x: 320, y: 10, width: 300, height: 200, font: 'Arial Bold 20'
x: 320, y: 10, width: 300, height: 200, font: 'Arial Bold 7'
save_png prefix: 'config_text_'
end
Squib::Deck.new(config: 'config_disable_quotes.yml') do
text str: %{This has typographic sugar --- and ``explicit'' quotes --- but the quotes are "dumb"},
x: 10, y: 10, width: 300, height: 200, font: 'Serif 20',
x: 10, y: 10, width: 300, height: 200, font: 'Serif 7',
markup: true, hint: :cyan
save_png prefix: 'config_disable_text_'
end

2
samples/config/custom_config.rb

@ -6,7 +6,7 @@ Squib::Deck.new(config: 'custom-config.yml') do
# Hints can be turned on in the config file
text str: 'The Title', x: 0, y: 78, width: 825,
font: 'Arial 72', align: :center
font: 'Arial 24', align: :center
# Progress bars are shown for these commands
# And images are taken from img_dir, not the cwd.

6
samples/data/_csv.rb

@ -5,8 +5,8 @@ Squib::Deck.new(cards: 2) do
# Outputs a hash of arrays with the header names as keys
data = csv file: 'sample.csv'
text str: data['Type'], x: 250, y: 55, font: 'Arial 54'
text str: data['Level'], x: 65, y: 65, font: 'Arial 72'
text str: data['Type'], x: 250, y: 55, font: 'Arial 18'
text str: data['Level'], x: 65, y: 65, font: 'Arial 24'
save format: :png, prefix: 'sample_csv_'
@ -21,7 +21,7 @@ num_cards = data['Name'].size # ...but 4 cards!
Squib::Deck.new(cards: num_cards) do
background color: :white
rect # card border
text str: data['Name'], font: 'Arial 54'
text str: data['Name'], font: 'Arial 18'
save_sheet prefix: 'sample_csv_qty_', columns: 4
end

8
samples/data/_excel.rb

@ -7,9 +7,9 @@ Squib::Deck.new(cards: 3) do
# Outputs a hash of arrays with the header names as keys
data = xlsx file: 'sample.xlsx'
text str: data['Name'], x: 250, y: 55, font: 'Arial 54'
text str: data['Level'], x: 65, y: 65, font: 'Arial 72'
text str: data['Description'], x: 65, y: 600, font: 'Arial 36'
text str: data['Name'], x: 250, y: 55, font: 'Arial 18'
text str: data['Level'], x: 65, y: 65, font: 'Arial 24'
text str: data['Description'], x: 65, y: 600, font: 'Arial 12'
save format: :png, prefix: 'sample_excel_' # save to individual pngs
end
@ -21,7 +21,7 @@ num_cards = data['Name'].size # ...but 4 cards
Squib::Deck.new(cards: num_cards) do
background color: :white
rect # card border
text str: data['Name'], font: 'Arial 54'
text str: data['Name'], font: 'Arial 18'
save_sheet prefix: 'sample_xlsx_qty_', columns: 4
end

4
samples/images/_images.rb

@ -30,7 +30,7 @@ Squib::Deck.new(width: 1000, height: 3000) do
png file: 'sprites.png', x: x - 50, y: y - 50 # entire sprite sheet
rect x: x - 50, y: y - 50, width: 100, height: 100, # draw the crop line
radius: 15, dash: '3 3', stroke_color: 'red', stroke_width: 3
text str: '➜', font: 'Sans Bold 36', x: x + 150, y: y - 35
text str: '➜', font: 'Sans Bold 12', x: x + 150, y: y - 35
png file: 'sprites.png', x: x + 200, y: y - 50, # just the robot golem image
crop_x: 0, crop_y: 0, crop_corner_radius: 15,
crop_width: 100, crop_height: 100
@ -38,7 +38,7 @@ Squib::Deck.new(width: 1000, height: 3000) do
png file: 'sprites.png', x: x - 50, y: y + 50 # entire sprite sheet again
rect x: x + 14, y: y + 50, width: 65, height: 65, # highlight the crop
radius: 25, dash: '3 3', stroke_color: 'red', stroke_width: 3
text str: '➜', font: 'Sans Bold 36', x: x + 150, y: y + 50
text str: '➜', font: 'Sans Bold 12', x: x + 150, y: y + 50
png file: 'sprites.png', x: x + 225, y: y + 50, # just the drakkar ship image, rotated
crop_x: 64, crop_y: 0, crop_corner_x_radius: 25, crop_corner_y_radius: 25,
crop_width: 64, crop_height: 64, angle: Math::PI / 6

4
samples/images/_unicode.rb

@ -15,8 +15,8 @@ Squib::Deck.new(height: (game_chars.size / cols + 1) * cell_height,
game_chars.each_with_index do |c, i|
rect fill_color: %w(#eeee #ffff)[i % 2],
width: cell_width, height: cell_height, x: x, y: y
text str: c.inspect, font: 'Sans 42', x: x, y: y
text str: c, font: 'Sans,Segoe UI Symbol 42', x: x + 300, y: y
text str: c.inspect, font: 'Sans 14', x: x, y: y
text str: c, font: 'Sans,Segoe UI Symbol 14', x: x + 300, y: y
x += cell_width
if i % cols == cols - 1
x = 1

4
samples/intro/02_options.rb

@ -4,11 +4,11 @@ Squib::Deck.new cards: 1 do
background color: '#252322'
rect fill_color: '#0B3736',
x: 38, y: 38, width: 750, height: 1050, radius: 38
text str: 'Robot Golem', font: 'True Crimes, Sans 72',
text str: 'Robot Golem', font: 'True Crimes, Sans 24',
align: :center, x: 75, width: :deck, color: '#DFDFE1', y: 90
svg file: 'auto-repair.svg', x: 75, y: 75, width: 100, height: :scale
svg file: 'robot-golem.svg', x: 75, y: 300, width: 675, height: :scale
text str: 'Draw two cards', font: 'Serif 36',
text str: 'Draw two cards', font: 'Serif 12',
align: :center, width: :deck, color: '#DFDFE1', y: 1000
save_png prefix: 'part2_'
end

4
samples/intro/part3_layout.yml

@ -6,7 +6,7 @@ backdrop:
width: 750
height: 1050
title:
font: 'True Crimes, Sans 72'
font: 'True Crimes, Sans 24'
align: center
color: '#DFDFE1'
x: 75
@ -27,7 +27,7 @@ art:
width: 675
height: 675
power:
font: 'Serif 36'
font: 'Serif 12'
align: center
width: 825
color: '#DFDFE1'

8
samples/layouts/builtin_layouts.rb

@ -5,7 +5,7 @@ require 'squib'
Squib::Deck.new(layout: 'fantasy.yml') do
background color: 'white'
set font: 'Times New Roman,Serif 32'
set font: 'Times New Roman,Serif 10.5'
hint text: '#333' # show extents of text boxes to demo the layout
text str: 'fantasy.yml', layout: :title
@ -26,7 +26,7 @@ end
Squib::Deck.new(layout: 'economy.yml') do
background color: 'white'
set font: 'Times New Roman,Serif 32'
set font: 'Times New Roman,Serif 10.5'
hint text: '#333' # show extents of text boxes to demo the layout
text str: 'economy.yml', layout: :title
@ -54,8 +54,8 @@ end
Squib::Deck.new(layout: 'playing-card.yml') do
background color: 'white'
text str: "A\u2660", layout: :bonus_ul, font: 'Sans bold 100', hint: :red
text str: "A\u2660", layout: :bonus_lr, font: 'Sans bold 100', hint: :red
text str: "A\u2660", layout: :bonus_ul, font: 'Sans bold 33', hint: :red
text str: "A\u2660", layout: :bonus_lr, font: 'Sans bold 33', hint: :red
text str: 'artwork here', layout: :art, hint: :red
save_png prefix: 'layouts_builtin_playing_card_'
end

2
samples/layouts/custom-layout2.yml

@ -8,7 +8,7 @@ subtitle:
height: 60
align: left
valign: middle
font_size: 25
font_size: 8
# This one is completely new
description:
extends: subtitle

4
samples/layouts/layouts.rb

@ -44,8 +44,8 @@ end
# Built-in layouts are easy to use and extend
Squib::Deck.new(layout: 'playing-card.yml') do
text str: "A\u2660", layout: :bonus_ul, font: 'Sans bold 100', hint: :red
text str: "A\u2660", layout: :bonus_lr, font: 'Sans bold 100', hint: :red
text str: "A\u2660", layout: :bonus_ul, font: 'Sans bold 33', hint: :red
text str: "A\u2660", layout: :bonus_lr, font: 'Sans bold 33', hint: :red
text str: 'artwork here', layout: :art, hint: :red
save_png prefix: 'layout_builtin_playing_card_'
end

4
samples/proofs/_tgc_proofs.rb

@ -6,8 +6,8 @@ Squib::Deck.new(width: 825, height: 1125, cards: 1) do
rect x: 38, y: 38, width: 750, height: 1050, x_radius: 38, y_radius: 38
rect x: 75, y: 75, width: 128, height: 128, x_radius: 25, y_radius: 25
text str: 'Mastermind', x: 220, y: 78, font: 'Arial 54'
text str: 3, x: 75, y: 85, width: 128, font: 'Arial 72', align: :center
text str: 'Mastermind', x: 220, y: 78, font: 'Arial 18'
text str: 3, x: 75, y: 85, width: 128, font: 'Arial 24', align: :center
# TGC proof overlay (using alpha-transparency)
png file: 'pokercard.png', x:0, y:0, alpha: 0.5

6
samples/ranges/_ranges.rb

@ -7,12 +7,12 @@ data = { 'name' => ['Thief', 'Grifter', 'Mastermind'],
Squib::Deck.new(width: 825, height: 1125, cards: 3) do
# Default range is :all
background color: :white
text str: data['name'], x: 250, y: 55, font: 'Arial 54'
text str: data['level'], x: 65, y: 40, font: 'Arial 72'
text str: data['name'], x: 250, y: 55, font: 'Arial 18'
text str: data['level'], x: 65, y: 40, font: 'Arial 24'
# Could be explicit about using :all, too
text range: :all,
str: data['type'], x: 40, y: 128, font: 'Arial 18',
str: data['type'], x: 40, y: 128, font: 'Arial 6',
width: 100, align: :center
# Ranges are inclusive, zero-based

2
samples/saves/_hand.rb

@ -4,7 +4,7 @@ Squib::Deck.new(cards: 8, layout: 'playing-card.yml') do
background color: :cyan
rect x: 37, y: 37, width: 750, height: 1050, fill_color: :black, radius: 25
rect x: 75, y: 75, width: 675, height: 975, fill_color: :white, radius: 20
text str: ('A'..'Z').to_a, layout: :bonus_ul, font: 'Sans bold 100'
text str: ('A'..'Z').to_a, layout: :bonus_ul, font: 'Sans bold 33'
# Defaults are sensible
hand # saves to _output/hand.png

2
samples/saves/_saves.rb

@ -7,7 +7,7 @@ Squib::Deck.new(width: 825, height: 1125, cards: 16) do
rect x: 38, y: 38, width: 750, height: 1050,
x_radius: 38, y_radius: 38, stroke: 3.0, dash: '4 4'
text str: (1..16).to_a, x: 220, y: 78, font: 'Arial 54'
text str: (1..16).to_a, x: 220, y: 78, font: 'Arial 18'
# Here's what a regular save_png looks like for just the first card
save_png range: 0, prefix: 'save_png_'

2
samples/saves/_showcase.rb

@ -7,7 +7,7 @@ Squib::Deck.new(cards: 4) do
rect fill_color: '#DED4B9', x: 78, y: 78,
width: '2.25in', height: '3.25in', radius: 32
text str: %w(Grifter Thief Thug Kingpin),
font: 'Helvetica,Sans weight=800 120',
font: 'Helvetica,Sans weight=800 40',
x: 78, y: 78, width: '2.25in', align: :center
svg file: 'spanner.svg', x: (825 - 500) / 2, y: 500, width: 500, height: 500

28
samples/text/_embed_text.rb

@ -5,7 +5,7 @@ Squib::Deck.new do
rect x: 0, y: 0, width: 825, height: 1125, stroke_width: 2.0
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 21',
text(str: embed_text, font: 'Sans 7',
x: 0, y: 0, width: 180, hint: :red,
align: :left, ellipsize: false, justify: false) do |embed|
embed.svg key: ':tool:', width: 28, height: 28, file: 'spanner.svg'
@ -14,7 +14,7 @@ Squib::Deck.new do
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',
text(str: embed_text, font: 'Sans 7',
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'
@ -23,7 +23,7 @@ Squib::Deck.new do
end
embed_text = 'This :tool: aligns on the bottom properly. :purse:'
text(str: embed_text, font: 'Sans 21',
text(str: embed_text, font: 'Sans 7',
x: 400, y: 0, width: 180, height: 300, valign: :bottom,
align: :left, ellipsize: false, justify: false, hint: :green) do |embed|
embed.svg key: ':tool:', width: 28, height: 28, file: 'spanner.svg'
@ -32,14 +32,14 @@ Squib::Deck.new do
end
embed_text = 'Yes, this wraps strangely. We are trying to determine the cause. These are 1 :tool::tool::tool: and these are multiple :tool::tool: :tool::tool:'
text(str: embed_text, font: 'Sans 18',
text(str: embed_text, font: 'Sans 6',
x: 600, y: 0, width: 180, height: 300, wrap: :word_char,
align: :left, ellipsize: false, justify: false, hint: :cyan) do |embed|
embed.svg key: ':tool:', width: 28, height: 28, file: 'spanner.svg'
end
embed_text = ':tool:Justify will :tool: work too, and :purse: with more words just for fun'
text(str: embed_text, font: 'Sans 21',
text(str: embed_text, font: 'Sans 7',
x: 0, y: 320, width: 180, height: 300, valign: :bottom,
align: :left, ellipsize: false, justify: true, hint: :magenta) do |embed|
embed.svg key: ':tool:', width: 28, height: 28, file: 'spanner.svg'
@ -48,7 +48,7 @@ Squib::Deck.new do
end
embed_text = 'Right-aligned works :tool: with :health: and :purse:'
text(str: embed_text, font: 'Sans 21',
text(str: embed_text, font: 'Sans 7',
x: 200, y: 320, width: 180, height: 300, valign: :bottom,
align: :right, ellipsize: false, justify: false, hint: :magenta) do |embed|
embed.svg key: ':tool:', width: 28, height: 28, file: 'spanner.svg'
@ -57,7 +57,7 @@ Squib::Deck.new do
end
embed_text = ':tool:Center-aligned works :tool: with :health: and :purse:'
text(str: embed_text, font: 'Sans 21',
text(str: embed_text, font: 'Sans 7',
x: 400, y: 320, width: 180, height: 300,
align: :center, ellipsize: false, justify: false, hint: :magenta) do |embed|
embed.svg key: ':tool:', width: 28, height: 28, data: File.read('spanner.svg')
@ -66,7 +66,7 @@ Squib::Deck.new do
end
embed_text = 'Markup --- and typography replacements --- with ":tool:" icons <i>won\'t</i> fail'
text(str: embed_text, font: 'Serif 18', markup: true,
text(str: embed_text, font: 'Serif 6', markup: true,
x: 600, y: 320, width: 180, height: 300,
align: :center, hint: :magenta) do |embed|
embed.svg key: ':tool:', width: 28, height: 28, file: 'spanner.svg'
@ -74,18 +74,18 @@ Squib::Deck.new do
embed_text = ':tool:' # JUST the icon
text(str: embed_text, x: 0, y: 640, width: 180, height: 50, markup: true,
font: 'Arial 21', align: :center, valign: :middle, hint: :red) do |embed|
font: 'Arial 7', align: :center, valign: :middle, hint: :red) do |embed|
embed.svg key: ':tool:', width: 28, height: 28, file: 'spanner.svg'
end
embed_text = ':purse:' # JUST the icon
text(str: embed_text, x: 200, y: 640, width: 180, height: 50, markup: true,
font: 'Arial 21', align: :center, valign: :middle, hint: :red) do |embed|
font: 'Arial 7', align: :center, valign: :middle, hint: :red) do |embed|
embed.png key: ':purse:', width: 28, height: 28, file: 'shiny-purse.png'
end
embed_text = ":tool: Death to Nemesis bug 103!! :purse:"
text(str: embed_text, font: 'Sans Bold 24', stroke_width: 2,
text(str: embed_text, font: 'Sans Bold 8', stroke_width: 2,
color: :red, stroke_color: :blue, dash: '3 3', align: :left,
valign: :middle, x: 0, y: 700, width: 380, height: 150,
hint: :magenta) do |embed|
@ -94,7 +94,7 @@ Squib::Deck.new do
end
embed_text = 'You can adjust the icon with dx and dy. Normal: :tool: Adjusted: :heart:'
text(str: embed_text, font: 'Sans 18', x: 400, y: 640, width: 180,
text(str: embed_text, font: 'Sans 6', x: 400, y: 640, width: 180,
height: 300, hint: :magenta) do |embed|
embed.svg key: ':tool:', width: 28, height: 28, file: 'spanner.svg'
embed.svg key: ':heart:', width: 28, height: 28, dx: 10, dy: 10,
@ -102,7 +102,7 @@ Squib::Deck.new do
end
embed_text = "Native sizes work too\n:tool:\n\n\n\n\n\n:shiny-purse:\n\n\n\n\n\n:tool2:"
text(str: embed_text, font: 'Sans 18', x: 600, y: 640, width: 180,
text(str: embed_text, font: 'Sans 6', x: 600, y: 640, width: 180,
height: 475, hint: :magenta) do |embed|
embed.svg key: ':tool:', width: :native, height: :native,
file: 'spanner.svg'
@ -118,7 +118,7 @@ end
Squib::Deck.new(cards: 3) do
background color: :white
str = 'Take 1 :tool: and gain 2 :health:.'
text(str: str, font: 'Sans', font_size: [18, 26, 35],
text(str: str, font: 'Sans', font_size: [6, 8.5, 11.5],
x: 0, y: 0, width: 180, height: 300, valign: :bottom,
align: :left, ellipsize: false, justify: false, hint: :cyan) do |embed|
embed.svg key: ':tool:', width: [28, 42, 56], height: [28, 42, 56], file: 'spanner.svg'

16
samples/text/_text.rb

@ -5,31 +5,31 @@ Squib::Deck.new(width: 1000, height: 1250) do
draw_graph_paper width, height
sample 'Font strings are quite expressive. Specify family, modifiers, then size. Font names with spaces in them should end with a comma to help with parsing.' do |x, y|
text font: 'Arial bold italic 32', str: 'Bold and italic!', x: x, y: y - 50
text font: 'Arial weight=300 32', str: 'Light bold!', x: x, y: y
text font: 'Times New Roman, 32', str: 'Times New Roman', x: x, y: y + 50
text font: 'NoSuchFont,Arial 32', str: 'Arial Backup', x: x, y: y + 100
text font: 'Arial bold italic 11', str: 'Bold and italic!', x: x, y: y - 50
text font: 'Arial weight=300 11', str: 'Light bold!', x: x, y: y
text font: 'Times New Roman, 11', str: 'Times New Roman', x: x, y: y + 50
text font: 'NoSuchFont,Arial 11', str: 'Arial Backup', x: x, y: y + 100
end
sample 'Specify width and height to see a text box. Also: set "hint" to see the extents of your text box' do |x, y|
text str: 'This has fixed width and height.', x: x, y: y,
hint: :red, width: 300, height: 100, font: 'Serif bold 24'
hint: :red, width: 300, height: 100, font: 'Serif bold 8'
end
sample 'If you specify the width only, the text will ellipsize.' do |x, y|
text str: 'The meaning of life is 42', x: x - 50, y: y,
hint: :red, width: 350, font: 'Serif bold 22'
hint: :red, width: 350, font: 'Serif bold 7'
end
sample 'If you specify the width only, and turn off ellipsize, the height will auto-stretch.' do |x, y|
text str: 'This has fixed width, but not fixed height.', x: x, y: y,
hint: :red, width: 300, ellipsize: false, font: 'Serif bold 24'
hint: :red, width: 300, ellipsize: false, font: 'Serif bold 8'
end
sample 'The text method returns the ink extents of each card\'s rendered text. So you can custom-fit a shape around it.' do |x, y|
['Auto fit!', 'Auto fit!!!!' ].each.with_index do |str, i|
text_y = y + i * 50
extents = text str: str, x: x, y: text_y, font: 'Sans Bold 24'
extents = text str: str, x: x, y: text_y, font: 'Sans Bold 8'
# Extents come back as an array of hashes, which can get split out like this
text_width = extents[0][:width]

34
samples/text/_text_options.rb

@ -11,28 +11,28 @@ Squib::Deck.new(width: 825, height: 1125, cards: 3) do
rect x: 30, y: 30, width: 128, height: 128, x_radius: 25, y_radius: 25
# Arrays are rendered over each card
text str: data['name'], x: 250, y: 55, font: 'Arial weight=900 54'
text str: data['level'], x: 65, y: 40, font: 'Arial 72', color: :burnt_orange
text str: data['name'], x: 250, y: 55, font: 'Arial weight=900 18'
text str: data['level'], x: 65, y: 40, font: 'Arial 24', color: :burnt_orange
text str: 'Font strings are expressive!', x:65, y: 200,
font: 'Impact bold italic 36'
font: 'Impact bold italic 12'
text str: 'Font strings are expressive!', x:65, y: 300,
font: 'Arial,Verdana weight=900 style=oblique 36'
font: 'Arial,Verdana weight=900 style=oblique 12'
text str: 'Font string sizes can be overridden per card.', x: 65, y: 350,
font: 'Impact 36', font_size: [16, 20, 24]
font: 'Impact 12', font_size: [5, 7, 8]
text str: 'This text has fixed width, fixed height, center-aligned, middle-valigned, and has a red hint',
hint: :red,
x: 65, y: 400,
width: 300, height: 125,
align: :center, valign: 'MIDDLE', # these can be specified with case-insenstive strings too
font: 'Serif 16'
font: 'Serif 5'
extents = text str: 'Ink extent return value',
x: 65, y: 550,
font: 'Sans Bold', font_size: [16, 20, 24]
font: 'Sans Bold', font_size: [5, 7, 8]
margin = 10
# Extents come back as an array of hashes, which can get split out like this
ws = extents.inject([]) { |arr, ext| arr << ext[:width] + 10; arr }
@ -43,28 +43,28 @@ Squib::Deck.new(width: 825, height: 1125, cards: 3) do
# If width & height are defined and the text will overflow the box, we can ellipsize.
text str: "Ellipsization!\nThe ultimate question of life, the universe, and everything to life and everything is 42",
hint: :green, font: 'Arial 22',
hint: :green, font: 'Arial 7',
x: 450, y: 400,
width: 280, height: 180,
ellipsize: true
# Text hints are guides for showing you how your text boxes are laid out exactly
hint text: :cyan
set font: 'Serif 20' # Impacts all future text calls (unless they specify differently)
set font: 'Serif 7' # Impacts all future text calls (unless they specify differently)
text str: 'Text hints & fonts are globally togglable!', x: 65, y: 625
set font: :default # back to Squib-wide default
hint text: :off
text str: 'See? No hint here.',
x: 565, y: 625,
font: 'Arial 22'
font: 'Arial 7'
# Text can be rotated, in radians, about the upper-left corner of the text box.
text str: 'Rotated',
x: 565, y: 675, angle: 0.2,
font: 'Arial 18', hint: :red
font: 'Arial 6', hint: :red
# Text can be justified, and have newlines
text str: longtext, font: 'Arial 16',
text str: longtext, font: 'Arial 5',
x: 65, y: 700,
width: '1.5in', height: inches(1),
justify: true, spacing: -6
@ -72,7 +72,7 @@ Squib::Deck.new(width: 825, height: 1125, cards: 3) do
# Here's how you embed images into text.
# Pass a block to the method call and use the given context
embed_text = 'Embedded icons! Take 1 :tool: and gain 2:health:. If Level 2, take 2 :tool:'
text(str: embed_text, font: 'Sans 18',
text(str: embed_text, font: 'Sans 6',
x: '1.8in', y: '2.5in', width: '0.85in',
align: :left, ellipsize: false) do |embed|
embed.svg key: ':tool:', width: 28, height: 28, file: 'spanner.svg'
@ -81,22 +81,22 @@ Squib::Deck.new(width: 825, height: 1125, cards: 3) do
text str: 'Fill n <span fgcolor="#ff0000">stroke</span>',
color: :green, stroke_width: 2.0, stroke_color: :blue,
x: '1.8in', y: '2.9in', width: '0.85in', font: 'Sans Bold 26', markup: true
x: '1.8in', y: '2.9in', width: '0.85in', font: 'Sans Bold 9', markup: true
text str: 'Stroke n <span fgcolor="#ff0000">fill</span>',
color: :green, stroke_width: 2.0, stroke_color: :blue, stroke_strategy: :stroke_first,
x: '1.8in', y: '3.0in', width: '0.85in', font: 'Sans Bold 26', markup: true
x: '1.8in', y: '3.0in', width: '0.85in', font: 'Sans Bold 9', markup: true
text str: 'Dotted',
color: :white, stroke_width: 2.0, dash: '4 2', stroke_color: :black,
x: '1.8in', y: '3.1in', width: '0.85in', font: 'Sans Bold 26', markup: true
x: '1.8in', y: '3.1in', width: '0.85in', font: 'Sans Bold 9', markup: true
#
text str: "<b>Markup</b> is <i>quite</i> <s>'easy'</s> <span fgcolor=\"\#ff0000\">awesome</span>. Can't beat those \"smart\" 'quotes', now with 10--20% more en-dashes --- and em-dashes --- with explicit ellipses too...",
markup: true,
x: 50, y: 1000,
width: 750, height: 100,
valign: :bottom,
font: 'Serif 18', hint: :cyan
font: 'Serif 6', hint: :cyan
save prefix: 'text_options_', format: :png
end

10
spec/api/api_units_spec.rb

@ -14,6 +14,16 @@ describe Squib::Deck do
end
end
context '#pt' do
it 'converts inches properly' do
expect(deck.points(1)).to eq 4.166666666666667
end
it 'handles strings too' do
expect(deck.points('1')).to eq 4.166666666666667
end
end
context '#cm' do
it 'converts inches properly' do
expect(deck.cm(1)).to eq 118.1102361

5
spec/args/unit_conversion_spec.rb

@ -15,6 +15,11 @@ describe Squib::Args::UnitConversion do
expect(subject.parse('1 in')).to eq(300)
end
it 'does pt' do
expect(subject.parse('1pt')).to eq(4.166666666666667)
expect(subject.parse('1pt ')).to eq(4.166666666666667)
end
it 'does cm' do
expect(subject.parse('1cm')).to eq(118.1102361)
expect(subject.parse('1cm ')).to eq(118.1102361)

6
spec/data/samples/autoscale_font/_autoscale_font.rb.txt

@ -60,7 +60,7 @@ cairo: set_source_color(["black"])
cairo: translate([10, 10])
cairo: rotate([0])
cairo: move_to([0, 0])
pango font: size=([32768])
pango font: size=([10915.84])
pango: font_description=([MockDouble])
pango: text=(["Short & Big"])
pango: width=([286720])
@ -82,7 +82,7 @@ cairo: set_source_color(["black"])
cairo: translate([10, 10])
cairo: rotate([0])
cairo: move_to([0, 0])
pango font: size=([18432])
pango font: size=([6144])
pango: font_description=([MockDouble])
pango: text=(["Medium Length & Size"])
pango: width=([286720])
@ -104,7 +104,7 @@ cairo: set_source_color(["black"])
cairo: translate([10, 10])
cairo: rotate([0])
cairo: move_to([0, 0])
pango font: size=([12288])
pango font: size=([4096])
pango: font_description=([MockDouble])
pango: text=(["Super duper long string here, therefore a smaller font."])
pango: width=([286720])

6
spec/data/samples/text/_embed_text.rb.txt

@ -348,7 +348,7 @@ cairo: set_source_color(["black"])
cairo: translate([0, 0])
cairo: rotate([0])
cairo: move_to([0, 0])
pango font: size=([18432])
pango font: size=([6144])
pango: font_description=([MockDouble])
pango: text=(["Take 1 :tool: and gain 2 :health:."])
pango: width=([184320])
@ -372,7 +372,7 @@ cairo: set_source_color(["black"])
cairo: translate([0, 0])
cairo: rotate([0])
cairo: move_to([0, 0])
pango font: size=([26624])
pango font: size=([8704.0])
pango: font_description=([MockDouble])
pango: text=(["Take 1 :tool: and gain 2 :health:."])
pango: width=([184320])
@ -396,7 +396,7 @@ cairo: set_source_color(["black"])
cairo: translate([0, 0])
cairo: rotate([0])
cairo: move_to([0, 0])
pango font: size=([35840])
pango font: size=([11776.0])
pango: font_description=([MockDouble])
pango: text=(["Take 1 :tool: and gain 2 :health:."])
pango: width=([184320])

12
spec/data/samples/text/_text_options.rb.txt

@ -282,7 +282,7 @@ cairo: set_source_color(["black"])
cairo: translate([65, 350])
cairo: rotate([0])
cairo: move_to([0, 0])
pango font: size=([16384])
pango font: size=([5120])
pango: font_description=([MockDouble])
pango: text=(["Font string sizes can be overridden per card."])
pango: wrap=([#<Pango::WrapMode word-char>])
@ -298,7 +298,7 @@ cairo: set_source_color(["black"])
cairo: translate([65, 350])
cairo: rotate([0])
cairo: move_to([0, 0])
pango font: size=([20480])
pango font: size=([7168])
pango: font_description=([MockDouble])
pango: text=(["Font string sizes can be overridden per card."])
pango: wrap=([#<Pango::WrapMode word-char>])
@ -314,7 +314,7 @@ cairo: set_source_color(["black"])
cairo: translate([65, 350])
cairo: rotate([0])
cairo: move_to([0, 0])
pango font: size=([24576])
pango font: size=([8192])
pango: font_description=([MockDouble])
pango: text=(["Font string sizes can be overridden per card."])
pango: wrap=([#<Pango::WrapMode word-char>])
@ -393,7 +393,7 @@ cairo: set_source_color(["black"])
cairo: translate([65, 550])
cairo: rotate([0])
cairo: move_to([0, 0])
pango font: size=([16384])
pango font: size=([5120])
pango: font_description=([MockDouble])
pango: text=(["Ink extent return value"])
pango: wrap=([#<Pango::WrapMode word-char>])
@ -409,7 +409,7 @@ cairo: set_source_color(["black"])
cairo: translate([65, 550])
cairo: rotate([0])
cairo: move_to([0, 0])
pango font: size=([20480])
pango font: size=([7168])
pango: font_description=([MockDouble])
pango: text=(["Ink extent return value"])
pango: wrap=([#<Pango::WrapMode word-char>])
@ -425,7 +425,7 @@ cairo: set_source_color(["black"])
cairo: translate([65, 550])
cairo: rotate([0])
cairo: move_to([0, 0])
pango font: size=([24576])
pango font: size=([8192])
pango: font_description=([MockDouble])
pango: text=(["Ink extent return value"])
pango: wrap=([#<Pango::WrapMode word-char>])

1
spec/spec_helper.rb

@ -115,6 +115,7 @@ def mock_cairo(strio)
allow(pango).to receive(:attributes).and_return(nil)
allow(pango_cxt).to receive(:set_shape_renderer)
allow(pango_cxt).to receive(:font_options=)
allow(pango_cxt).to receive(:resolution=)
allow(iter).to receive(:next_char!).and_return(false)
allow(iter).to receive(:char_extents).and_return(Pango::Rectangle.new(5, 5, 5, 5))
allow(iter).to receive(:index).and_return(1000)

Loading…
Cancel
Save