Tons of text features and options added
parent
c477432239
commit
9da4d0a499
|
|
@ -0,0 +1,9 @@
|
|||
module Squib
|
||||
class Deck
|
||||
|
||||
def hint(text: nil)
|
||||
@text_hint = colorify(text, nillable: true)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -2,10 +2,11 @@ module Squib
|
|||
class Deck
|
||||
|
||||
def rect(range: :all, x: 0, y: 0, width: 825, height: 1125, \
|
||||
x_radius: 0, y_radius: 0)
|
||||
x_radius: 0, y_radius: 0, color: :black)
|
||||
range = rangeify(range)
|
||||
color = colorify(color)
|
||||
range.each do |i|
|
||||
@cards[i].draw_rectangle(x, y, width, height, x_radius, y_radius)
|
||||
@cards[i].draw_rectangle(x, y, width, height, x_radius, y_radius, color)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,5 @@
|
|||
module Squib
|
||||
class Deck
|
||||
def fontify (font)
|
||||
font = 'Arial 36' if font==:use_set
|
||||
font
|
||||
end
|
||||
|
||||
def font(type: 'Arial', size: 12, **options)
|
||||
raise 'Not implemented!'
|
||||
end
|
||||
|
|
@ -17,7 +12,8 @@ module Squib
|
|||
range = rangeify(range)
|
||||
str = [str] * @cards.size unless str.respond_to? :each
|
||||
font = fontify(font)
|
||||
color = colorify(options[:color])
|
||||
color = colorify(options[:color], nillable: false)
|
||||
options['hint'] = colorify(options['hint']) unless options['hint'].nil?
|
||||
range.each do |i|
|
||||
cards[i].text(str[i], font, x, y, color, options)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
require 'cairo'
|
||||
require 'squib/input_helpers'
|
||||
|
||||
module Squib
|
||||
class Card
|
||||
include Squib::InputHelpers
|
||||
attr_reader :width, :height
|
||||
attr_accessor :cairo_surface, :cairo_context
|
||||
|
||||
def initialize(width, height)
|
||||
@width=width; @height=height
|
||||
def initialize(deck, width, height)
|
||||
@deck=deck; @width=width; @height=height
|
||||
@cairo_surface = Cairo::ImageSurface.new(width,height)
|
||||
@cairo_context = Cairo::Context.new(@cairo_surface)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,15 +1,18 @@
|
|||
require 'squib/card'
|
||||
require 'squib/input_helpers'
|
||||
|
||||
module Squib
|
||||
class Deck
|
||||
include Enumerable
|
||||
include Squib::InputHelpers
|
||||
attr_reader :width, :height
|
||||
attr_reader :cards
|
||||
attr_reader :text_hint
|
||||
|
||||
def initialize(width: 825, height: 1125, cards: 1, &block)
|
||||
@width=width; @height=height
|
||||
@cards = []
|
||||
cards.times{ @cards << Squib::Card.new(width, height) }
|
||||
cards.times{ @cards << Squib::Card.new(self, width, height) }
|
||||
if block_given?
|
||||
instance_eval(&block)
|
||||
end
|
||||
|
|
@ -24,26 +27,6 @@ module Squib
|
|||
@cards.each { |card| block.call(card) }
|
||||
end
|
||||
|
||||
def rangeify (range)
|
||||
range = 0..(@cards.size-1) if range == :all
|
||||
range = range..range if range.is_a? Integer
|
||||
if range.max > (@cards.size-1)
|
||||
raise "#{range} is outside of deck range of 0..#{@card.size-1}"
|
||||
end
|
||||
return range
|
||||
end
|
||||
|
||||
def fileify(file)
|
||||
raise 'File #{file} does not exist!' unless File.exists? file
|
||||
file
|
||||
end
|
||||
|
||||
def colorify(color)
|
||||
color ||= :black
|
||||
color = Cairo::Color.parse(color)
|
||||
color
|
||||
end
|
||||
|
||||
##################
|
||||
### PUBLIC API ###
|
||||
##################
|
||||
|
|
@ -51,6 +34,7 @@ module Squib
|
|||
require 'squib/api/data'
|
||||
require 'squib/api/image'
|
||||
require 'squib/api/save'
|
||||
require 'squib/api/settings'
|
||||
require 'squib/api/shapes'
|
||||
require 'squib/api/text'
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
module Squib
|
||||
class Card
|
||||
|
||||
def draw_rectangle(x, y, width, height, x_radius, y_radius)
|
||||
def draw_rectangle(x, y, width, height, x_radius, y_radius, color)
|
||||
cc = cairo_context
|
||||
cc.set_source_rgb(0.0,0.0,0.0)
|
||||
cc.set_source_color(color)
|
||||
cc.rounded_rectangle(x, y, width, height, x_radius, y_radius)
|
||||
cc.stroke
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,25 +3,84 @@ require 'pango'
|
|||
module Squib
|
||||
class Card
|
||||
|
||||
def draw_text_hint(x,y,layout, color)
|
||||
return if color.nil? && @deck.text_hint.nil?
|
||||
color ||= @deck.text_hint
|
||||
w = layout.width / Pango::SCALE
|
||||
w = layout.extents[1].width / Pango::SCALE if w < 0 #i.e. was never set
|
||||
h = layout.height / Pango::SCALE
|
||||
h = layout.extents[1].height / Pango::SCALE if h < 0 #i.e. was never set
|
||||
draw_rectangle(x,y,w,h,0,0,color)
|
||||
end
|
||||
|
||||
def ellipsize(layout, options)
|
||||
unless options[:ellipsize].nil?
|
||||
h = { :none => Pango::Layout::ELLIPSIZE_NONE,
|
||||
:start => Pango::Layout::ELLIPSIZE_START,
|
||||
:middle => Pango::Layout::ELLIPSIZE_MIDDLE,
|
||||
:end => Pango::Layout::ELLIPSIZE_END,
|
||||
true => Pango::Layout::ELLIPSIZE_END,
|
||||
false => Pango::Layout::ELLIPSIZE_NONE
|
||||
}
|
||||
layout.ellipsize = h[options[:ellipsize]]
|
||||
end
|
||||
layout
|
||||
end
|
||||
|
||||
def wrap(layout, options)
|
||||
unless options[:wrap].nil?
|
||||
h = { :word => Pango::Layout::WRAP_WORD,
|
||||
:char => Pango::Layout::WRAP_CHAR,
|
||||
:word_char => Pango::Layout::WRAP_WORD_CHAR,
|
||||
true => Pango::Layout::WRAP_WORD_CHAR,
|
||||
}
|
||||
layout.wrap = h[options[:wrap]]
|
||||
end
|
||||
layout
|
||||
end
|
||||
|
||||
def align(layout, options)
|
||||
unless options[:align].nil?
|
||||
h = { :left => Pango::ALIGN_LEFT,
|
||||
:right => Pango::ALIGN_RIGHT,
|
||||
:center => Pango::ALIGN_CENTER
|
||||
}
|
||||
layout.alignment = h[options[:align]]
|
||||
end
|
||||
layout
|
||||
end
|
||||
|
||||
def setwh(layout, options)
|
||||
layout.width = options[:width] * Pango::SCALE unless options[:width].nil?
|
||||
layout.height = options[:height] * Pango::SCALE unless options[:height].nil?
|
||||
layout
|
||||
end
|
||||
|
||||
def fitxy(layout, x,y, options)
|
||||
w = options[:width] ; h = options[:height]
|
||||
w ||= (@width - 2*x); h ||= (@height - 2*y) # default centers to x,y
|
||||
w *= Pango::SCALE ; h *= Pango::SCALE
|
||||
layout.width=w ; layout.height=h
|
||||
layout
|
||||
end
|
||||
|
||||
def text(str, font, x, y, color, options)
|
||||
cc = cairo_context
|
||||
cc.set_source_color(color)
|
||||
cc.move_to(x,y)
|
||||
layout = cc.create_pango_layout
|
||||
layout.text = str.to_s
|
||||
w = options[:width] ; h = options[:height]
|
||||
w ||= (@width - 2*x); h ||= (@height - 2*y) # default centers to x,y
|
||||
w *= Pango::SCALE ; h *= Pango::SCALE
|
||||
layout.width=w ; layout.height=h
|
||||
layout.wrap = Pango::WRAP_WORD
|
||||
layout.justify = true
|
||||
layout.alignment = Pango::ALIGN_LEFT
|
||||
layout.markup = str.to_s if options[:markup]
|
||||
layout = setwh(layout, options) unless options[:width].nil? && options[:height].nil?
|
||||
layout = fitxy(layout, x, y , options) if options[:fitxy]
|
||||
layout = wrap(layout, options)
|
||||
layout = ellipsize(layout, options)
|
||||
layout = align(layout, options)
|
||||
layout.justify = options[:justify] unless options[:justify].nil?
|
||||
layout.font_description = Pango::FontDescription.new(font)
|
||||
#Center it vertically?
|
||||
#puts "Height: #{layout.extents[1].height / Pango::SCALE}"
|
||||
#puts "Height: #{layout.pixel_size[1]*layout.line_count}"
|
||||
cc.update_pango_layout(layout)
|
||||
cc.show_pango_layout(layout)
|
||||
draw_text_hint(x,y,layout,options[:hint])
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
module Squib
|
||||
module InputHelpers
|
||||
|
||||
def rangeify (range)
|
||||
range = 0..(@cards.size-1) if range == :all
|
||||
range = range..range if range.is_a? Integer
|
||||
if range.max > (@cards.size-1)
|
||||
raise "#{range} is outside of deck range of 0..#{@card.size-1}"
|
||||
end
|
||||
return range
|
||||
end
|
||||
module_function :rangeify
|
||||
|
||||
def fileify(file)
|
||||
raise 'File #{file} does not exist!' unless File.exists? file
|
||||
file
|
||||
end
|
||||
module_function :fileify
|
||||
|
||||
def colorify(color, nillable: false)
|
||||
if nillable # for optional color arguments like text hints
|
||||
color = Cairo::Color.parse(color) unless color.nil?
|
||||
else
|
||||
color ||= :black
|
||||
color = Cairo::Color.parse(color)
|
||||
end
|
||||
color
|
||||
end
|
||||
module_function :colorify
|
||||
|
||||
def fontify (font)
|
||||
font = 'Arial 36' if font==:use_set
|
||||
font
|
||||
end
|
||||
module_function :fontify
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
#!/usr/bin/env ruby
|
||||
require 'squib'
|
||||
|
||||
data = {'name' => ['Thief', 'Grifter', 'Mastermind'],
|
||||
'level' => [1,2,3]}
|
||||
longtext = "This is left-justified text centered on the card based on x and y.\nWhat do you know about tweetle beetles? well... \nWhen tweetle beetles fight, it's called a tweetle beetle battle. And when they battle in a puddle, it's a tweetle beetle puddle battle. AND when tweetle beetles battle with paddles in a puddle, they call it a tweetle beetle puddle paddle battle. AND... When beetles battle beetles in a puddle paddle battle and the beetle battle puddle is a puddle in a bottle... ..they call this a tweetle beetle bottle puddle paddle battle muddle. AND... When beetles fight these battles in a bottle with their paddles and the bottle's on a poodle and the poodle's eating noodles... ...they call this a muddle puddle tweetle poodle beetle noodle bottle paddle battle."
|
||||
|
||||
Squib::Deck.new(width: 825, height: 1125, cards: 128) do
|
||||
background color: :white
|
||||
rect x: 15, y: 15, width: 795, height: 1095, x_radius: 50, y_radius: 50
|
||||
rect x: 30, y: 30, width: 128, height: 128, x_radius: 25, y_radius: 25
|
||||
|
||||
text str: data['name'], x: 250, y: 55, font: 'Arial 54'
|
||||
text str: data['level'], x: 65, y: 40, font: 'Arial 72', color: :burnt_orange
|
||||
|
||||
text str: "This text has a hint, fixed width, and fixed height",
|
||||
hint: :red,
|
||||
x: 65, y: 400,
|
||||
width: 300, height: 200,
|
||||
font: 'Arial 24'
|
||||
|
||||
text str: "Ellipsization!\nThe ultimate question of life, the universe, and everything to life and everything is 42",
|
||||
hint: :green, font: 'Arial 22',
|
||||
x: 450, y: 400,
|
||||
width: 280, height: 180,
|
||||
ellipsize: true
|
||||
|
||||
hint text: :cyan
|
||||
text str: "Text hints are also globally togglable!",
|
||||
x: 65, y: 625,
|
||||
font: 'Arial 22'
|
||||
hint text: nil
|
||||
text str: "See? No hint here.",
|
||||
x: 565, y: 625,
|
||||
font: 'Arial 22'
|
||||
|
||||
text str: longtext, font: 'Arial 16',
|
||||
x: 65, y: 700,
|
||||
fitxy: true, justify: true
|
||||
|
||||
text str: "<b>Markup</b> is also <i>quite</i> <s>easy</s> awesome",
|
||||
markup: true,
|
||||
x: 50, y: 1000,
|
||||
font: 'Arial 32'
|
||||
|
||||
save prefix: 'text_', format: :png
|
||||
end
|
||||
|
||||
puts "Done!"
|
||||
|
||||
|
||||
Loading…
Reference in New Issue