arrow 1.0.7
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/ChangeLog +1590 -0
- data/LICENSE +28 -0
- data/README +75 -0
- data/Rakefile +366 -0
- data/Rakefile.local +63 -0
- data/data/arrow/applets/TEMPLATE.rb.tpl +53 -0
- data/data/arrow/applets/args.rb +50 -0
- data/data/arrow/applets/config.rb +55 -0
- data/data/arrow/applets/error.rb +63 -0
- data/data/arrow/applets/files.rb +46 -0
- data/data/arrow/applets/inspect.rb +46 -0
- data/data/arrow/applets/nosuchapplet.rb +31 -0
- data/data/arrow/applets/status.rb +92 -0
- data/data/arrow/applets/test.rb +133 -0
- data/data/arrow/applets/tutorial/counter.rb +96 -0
- data/data/arrow/applets/tutorial/dingus.rb +67 -0
- data/data/arrow/applets/tutorial/hello.rb +34 -0
- data/data/arrow/applets/tutorial/hello2.rb +73 -0
- data/data/arrow/applets/tutorial/imgtext.rb +90 -0
- data/data/arrow/applets/tutorial/imgtext2.rb +286 -0
- data/data/arrow/applets/tutorial/index.rb +36 -0
- data/data/arrow/applets/tutorial/logo.rb +98 -0
- data/data/arrow/applets/tutorial/memcache.rb +61 -0
- data/data/arrow/applets/tutorial/missing.rb +37 -0
- data/data/arrow/applets/tutorial/protected.rb +100 -0
- data/data/arrow/applets/tutorial/redirector.rb +52 -0
- data/data/arrow/applets/tutorial/rndimages.rb +159 -0
- data/data/arrow/applets/tutorial/sharenotes.rb +83 -0
- data/data/arrow/applets/tutorial/subclassed-hello.rb +32 -0
- data/data/arrow/applets/tutorial/superhello.rb +72 -0
- data/data/arrow/applets/tutorial/timeclock.rb +78 -0
- data/data/arrow/applets/view-applet.rb +123 -0
- data/data/arrow/applets/view-template.rb +85 -0
- data/data/arrow/applets/wiki.rb +274 -0
- data/data/arrow/templates/TEMPLATE.tmpl.tpl +36 -0
- data/data/arrow/templates/applet-status.tmpl +153 -0
- data/data/arrow/templates/args-display.tmpl +120 -0
- data/data/arrow/templates/config/display-table.tmpl +36 -0
- data/data/arrow/templates/config/display.tmpl +36 -0
- data/data/arrow/templates/counter-deleted.tmpl +33 -0
- data/data/arrow/templates/counter.tmpl +59 -0
- data/data/arrow/templates/dingus.tmpl +55 -0
- data/data/arrow/templates/enumtable.tmpl +8 -0
- data/data/arrow/templates/error-display.tmpl +92 -0
- data/data/arrow/templates/filemap.tmpl +89 -0
- data/data/arrow/templates/hello-world-src.tmpl +34 -0
- data/data/arrow/templates/hello-world.tmpl +60 -0
- data/data/arrow/templates/imgtext/fontlist.tmpl +46 -0
- data/data/arrow/templates/imgtext/form.tmpl +70 -0
- data/data/arrow/templates/imgtext/reload-error.tmpl +40 -0
- data/data/arrow/templates/imgtext/reload.tmpl +55 -0
- data/data/arrow/templates/inspect/display.tmpl +80 -0
- data/data/arrow/templates/loginform.tmpl +64 -0
- data/data/arrow/templates/logout.tmpl +32 -0
- data/data/arrow/templates/memcache/display.tmpl +41 -0
- data/data/arrow/templates/navbar.incl +27 -0
- data/data/arrow/templates/nosuchapplet.tmpl +32 -0
- data/data/arrow/templates/printsource.tmpl +35 -0
- data/data/arrow/templates/protected.tmpl +36 -0
- data/data/arrow/templates/rndimages.tmpl +38 -0
- data/data/arrow/templates/service-response.tmpl +13 -0
- data/data/arrow/templates/sharenotes/display.tmpl +38 -0
- data/data/arrow/templates/status.tmpl +120 -0
- data/data/arrow/templates/templateviewer.tmpl +43 -0
- data/data/arrow/templates/test/harness.tmpl +57 -0
- data/data/arrow/templates/test/list.tmpl +48 -0
- data/data/arrow/templates/test/problem.tmpl +42 -0
- data/data/arrow/templates/tutorial/index.tmpl +37 -0
- data/data/arrow/templates/tutorial/missingapplet.tmpl +29 -0
- data/data/arrow/templates/view-applet-nosuch.tmpl +32 -0
- data/data/arrow/templates/view-applet.tmpl +40 -0
- data/data/arrow/templates/view-template.tmpl +83 -0
- data/data/arrow/templates/wiki/formerror.tmpl +47 -0
- data/data/arrow/templates/wiki/markup_help.incl +6 -0
- data/data/arrow/templates/wiki/new.tmpl +56 -0
- data/data/arrow/templates/wiki/new_system.tmpl +122 -0
- data/data/arrow/templates/wiki/sectionlist.tmpl +43 -0
- data/data/arrow/templates/wiki/show.tmpl +34 -0
- data/docs/manual/layouts/default.page +43 -0
- data/docs/manual/lib/api-filter.rb +81 -0
- data/docs/manual/lib/editorial-filter.rb +64 -0
- data/docs/manual/lib/examples-filter.rb +244 -0
- data/docs/manual/lib/links-filter.rb +117 -0
- data/lib/apache/fakerequest.rb +448 -0
- data/lib/apache/logger.rb +33 -0
- data/lib/arrow.rb +51 -0
- data/lib/arrow/acceptparam.rb +207 -0
- data/lib/arrow/applet.rb +725 -0
- data/lib/arrow/appletmixins.rb +218 -0
- data/lib/arrow/appletregistry.rb +590 -0
- data/lib/arrow/applettestcase.rb +503 -0
- data/lib/arrow/broker.rb +255 -0
- data/lib/arrow/cache.rb +176 -0
- data/lib/arrow/config-loaders/yaml.rb +75 -0
- data/lib/arrow/config.rb +615 -0
- data/lib/arrow/constants.rb +24 -0
- data/lib/arrow/cookie.rb +359 -0
- data/lib/arrow/cookieset.rb +108 -0
- data/lib/arrow/dispatcher.rb +368 -0
- data/lib/arrow/dispatcherloader.rb +50 -0
- data/lib/arrow/exceptions.rb +61 -0
- data/lib/arrow/fallbackhandler.rb +48 -0
- data/lib/arrow/formvalidator.rb +631 -0
- data/lib/arrow/htmltokenizer.rb +343 -0
- data/lib/arrow/logger.rb +488 -0
- data/lib/arrow/logger/apacheoutputter.rb +69 -0
- data/lib/arrow/logger/arrayoutputter.rb +63 -0
- data/lib/arrow/logger/coloroutputter.rb +111 -0
- data/lib/arrow/logger/fileoutputter.rb +96 -0
- data/lib/arrow/logger/htmloutputter.rb +54 -0
- data/lib/arrow/logger/outputter.rb +123 -0
- data/lib/arrow/mixins.rb +425 -0
- data/lib/arrow/monkeypatches.rb +94 -0
- data/lib/arrow/object.rb +117 -0
- data/lib/arrow/path.rb +196 -0
- data/lib/arrow/service.rb +447 -0
- data/lib/arrow/session.rb +289 -0
- data/lib/arrow/session/dbstore.rb +100 -0
- data/lib/arrow/session/filelock.rb +160 -0
- data/lib/arrow/session/filestore.rb +132 -0
- data/lib/arrow/session/id.rb +98 -0
- data/lib/arrow/session/lock.rb +253 -0
- data/lib/arrow/session/md5id.rb +42 -0
- data/lib/arrow/session/nulllock.rb +42 -0
- data/lib/arrow/session/posixlock.rb +166 -0
- data/lib/arrow/session/sha1id.rb +54 -0
- data/lib/arrow/session/store.rb +366 -0
- data/lib/arrow/session/usertrackid.rb +52 -0
- data/lib/arrow/spechelpers.rb +73 -0
- data/lib/arrow/template.rb +713 -0
- data/lib/arrow/template/attr.rb +31 -0
- data/lib/arrow/template/call.rb +31 -0
- data/lib/arrow/template/comment.rb +33 -0
- data/lib/arrow/template/container.rb +118 -0
- data/lib/arrow/template/else.rb +41 -0
- data/lib/arrow/template/elsif.rb +44 -0
- data/lib/arrow/template/escape.rb +53 -0
- data/lib/arrow/template/export.rb +87 -0
- data/lib/arrow/template/for.rb +145 -0
- data/lib/arrow/template/if.rb +78 -0
- data/lib/arrow/template/import.rb +119 -0
- data/lib/arrow/template/include.rb +206 -0
- data/lib/arrow/template/iterator.rb +208 -0
- data/lib/arrow/template/nodes.rb +734 -0
- data/lib/arrow/template/parser.rb +571 -0
- data/lib/arrow/template/prettyprint.rb +53 -0
- data/lib/arrow/template/render.rb +191 -0
- data/lib/arrow/template/selectlist.rb +94 -0
- data/lib/arrow/template/set.rb +87 -0
- data/lib/arrow/template/timedelta.rb +81 -0
- data/lib/arrow/template/unless.rb +78 -0
- data/lib/arrow/template/urlencode.rb +51 -0
- data/lib/arrow/template/yield.rb +139 -0
- data/lib/arrow/templatefactory.rb +125 -0
- data/lib/arrow/testcase.rb +567 -0
- data/lib/arrow/transaction.rb +608 -0
- data/rake/191_compat.rb +26 -0
- data/rake/dependencies.rb +76 -0
- data/rake/documentation.rb +114 -0
- data/rake/helpers.rb +502 -0
- data/rake/hg.rb +282 -0
- data/rake/manual.rb +787 -0
- data/rake/packaging.rb +129 -0
- data/rake/publishing.rb +278 -0
- data/rake/style.rb +62 -0
- data/rake/svn.rb +668 -0
- data/rake/testing.rb +187 -0
- data/rake/verifytask.rb +64 -0
- data/spec/arrow/acceptparam_spec.rb +157 -0
- data/spec/arrow/applet_spec.rb +575 -0
- data/spec/arrow/appletmixins_spec.rb +409 -0
- data/spec/arrow/appletregistry_spec.rb +294 -0
- data/spec/arrow/broker_spec.rb +153 -0
- data/spec/arrow/config_spec.rb +224 -0
- data/spec/arrow/cookieset_spec.rb +164 -0
- data/spec/arrow/dispatcher_spec.rb +137 -0
- data/spec/arrow/dispatcherloader_spec.rb +65 -0
- data/spec/arrow/formvalidator_spec.rb +781 -0
- data/spec/arrow/logger_spec.rb +346 -0
- data/spec/arrow/mixins_spec.rb +120 -0
- data/spec/arrow/service_spec.rb +645 -0
- data/spec/arrow/session_spec.rb +121 -0
- data/spec/arrow/template/iterator_spec.rb +222 -0
- data/spec/arrow/templatefactory_spec.rb +185 -0
- data/spec/arrow/transaction_spec.rb +319 -0
- data/spec/arrow_spec.rb +37 -0
- data/spec/lib/appletmatchers.rb +281 -0
- data/spec/lib/constants.rb +77 -0
- data/spec/lib/helpers.rb +41 -0
- data/spec/lib/matchers.rb +44 -0
- data/tests/cookie.tests.rb +310 -0
- data/tests/path.tests.rb +157 -0
- data/tests/session.tests.rb +111 -0
- data/tests/session_id.tests.rb +82 -0
- data/tests/session_lock.tests.rb +191 -0
- data/tests/session_store.tests.rb +53 -0
- data/tests/template.tests.rb +1360 -0
- metadata +339 -0
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
#
|
|
3
|
+
# The FancyImageText class, a derivative of Arrow::Applet. It
|
|
4
|
+
# is an applet which generates an image of a string of TrueType text.
|
|
5
|
+
#
|
|
6
|
+
# == VCS Id
|
|
7
|
+
#
|
|
8
|
+
# $Id$
|
|
9
|
+
#
|
|
10
|
+
# == Authors
|
|
11
|
+
#
|
|
12
|
+
# * Michael Granger <ged@FaerieMUD.org>
|
|
13
|
+
#
|
|
14
|
+
# Thanks to Mahlon Smith <mahlon@martini.nu> for ideas for refinement,
|
|
15
|
+
# suggestions.
|
|
16
|
+
#
|
|
17
|
+
|
|
18
|
+
require 'GD'
|
|
19
|
+
require 'ft2'
|
|
20
|
+
require 'arrow/applet'
|
|
21
|
+
|
|
22
|
+
### It is an applet which generates an image from one or more characters of text.
|
|
23
|
+
class FancyImageText < Arrow::Applet
|
|
24
|
+
|
|
25
|
+
# Default settings
|
|
26
|
+
DefaultFont = 'TektonPro-Regular'
|
|
27
|
+
DefaultFont.untaint
|
|
28
|
+
DefaultFontDir = "/Library/WebServer/Fonts"
|
|
29
|
+
DefaultFontDir.untaint
|
|
30
|
+
|
|
31
|
+
DefaultFontSize = 36
|
|
32
|
+
DefaultText = 'TrueType Font Mangler'
|
|
33
|
+
|
|
34
|
+
# Colors
|
|
35
|
+
DefaultForegroundColor = "#000000"
|
|
36
|
+
DefaultBackgroundColor = "#ffffff"
|
|
37
|
+
|
|
38
|
+
# Safety constraints
|
|
39
|
+
MaxPointSize = 180
|
|
40
|
+
MinPointSize = 5
|
|
41
|
+
MaxTextLength = 1024
|
|
42
|
+
|
|
43
|
+
# URLs of the form: /ttf/<fontname>/<size>/<caption>.<fmt>
|
|
44
|
+
# Stolen shamelessly from Mahlon.
|
|
45
|
+
FileName = %r{(.*)\.(png|jpg)}i
|
|
46
|
+
|
|
47
|
+
# Applet signature
|
|
48
|
+
Signature = {
|
|
49
|
+
:name => "imagetext",
|
|
50
|
+
:description => "Generates an image from one or more characters of text.",
|
|
51
|
+
:maintainer => "ged@FaerieMUD.org",
|
|
52
|
+
:default_action => 'fontlist',
|
|
53
|
+
:templates => {
|
|
54
|
+
:form => 'imgtext/form.tmpl',
|
|
55
|
+
:fontlist => 'imgtext/fontlist.tmpl',
|
|
56
|
+
:reload => 'imgtext/reload.tmpl',
|
|
57
|
+
:reload_error => 'imgtext/reload-error.tmpl',
|
|
58
|
+
},
|
|
59
|
+
:vargs => {
|
|
60
|
+
:__default__ => {
|
|
61
|
+
:required => [],
|
|
62
|
+
:optional => [:imgtext, :fontsize, :fontface],
|
|
63
|
+
:constraints => {
|
|
64
|
+
:imgtext => /^[\x20-\x7e-]+$/,
|
|
65
|
+
:fontsize => /^\d+$/,
|
|
66
|
+
:fontface => /^\S+$/,
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
### Load some stuff when the applet is created.
|
|
74
|
+
def initialize( *args ) # :nodoc:
|
|
75
|
+
super
|
|
76
|
+
|
|
77
|
+
if @config.respond_to?( :imgtext )
|
|
78
|
+
bkgnd = @config.imgtext.background
|
|
79
|
+
fgnd = @config.imgtext.foreground
|
|
80
|
+
@fontdir = @config.imgtext.fontdir
|
|
81
|
+
@defaultfont = @config.imgtext.defaultfont
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
bkgnd ||= DefaultBackgroundColor
|
|
85
|
+
fgnd ||= DefaultForegroundColor
|
|
86
|
+
@fontdir ||= DefaultFontDir
|
|
87
|
+
@defaultfont ||= DefaultFont
|
|
88
|
+
|
|
89
|
+
@background= GD::Image.trueColorAlpha( bkgnd, GD::AlphaTransparent )
|
|
90
|
+
@foreground = GD::Image.trueColorAlpha( fgnd, GD::AlphaOpaque )
|
|
91
|
+
@fonts = load_fonts( @fontdir )
|
|
92
|
+
|
|
93
|
+
self.log.debug "Loaded %d fonts" % @fonts.length
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
######
|
|
98
|
+
public
|
|
99
|
+
######
|
|
100
|
+
|
|
101
|
+
attr_reader :fontdir, :background, :foreground, :fonts
|
|
102
|
+
|
|
103
|
+
### The action to run when the specified action method doesn't exist. This
|
|
104
|
+
### is used to make the URL a bit shorter -- the action name becomes the
|
|
105
|
+
### font name in effect.
|
|
106
|
+
def action_missing_action( txn, *args )
|
|
107
|
+
|
|
108
|
+
# Fetch the REST arguments and build the image for them
|
|
109
|
+
fontname, size, imgname = *args
|
|
110
|
+
caption, fmt = $1, $2 if FileName.match( imgname )
|
|
111
|
+
img = make_image( txn, fontname, size, caption ) or return false
|
|
112
|
+
|
|
113
|
+
self.log.debug "Made %s image with font: %s, size: %d, caption: %p" %
|
|
114
|
+
[ fmt, fontname, size, caption ]
|
|
115
|
+
|
|
116
|
+
# Render the image according to what extension the URI had
|
|
117
|
+
case fmt
|
|
118
|
+
when /png/
|
|
119
|
+
txn.content_type = 'image/png'
|
|
120
|
+
return img.pngStr
|
|
121
|
+
|
|
122
|
+
when /jpg/
|
|
123
|
+
txn.content_type = 'image/jpeg'
|
|
124
|
+
return img.jpegStr( -1 )
|
|
125
|
+
|
|
126
|
+
else
|
|
127
|
+
self.log.error "Unsupported image extension %p" % fmt
|
|
128
|
+
return false
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
### Display a list of the available fonts.
|
|
134
|
+
def fontlist_action( txn, *rest )
|
|
135
|
+
templ = self.load_template( :fontlist )
|
|
136
|
+
templ.txn = txn
|
|
137
|
+
templ.app = self
|
|
138
|
+
templ.fonts = @fonts
|
|
139
|
+
|
|
140
|
+
return templ
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
### Reload the fonts and display what changed.
|
|
145
|
+
def reload_action( txn, *args )
|
|
146
|
+
self.log.debug "Doing reload of fonts for child %d" % [ Process.pid ]
|
|
147
|
+
|
|
148
|
+
newfonts = tmpl = nil
|
|
149
|
+
|
|
150
|
+
# Try to reload the fonts, replacing the currently-loaded ones and
|
|
151
|
+
# showing the differences if it succeeds, and showing the error and
|
|
152
|
+
# keeping the old ones if it fails.
|
|
153
|
+
begin
|
|
154
|
+
newfonts = load_fonts( @fontdir )
|
|
155
|
+
rescue Exception => err
|
|
156
|
+
self.log.error "Caught exception while attempting to reload fonts: %s\n\t%s" %
|
|
157
|
+
[ err.message, err.backtrace.join("\n\t") ]
|
|
158
|
+
tmpl = self.load_template( :reload_error )
|
|
159
|
+
tmpl.exception = err
|
|
160
|
+
else
|
|
161
|
+
tmpl = self.load_template( :reload )
|
|
162
|
+
tmpl.newfonts = newfonts.reject {|name,font| @fonts.key?(name)}
|
|
163
|
+
tmpl.removedfonts = @fonts.reject {|name,font| newfonts.key?(name)}
|
|
164
|
+
@fonts = newfonts
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
tmpl.txn = txn
|
|
168
|
+
tmpl.applet = self
|
|
169
|
+
|
|
170
|
+
return tmpl
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
#########
|
|
175
|
+
protected
|
|
176
|
+
#########
|
|
177
|
+
|
|
178
|
+
### Load Hashes full of font info for each of the readable fonts in the
|
|
179
|
+
### given +dir+ and return them in a Hash keyed by the font name.
|
|
180
|
+
def load_fonts( dir )
|
|
181
|
+
count = 0
|
|
182
|
+
fonts = {}
|
|
183
|
+
|
|
184
|
+
Dir["#{dir}/*.{otf,ttf}"].each {|file|
|
|
185
|
+
file.untaint
|
|
186
|
+
next unless File.file?( file ) && File.readable?( file )
|
|
187
|
+
face = nil
|
|
188
|
+
|
|
189
|
+
count += 1
|
|
190
|
+
begin
|
|
191
|
+
face = FT2::Face.load( file ) or
|
|
192
|
+
raise ".load returned nil"
|
|
193
|
+
rescue Exception => err
|
|
194
|
+
self.log.debug "While loading #{file}: %s" % err.message
|
|
195
|
+
next
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
fonts[ face.name ] = {
|
|
199
|
+
:file => file,
|
|
200
|
+
:family => face.family,
|
|
201
|
+
:style => face.style,
|
|
202
|
+
:bold => face.bold?,
|
|
203
|
+
:italic => face.italic?,
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
self.log.debug "Mapped %d of %d font files" %
|
|
208
|
+
[ fonts.keys.nitems, count ]
|
|
209
|
+
return fonts
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
### Create a GD::Image object from the given +txn+ and +rest+-style
|
|
214
|
+
### arguments.
|
|
215
|
+
def make_image( txn, fontname, size, caption )
|
|
216
|
+
|
|
217
|
+
# Arguments are read from either the query args or the REST-style
|
|
218
|
+
# parameters, preferring the latter.
|
|
219
|
+
|
|
220
|
+
# Fetch the text and normalize it
|
|
221
|
+
text = $1 if /([\x20-\x7f]+)/.match( caption )
|
|
222
|
+
text ||= txn.vargs[:imgtext]
|
|
223
|
+
text ||= DefaultText
|
|
224
|
+
text = text[0, MaxTextLength] if text.length > MaxTextLength
|
|
225
|
+
self.log.debug "Set text to %p" % text
|
|
226
|
+
|
|
227
|
+
# Get the face name the same way
|
|
228
|
+
face = $1 if /(\S+)/.match( fontname )
|
|
229
|
+
face ||= txn.vargs[:fontface]
|
|
230
|
+
face ||= @defaultfont
|
|
231
|
+
self.log.debug "Set face to %p" % face
|
|
232
|
+
|
|
233
|
+
# Get the pointsize the same way
|
|
234
|
+
pointsize = Integer($1) if /(\d+)/.match( size )
|
|
235
|
+
pointsize ||= Integer( txn.vargs[:fontsize] ) rescue nil
|
|
236
|
+
pointsize = DefaultFontSize if pointsize.nil? || pointsize.zero?
|
|
237
|
+
pointsize = MaxPointSize if pointsize > MaxPointSize
|
|
238
|
+
pointsize = MinPointSize if pointsize < MinPointSize
|
|
239
|
+
self.log.debug "Set pointsize to %p" % pointsize
|
|
240
|
+
|
|
241
|
+
# Calculate the size of the image based on the size of the rendered text
|
|
242
|
+
raise "No such font '#{face}'" unless @fonts.key?( face )
|
|
243
|
+
font = @fonts[ face ][:file]
|
|
244
|
+
self.log.debug "Font file is %p" % font
|
|
245
|
+
err, brect = GD::Image.stringFT( @foreground, font, pointsize, 0, 0, 0, text )
|
|
246
|
+
raise "Failed to calculate bounding-box for #{font}: #{err}" if err
|
|
247
|
+
self.log.debug "Bounding rect: %p" % [ brect ]
|
|
248
|
+
|
|
249
|
+
# Calculate the image size from the bounding rectangle with a 5-pixel
|
|
250
|
+
# border.
|
|
251
|
+
width = brect[2] - brect[6] + 10
|
|
252
|
+
height = brect[3] - brect[7] + 10
|
|
253
|
+
self.log.debug "Width: %d, height: %d" % [ width, height ]
|
|
254
|
+
|
|
255
|
+
# Make the image and colors
|
|
256
|
+
img = GD::Image.newTrueColor( width, height )
|
|
257
|
+
self.log.debug "Created image object: %p" % [ img ]
|
|
258
|
+
|
|
259
|
+
# If the GD library has been patched to support alpha-channel PNGs, turn
|
|
260
|
+
# that on.
|
|
261
|
+
if img.respond_to? :saveAlpha
|
|
262
|
+
self.log.debug "Using saveAlpha"
|
|
263
|
+
img.saveAlpha = true
|
|
264
|
+
img.alphaBlending = false
|
|
265
|
+
|
|
266
|
+
# Otherwise just muddle through as best we can with immediate compositing
|
|
267
|
+
else
|
|
268
|
+
self.log.debug "Using alphaBlending"
|
|
269
|
+
img.alphaBlending = true
|
|
270
|
+
img.transparent( @background )
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
# Fill the image with the background and draw the text and a border with
|
|
274
|
+
# the foreground color.
|
|
275
|
+
self.log.debug "Filling background"
|
|
276
|
+
img.fill( 1, 1, @background )
|
|
277
|
+
self.log.debug "Drawing string"
|
|
278
|
+
img.stringFT( @foreground, font, pointsize, 0, 5 - brect[6], 5 - brect[7], text )
|
|
279
|
+
self.log.debug "Filled and set string."
|
|
280
|
+
|
|
281
|
+
return img
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
end # class FancyImageText
|
|
285
|
+
|
|
286
|
+
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
#
|
|
3
|
+
# The ArrowTutorial class, a derivative of Arrow::Applet. It
|
|
4
|
+
# is the applet which loads and displays the tutorial (or will eventually).
|
|
5
|
+
#
|
|
6
|
+
# == VCS Id
|
|
7
|
+
#
|
|
8
|
+
# $Id$
|
|
9
|
+
#
|
|
10
|
+
# == Authors
|
|
11
|
+
#
|
|
12
|
+
# * Michael Granger <ged@FaerieMUD.org>
|
|
13
|
+
#
|
|
14
|
+
|
|
15
|
+
require 'arrow/applet'
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Blah
|
|
19
|
+
class ArrowTutorial < Arrow::Applet
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# Applet signature
|
|
23
|
+
Signature = {
|
|
24
|
+
:name => "Arrow Tutorial",
|
|
25
|
+
:description => "The tutorial applet.",
|
|
26
|
+
:maintainer => "ged@FaerieMUD.org",
|
|
27
|
+
:default_action => 'index',
|
|
28
|
+
:templates => {
|
|
29
|
+
:index => 'index.tmpl',
|
|
30
|
+
},
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
end # class ArrowTutorial
|
|
35
|
+
|
|
36
|
+
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
#
|
|
3
|
+
# The LogoGenerator class, a derivative of Arrow::Applet. It
|
|
4
|
+
# generates a blank logo of a given size and format.
|
|
5
|
+
#
|
|
6
|
+
# == VCS Id
|
|
7
|
+
#
|
|
8
|
+
# $Id$
|
|
9
|
+
#
|
|
10
|
+
# == Authors
|
|
11
|
+
#
|
|
12
|
+
# * Michael Granger <ged@FaerieMUD.org>
|
|
13
|
+
#
|
|
14
|
+
|
|
15
|
+
require 'arrow/applet'
|
|
16
|
+
require 'GD'
|
|
17
|
+
|
|
18
|
+
### It generates a blank logo of a given size and format.
|
|
19
|
+
class LogoGenerator < Arrow::Applet
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# Applet signature
|
|
23
|
+
Signature = {
|
|
24
|
+
:name => "Logo Generator",
|
|
25
|
+
:description => "Generate a blank logo of a given size and format.",
|
|
26
|
+
:maintainer => "ged@FaerieMUD.org",
|
|
27
|
+
:default_action => 'display',
|
|
28
|
+
:vargs => {
|
|
29
|
+
:display => {
|
|
30
|
+
:optional => [:height, :width, :format],
|
|
31
|
+
:constraints => {
|
|
32
|
+
:height => /^\d+$/,
|
|
33
|
+
:width => /^\d+$/,
|
|
34
|
+
:format => /^(png|jpe?g|gif)$/,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def initialize( *args )
|
|
42
|
+
super
|
|
43
|
+
|
|
44
|
+
@defaultLogoWidth = 60
|
|
45
|
+
@defaultLogoHeight = 60
|
|
46
|
+
@defaultLogoImageFormat = :png
|
|
47
|
+
|
|
48
|
+
@background= GD::Image.trueColorAlpha( "#ffffff", GD::AlphaTransparent )
|
|
49
|
+
@foreground = GD::Image.trueColorAlpha( "#000000", GD::AlphaOpaque )
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
######
|
|
54
|
+
public
|
|
55
|
+
######
|
|
56
|
+
|
|
57
|
+
def display_action( txn, *args )
|
|
58
|
+
width = txn.vargs[ :width ] || @defaultLogoWidth
|
|
59
|
+
height = txn.vargs[ :height ] || @defaultLogoHeight
|
|
60
|
+
format = txn.vargs[ :format ] || @defaultLogoImageFormat
|
|
61
|
+
self.log.debug "height = %d, width = %d, format = %p" %
|
|
62
|
+
[ height, width, format ]
|
|
63
|
+
|
|
64
|
+
img = GD::Image.newTrueColor( width, height )
|
|
65
|
+
self.log.debug "Created image"
|
|
66
|
+
|
|
67
|
+
if img.respond_to? :saveAlpha
|
|
68
|
+
self.log.debug "Using saveAlpha"
|
|
69
|
+
img.saveAlpha = true
|
|
70
|
+
img.alphaBlending = false
|
|
71
|
+
|
|
72
|
+
# Otherwise just muddle through as best we can with immediate compositing
|
|
73
|
+
else
|
|
74
|
+
self.log.debug "Using alphaBlending"
|
|
75
|
+
img.alphaBlending = true
|
|
76
|
+
img.transparent( background )
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
img.fill( 1, 1, @background )
|
|
80
|
+
self.log.debug "Filled it with %p" % @background
|
|
81
|
+
img.rectangle( 0, 0, width - 1, height - 1, @foreground )
|
|
82
|
+
self.log.debug "Drew bounding rectangle"
|
|
83
|
+
img.line( 0, 0, width - 1, height - 1, @foreground )
|
|
84
|
+
self.log.debug "Draw first crosshatch"
|
|
85
|
+
img.line( 0, height - 1, width - 1, 0, @foreground )
|
|
86
|
+
self.log.debug "Draw second crosshatch"
|
|
87
|
+
|
|
88
|
+
imgdata = img.pngStr
|
|
89
|
+
self.log.debug "Extracted image data (%d bytes)" % imgdata.length
|
|
90
|
+
txn.request.content_type = "image/png"
|
|
91
|
+
|
|
92
|
+
return imgdata
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
end # class LogoGenerator
|
|
97
|
+
|
|
98
|
+
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
#
|
|
3
|
+
# The MemCache class, a derivative of Arrow::Applet. This is a web interface to MemCached.
|
|
4
|
+
#
|
|
5
|
+
# == VCS Id
|
|
6
|
+
#
|
|
7
|
+
# $Id$
|
|
8
|
+
#
|
|
9
|
+
# == Authors
|
|
10
|
+
#
|
|
11
|
+
# * Michael Granger <ged@FaerieMUD.org>
|
|
12
|
+
#
|
|
13
|
+
|
|
14
|
+
require 'arrow/applet'
|
|
15
|
+
require 'memcache'
|
|
16
|
+
|
|
17
|
+
### This is a web interface to MemCached.
|
|
18
|
+
class MemCacheApplet < Arrow::Applet
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# Applet signature
|
|
22
|
+
Signature = {
|
|
23
|
+
:name => "memcache",
|
|
24
|
+
:description => "This is a web interface to MemCached.",
|
|
25
|
+
:maintainer => "ged@FaerieMUD.org",
|
|
26
|
+
:default_action => 'display',
|
|
27
|
+
:templates => {
|
|
28
|
+
:display => 'memcache/display.tmpl',
|
|
29
|
+
},
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
DefaultServers = [ 'localhost:11211' ]
|
|
33
|
+
|
|
34
|
+
def initialize( *args )
|
|
35
|
+
super
|
|
36
|
+
|
|
37
|
+
servers = DefaultServers
|
|
38
|
+
if @config.respond_to?( :memcache )
|
|
39
|
+
servers.replace( @config.memcache.servers )
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
@memcache = MemCache.new( *servers )
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
######
|
|
47
|
+
public
|
|
48
|
+
######
|
|
49
|
+
|
|
50
|
+
def display_action( txn, *args )
|
|
51
|
+
templ = self.load_template( :display )
|
|
52
|
+
templ.txn = txn
|
|
53
|
+
templ.memcache = @memcache
|
|
54
|
+
|
|
55
|
+
return templ
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
end # class MemCache
|
|
60
|
+
|
|
61
|
+
|