pretty_text 0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|