pretty_text 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +9 -0
- data/Rakefile +22 -0
- data/lib/pretty_text.rb +126 -0
- data/lib/pretty_text_helper.rb +57 -0
- data/lib/pretty_text_style.rb +113 -0
- data/rails/init.rb +10 -0
- metadata +80 -0
data/README
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
desc 'Default: run unit tests.'
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
desc 'Test the text_renderer plugin.'
|
9
|
+
Rake::TestTask.new(:test) do |t|
|
10
|
+
t.libs << 'lib'
|
11
|
+
t.pattern = 'test/**/*_test.rb'
|
12
|
+
t.verbose = true
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Generate documentation for the text_renderer plugin.'
|
16
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
17
|
+
rdoc.rdoc_dir = 'rdoc'
|
18
|
+
rdoc.title = 'TextRenderer'
|
19
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
20
|
+
rdoc.rdoc_files.include('README')
|
21
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
22
|
+
end
|
data/lib/pretty_text.rb
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
module Cabird # :nodoc:
|
2
|
+
# This class represents a rendered text. It provides methods to get the path and
|
3
|
+
# the geometry to the generated image.
|
4
|
+
# Some parameters of the rendering process can be set using the global Hash
|
5
|
+
# <tt>PRETTY_TEXT</tt>. These are the configuration keys for <tt>PRETTY_TEXT</tt>:
|
6
|
+
# [<tt>:image_path</tt>]
|
7
|
+
# The public path where the plugin stores the rendered images relative to the
|
8
|
+
# public path. Defaults to 'images/pretty_text'
|
9
|
+
# [<tt>:scale_threshold</tt>]
|
10
|
+
# Some fonts might look a little bit ugly at smaller sizes. <tt>PrettyText</tt>
|
11
|
+
# tries to fix that by rendering small fonts 5 times bigger and scaling the
|
12
|
+
# result down to the original size. You can set a threshold for the font size
|
13
|
+
# in pts. All fonts smaller than this threshold will be rendered using this
|
14
|
+
# scale hack.
|
15
|
+
# [<tt>:scale_filter</tt>]
|
16
|
+
# The ImageMagick filter which is used for resizing. Defaults to
|
17
|
+
# <tt>Magick::GaussianFilter</tt>.
|
18
|
+
# [<tt>:scale_support</tt>]
|
19
|
+
# The support argument used by the ImageMagick <tt>resize</tt> method. Defaults
|
20
|
+
# to 0.5.
|
21
|
+
class PrettyText
|
22
|
+
require 'RMagick'
|
23
|
+
require 'fileutils'
|
24
|
+
|
25
|
+
@@config = Hash.new
|
26
|
+
mattr_writer :config
|
27
|
+
SCALE_FACTOR = 5
|
28
|
+
|
29
|
+
attr_reader :content
|
30
|
+
|
31
|
+
# This class method is used to set up a new <tt>PrettyText</tt> object. If the requested
|
32
|
+
# image is not yet created, it generates the image and returns the approprate
|
33
|
+
# <tt>PrettyText</tt> object.
|
34
|
+
def self.create(text, style = nil)
|
35
|
+
text = text.to_s
|
36
|
+
if (style.class.to_s != "Cabird::PrettyTextStyle")
|
37
|
+
style = Cabird::PrettyTextStyle.new(style)
|
38
|
+
end
|
39
|
+
|
40
|
+
# set up paths
|
41
|
+
public_image_path = @@config[:image_path] || File.join('system' , 'pretty_text')
|
42
|
+
public_path = File.join(public_image_path, style.generate_filename(text))
|
43
|
+
absolute_path = File.join(RAILS_ROOT, 'public', public_path)
|
44
|
+
|
45
|
+
# render small fonts bigger and scale down later
|
46
|
+
size = style.size
|
47
|
+
scale_hack = size <= (@@config[:scale_threshold] || 12)
|
48
|
+
size *= SCALE_FACTOR if scale_hack
|
49
|
+
|
50
|
+
if (!File.exist?(absolute_path))
|
51
|
+
# create directory
|
52
|
+
FileUtils.mkpath(File.dirname(absolute_path)) unless File.exists?(File.dirname(absolute_path))
|
53
|
+
|
54
|
+
gc = Magick::Draw.new
|
55
|
+
gc.font = File.join(RAILS_ROOT, 'fonts', style.font) if style.font
|
56
|
+
gc.pointsize = size
|
57
|
+
#gc.kerning(style.kerning)
|
58
|
+
gc.gravity = Magick::NorthWestGravity
|
59
|
+
gc.fill = style.color
|
60
|
+
text_to_render = style.process_text(text)
|
61
|
+
gc.text(style.xoffset, style.yoffset, text_to_render)
|
62
|
+
|
63
|
+
metrics = gc.get_multiline_type_metrics(text_to_render)
|
64
|
+
image = Magick::Image.new(metrics.width + style.xextra + style.xoffset, metrics.height + style.yextra + style.yoffset) do
|
65
|
+
self.background_color = style.bg_color
|
66
|
+
end
|
67
|
+
gc.draw(image)
|
68
|
+
|
69
|
+
# scale down to original size
|
70
|
+
if scale_hack
|
71
|
+
image.resize!(metrics.width / SCALE_FACTOR,
|
72
|
+
metrics.height / SCALE_FACTOR,
|
73
|
+
@@config[:scale_filter] || Magick::GaussianFilter,
|
74
|
+
@@config[:scale_support] || 0.5)
|
75
|
+
end
|
76
|
+
# handle gif transparency
|
77
|
+
if (style.format == :gif)
|
78
|
+
image = image.matte_replace(0, 0)
|
79
|
+
end
|
80
|
+
|
81
|
+
image.write(absolute_path)
|
82
|
+
end
|
83
|
+
|
84
|
+
return self.new(text, public_path)
|
85
|
+
end
|
86
|
+
|
87
|
+
# The constructor is used by the <tt>create</tt> factory method. You should not use it,
|
88
|
+
# but use the <tt>create</tt> method instead.
|
89
|
+
def initialize(text, public_path)
|
90
|
+
@content = text
|
91
|
+
@public_path = public_path
|
92
|
+
end
|
93
|
+
|
94
|
+
# Returns the relative path of the image starting at the public directory
|
95
|
+
def path
|
96
|
+
return File.join('', @public_path)
|
97
|
+
end
|
98
|
+
|
99
|
+
# Return the width of the image
|
100
|
+
def width
|
101
|
+
get_geometry if @width.nil?
|
102
|
+
return @width
|
103
|
+
end
|
104
|
+
|
105
|
+
# Returns the height of the image
|
106
|
+
def height
|
107
|
+
get_geometry if @height.nil?
|
108
|
+
return @height
|
109
|
+
end
|
110
|
+
|
111
|
+
# Returns the string the image is created from
|
112
|
+
def to_s
|
113
|
+
return @text
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
# Retrieves the geometry of the image and saves it to the <tt>@width</tt> and
|
119
|
+
# <tt>@height</tt> attributes of the class
|
120
|
+
def get_geometry
|
121
|
+
image = Magick::Image.read(File.join(RAILS_ROOT, 'public', @public_path)).first
|
122
|
+
@width = image.columns
|
123
|
+
@height = image.rows
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Cabird # :nodoc:
|
2
|
+
# This module contains helper methods to create <tt>PrettyText</tt> objects and to include
|
3
|
+
# the generated image in your view.
|
4
|
+
module PrettyTextHelper
|
5
|
+
# This helper creates a <tt>PrettyText</tt> object and shows the generated text as
|
6
|
+
# background image of a HTML-tag.
|
7
|
+
# You can set the style of the rendered text by a <tt>PrettyTextStyle</tt> object
|
8
|
+
# or by a hash:
|
9
|
+
#
|
10
|
+
# <% @style = Cabird::PrettyTextStyle.new(:color => '#666666', :size => 30) %>
|
11
|
+
# <%= pretty_text("the text", @style, 'h1')
|
12
|
+
#
|
13
|
+
# or
|
14
|
+
#
|
15
|
+
# <%= pretty_text("the text", {:color => '#666666', :size => 30}, 'h1')
|
16
|
+
#
|
17
|
+
# which will result in the same output:
|
18
|
+
#
|
19
|
+
# <h1 style="... background: url('...'); ...">the text</h1>
|
20
|
+
#
|
21
|
+
# Using the <tt>PrettyTextStyle</tt> class gives you the opportunity to use a kind of
|
22
|
+
# style inheritance:
|
23
|
+
#
|
24
|
+
# <% @style = Cabird::PrettyTextStyle.new(:color => '#666666', :size => 30) %>
|
25
|
+
# <%= pretty_text("a headline", @style, 'h1')
|
26
|
+
# <%= pretty_text("normal text", @style.alter(:size => 12), 'p')
|
27
|
+
#
|
28
|
+
# Use the html_options to append HTML options to the tag:
|
29
|
+
# <%= pretty_text("the text", @style, 'h1', {:class => "myclass"})
|
30
|
+
def pretty_text(str, style = nil, tag="span", html_options = nil)
|
31
|
+
text = Cabird::PrettyText.create(str, style);
|
32
|
+
|
33
|
+
if html_options
|
34
|
+
html_options = html_options.stringify_keys
|
35
|
+
convert_options_to_javascript!(html_options)
|
36
|
+
tag_options = tag_options(html_options)
|
37
|
+
else
|
38
|
+
tag_options = nil
|
39
|
+
end
|
40
|
+
|
41
|
+
style = "display:block;overflow:hidden;text-indent:-9999px;"
|
42
|
+
style << "width:#{text.width}px;height:#{text.height}px; "
|
43
|
+
style << "background:left top no-repeat url('#{image_path(text.path)}');"
|
44
|
+
|
45
|
+
ret = "<#{tag} style=\"#{style}\"#{tag_options}>"
|
46
|
+
ret << h(text.content)
|
47
|
+
ret << "</#{tag}>"
|
48
|
+
end
|
49
|
+
|
50
|
+
# This method returns the public path to the rendered text. The parameters are the same
|
51
|
+
# as the two first parameters of the pretty_text method.
|
52
|
+
def pretty_text_path(str, style = nil)
|
53
|
+
text = Cabird::PrettyText.create(str, style);
|
54
|
+
return text.path
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
module Cabird # :nodoc:
|
2
|
+
# This class represents a style used by the <tt>PrettyText</tt> class to generate
|
3
|
+
# an image. This style includes font properties like the font-file and the font-size,
|
4
|
+
# colors and text transformation like upcase.
|
5
|
+
#
|
6
|
+
# Possible style attributes are:
|
7
|
+
# [<tt>format</tt>]
|
8
|
+
# Can either be <tt>:png</tt> or <tt>:gif</tt>, defaults to <tt>:png</tt>.
|
9
|
+
# If <tt>:gif</tt> is used set the <tt>bg_color</tt> attribute to get proper
|
10
|
+
# antialiasing.
|
11
|
+
# [<tt>color</tt>]
|
12
|
+
# The color of the rendered text. Use HTML/CSS style color definitions (eg.:
|
13
|
+
# ##fff, ##d2d2d2). Defaults to ##fff.
|
14
|
+
# [<tt>bg_color</tt>]
|
15
|
+
# If you choose <tt>:gif</tt> as format the text will be rendered against the given
|
16
|
+
# <tt>bg_color</tt> and the areas of the background which are not effected by the
|
17
|
+
# antialiasing are cut out. This way you get proper antialiasing, although the gif
|
18
|
+
# format does not support alpha channels.
|
19
|
+
# [<tt>size</tt>]
|
20
|
+
# The size of the rendered font in points
|
21
|
+
# [<tt>font</tt>]
|
22
|
+
# The font file to use relative to the font root directory, which is fonts by default
|
23
|
+
# [<tt>upcase</tt>]
|
24
|
+
# This flag defines if the text is transformed to uppercase before rendering.
|
25
|
+
# This boolean defaults to false.
|
26
|
+
# [<tt>extra_width</tt>]
|
27
|
+
# Sometimes Imagemagick will calculate the wrong width for the image. You can add
|
28
|
+
# some extra space by setting this value. Defaults to 0. This might be obsolete due
|
29
|
+
# to an former error in the implementation.
|
30
|
+
#
|
31
|
+
# You can set the atrributes via the constructor:
|
32
|
+
# style = Cabird::PrettyTextStyle.new({:format => :png, :color => '#f00'})
|
33
|
+
# or via the setter methods:
|
34
|
+
# style.color = '#000'
|
35
|
+
class PrettyTextStyle
|
36
|
+
#require 'RMagick'
|
37
|
+
|
38
|
+
# require 'digest/md5'
|
39
|
+
require 'unicode'
|
40
|
+
|
41
|
+
@@default = {:format => :png,
|
42
|
+
:color => '#000',
|
43
|
+
:bg_color => '#fff',
|
44
|
+
:size => 12,
|
45
|
+
:font => nil,
|
46
|
+
:upcase => false,
|
47
|
+
:extra_width => 0,
|
48
|
+
:xextra => 0,
|
49
|
+
:xoffset => 0,
|
50
|
+
:yextra => 0,
|
51
|
+
:yoffset => 0,
|
52
|
+
:kerning => 0}
|
53
|
+
|
54
|
+
# define getters and setters with default
|
55
|
+
@@default.keys.each do |key|
|
56
|
+
# getter method
|
57
|
+
define_method key do
|
58
|
+
return @attributes[key] || @@default[key]
|
59
|
+
end
|
60
|
+
|
61
|
+
# setter method
|
62
|
+
define_method key.to_s + '=' do |value|
|
63
|
+
@attributes[key] = value
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Sets up a new <tt>PrettyTextStyle</tt> object. All of the above mentioned attributes
|
68
|
+
# can be set here.
|
69
|
+
def initialize(attributes = nil)
|
70
|
+
@attributes = attributes || Hash.new
|
71
|
+
end
|
72
|
+
|
73
|
+
# This method overrides the default getter method for the <tt>bg_color</tt> method.
|
74
|
+
def bg_color
|
75
|
+
return "transparent" if self.format == :png
|
76
|
+
return @attributes[:bg_color] || @@default[:bg_color]
|
77
|
+
end
|
78
|
+
|
79
|
+
# Applies all text transformations to a given text, which includes only the
|
80
|
+
# <tt>upcase</tt> option at the moment. Returns the transformed text.
|
81
|
+
def process_text(text)
|
82
|
+
return (self.upcase == true) ? Unicode::upcase(text) : text
|
83
|
+
end
|
84
|
+
|
85
|
+
# Generates a hash string of all attributes and a given string. This method is used
|
86
|
+
# by the <tt>generate_filename</tt> method to retrieve the filename for a combilnation
|
87
|
+
# of style attributes and a certain text.
|
88
|
+
def generate_hash(str = "")
|
89
|
+
to_hash = str
|
90
|
+
@@default.keys.each do |key|
|
91
|
+
to_hash += self.send(key).to_s
|
92
|
+
end
|
93
|
+
return Digest::MD5.hexdigest(to_hash)
|
94
|
+
end
|
95
|
+
|
96
|
+
# This method generates a hashed filename of the style attributes and a given text
|
97
|
+
def generate_filename(str)
|
98
|
+
fragments = self.generate_hash(str).scan(/(..)/).flatten
|
99
|
+
return File.join(fragments) + "." + self.format.to_s
|
100
|
+
end
|
101
|
+
|
102
|
+
# Clones this <tt>PrettyTextStyle</tt> object and returns an altered version of the clone.
|
103
|
+
# You can override attributes with the argument.
|
104
|
+
def alter(attributes = Hash.new)
|
105
|
+
result = Hash.new
|
106
|
+
@@default.keys.each do |key|
|
107
|
+
result[key] = (attributes[key]) ? attributes[key] :
|
108
|
+
@attributes[key]
|
109
|
+
end
|
110
|
+
return self.class.new(result)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
data/rails/init.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# Include hook code here
|
2
|
+
require 'pretty_text'
|
3
|
+
require 'pretty_text_style'
|
4
|
+
require 'pretty_text_helper'
|
5
|
+
|
6
|
+
# load configuration
|
7
|
+
Cabird::PrettyText.config = PRETTY_TEXT if Object.const_defined?(:PRETTY_TEXT)
|
8
|
+
|
9
|
+
# include helpers
|
10
|
+
ActionView::Base.send(:include, Cabird::PrettyTextHelper)
|
metadata
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pretty_text
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
version: "0.1"
|
9
|
+
platform: ruby
|
10
|
+
authors:
|
11
|
+
- Claas Abert
|
12
|
+
autorequire:
|
13
|
+
bindir: bin
|
14
|
+
cert_chain: []
|
15
|
+
|
16
|
+
date: 2010-08-08 00:00:00 +02:00
|
17
|
+
default_executable:
|
18
|
+
dependencies:
|
19
|
+
- !ruby/object:Gem::Dependency
|
20
|
+
name: rmagick
|
21
|
+
prerelease: false
|
22
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
23
|
+
none: false
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :runtime
|
31
|
+
version_requirements: *id001
|
32
|
+
description:
|
33
|
+
email:
|
34
|
+
executables: []
|
35
|
+
|
36
|
+
extensions: []
|
37
|
+
|
38
|
+
extra_rdoc_files: []
|
39
|
+
|
40
|
+
files:
|
41
|
+
- README
|
42
|
+
- Rakefile
|
43
|
+
- lib/pretty_text.rb
|
44
|
+
- lib/pretty_text_helper.rb
|
45
|
+
- lib/pretty_text_style.rb
|
46
|
+
- rails/init.rb
|
47
|
+
has_rdoc: true
|
48
|
+
homepage:
|
49
|
+
licenses: []
|
50
|
+
|
51
|
+
post_install_message:
|
52
|
+
rdoc_options: []
|
53
|
+
|
54
|
+
require_paths:
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
segments:
|
62
|
+
- 0
|
63
|
+
version: "0"
|
64
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
72
|
+
requirements: []
|
73
|
+
|
74
|
+
rubyforge_project:
|
75
|
+
rubygems_version: 1.3.7
|
76
|
+
signing_key:
|
77
|
+
specification_version: 3
|
78
|
+
summary: A TTF font rendering plugin for rails using RMagick.
|
79
|
+
test_files: []
|
80
|
+
|