|
1 """ |
|
2 Rendering output |
|
3 """ |
|
4 |
|
5 import os, os.path |
|
6 |
|
7 ## Settings |
|
8 # width of a tile |
|
9 TILE_WIDTH = 256 |
|
10 TILE_HEIGHT = 256 |
|
11 |
|
12 # max. output resolution to allow |
|
13 MAX_PIXELS = 1920 * 1200 |
|
14 |
|
15 def dir_url (prefix, name, item) : |
|
16 """ |
|
17 Join together an absolute URL prefix, an optional directory name, and a directory item |
|
18 """ |
|
19 |
|
20 url = prefix |
|
21 |
|
22 if name : |
|
23 url += '/' + name |
|
24 |
|
25 url += '/' + item |
|
26 |
|
27 return url |
|
28 |
|
29 def dir_list (dir_path) : |
|
30 """ |
|
31 Yield a series of directory items to show for the given dir |
|
32 """ |
|
33 |
|
34 # link to parent |
|
35 yield '..' |
|
36 |
|
37 for item in os.listdir(dir_path) : |
|
38 path = os.path.join(dir_path, item) |
|
39 |
|
40 # skip dotfiles |
|
41 if item.startswith('.') : |
|
42 continue |
|
43 |
|
44 # show dirs |
|
45 if os.path.isdir(path) : |
|
46 yield item |
|
47 |
|
48 # examine ext |
|
49 base, ext = os.path.splitext(path) |
|
50 |
|
51 # show .png files with a .cache file |
|
52 if ext == '.png' and os.path.exists(base + '.cache') : |
|
53 yield item |
|
54 |
|
55 def scale_by_zoom (val, zoom) : |
|
56 """ |
|
57 Scale coordinates by zoom factor |
|
58 """ |
|
59 |
|
60 if zoom > 0 : |
|
61 return val << zoom |
|
62 |
|
63 elif zoom > 0 : |
|
64 return val >> -zoom |
|
65 |
|
66 else : |
|
67 return val |
|
68 |
|
69 |
|
70 ### Render HTML data |
|
71 def dir_html (prefix, name, path) : |
|
72 """ |
|
73 Directory index |
|
74 """ |
|
75 |
|
76 name = name.rstrip('/') |
|
77 |
|
78 return """\ |
|
79 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> |
|
80 <head> |
|
81 <title>Index of %(dir)s</title> |
|
82 <link rel="Stylesheet" type="text/css" href="%(prefix)s/static/style.css"> |
|
83 </head> |
|
84 <body> |
|
85 <h1>Index of %(dir)s</h1> |
|
86 |
|
87 <ul> |
|
88 %(listing)s |
|
89 </ul> |
|
90 </body> |
|
91 </html>""" % dict( |
|
92 prefix = prefix, |
|
93 dir = '/' + name, |
|
94 |
|
95 listing = "\n".join( |
|
96 # <li> link |
|
97 """<li><a href="%(url)s">%(name)s</a></li>""" % dict( |
|
98 # URL to dir |
|
99 url = dir_url(prefix, name, item), |
|
100 |
|
101 # item name |
|
102 name = item, |
|
103 ) for item in dir_list(path) |
|
104 ), |
|
105 ) |
|
106 |
|
107 def img_html (prefix, name, image) : |
|
108 """ |
|
109 HTML for image |
|
110 """ |
|
111 |
|
112 # a little slow, but not so bad - two stats(), heh |
|
113 info = image.info() |
|
114 img_width, img_height = info['img_width'], info['img_height'] |
|
115 |
|
116 return """\ |
|
117 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> |
|
118 <head> |
|
119 <title>%(title)s</title> |
|
120 <script src="%(prefix)s/static/prototype.js" type="text/javascript"></script> |
|
121 <script src="%(prefix)s/static/dragdrop.js" type="text/javascript"></script> |
|
122 <script src="%(prefix)s/static/builder.js" type="text/javascript"></script> |
|
123 <script src="%(prefix)s/static/tiles2.js" type="text/javascript"></script> |
|
124 <link rel="Stylesheet" type="text/css" href="%(prefix)s/static/style.css"> |
|
125 </head> |
|
126 <body> |
|
127 <div id="wrapper"> |
|
128 <div id="viewport" style="width: 100%%; height: 100%%"> |
|
129 <div class="overlay"> |
|
130 <input type="button" id="btn-zoom-in" value="Zoom In" /> |
|
131 <input type="button" id="btn-zoom-out" value="Zoom Out" /> |
|
132 <a class="link" id="lnk-image" href="#"></a> |
|
133 </div> |
|
134 |
|
135 <div class="substrate"></div> |
|
136 |
|
137 <div class="background"> |
|
138 Loading... |
|
139 </div> |
|
140 </div> |
|
141 </div> |
|
142 |
|
143 <script type="text/javascript"> |
|
144 var tile_source = new Source("%(tile_url)s", %(tile_width)d, %(tile_height)d, -4, 0, %(img_width)d, %(img_height)d); |
|
145 var main = new Viewport(tile_source, "viewport"); |
|
146 </script> |
|
147 </body> |
|
148 </html>""" % dict( |
|
149 title = name, |
|
150 prefix = prefix, |
|
151 tile_url = prefix + '/' + name, |
|
152 |
|
153 tile_width = TILE_WIDTH, |
|
154 tile_height = TILE_HEIGHT, |
|
155 |
|
156 img_width = img_width, |
|
157 img_height = img_height, |
|
158 ) |
|
159 |
|
160 ### Render PNG Data |
|
161 def img_png_tile (image, x, y, zoom) : |
|
162 """ |
|
163 Render given tile, returning PNG data |
|
164 """ |
|
165 |
|
166 return image.tile_mem( |
|
167 TILE_WIDTH, TILE_HEIGHT, |
|
168 scale_by_zoom(x, -zoom), scale_by_zoom(y, -zoom), |
|
169 zoom |
|
170 ) |
|
171 |
|
172 def img_png_region (image, cx, cy, zoom, width, height) : |
|
173 """ |
|
174 Render arbitrary tile, returning PNG data |
|
175 """ |
|
176 |
|
177 x = scale_by_zoom(cx - width / 2, -zoom) |
|
178 y = scale_by_zoom(cy - height / 2, -zoom) |
|
179 |
|
180 # safely limit |
|
181 if width * height > MAX_PIXELS : |
|
182 raise ValueError("Image size: %d * %d > %d" % (width, height, MAX_PIXELS)) |
|
183 |
|
184 return image.tile_mem( |
|
185 width, height, |
|
186 x, y, |
|
187 zoom |
|
188 ) |
|
189 |