atome 0.4.7.0 → 0.5.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (262) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/README.md +7 -4
  4. data/Rakefile +22 -13
  5. data/app_builder_helpers/Rakefile +63 -21
  6. data/exe/atome +91 -45
  7. data/lib/atome/atome.rb +129 -0
  8. data/lib/atome/extensions/atome.rb +41 -0
  9. data/lib/atome/{kernel/helpers → extensions}/geolocation.rb +0 -0
  10. data/lib/atome/{kernel/helpers → extensions}/ping.rb +0 -0
  11. data/lib/atome/{kernel/helpers → extensions}/sha.rb +3 -1
  12. data/lib/atome/genesis/generators/atome.rb +38 -0
  13. data/lib/atome/{renderers/headless/properties/generator.rb → genesis/generators/communication.rb} +2 -0
  14. data/lib/atome/genesis/generators/effect.rb +6 -0
  15. data/lib/atome/genesis/generators/event.rb +10 -0
  16. data/lib/atome/genesis/generators/geometry.rb +6 -0
  17. data/lib/atome/genesis/generators/identity.rb +29 -0
  18. data/lib/atome/genesis/generators/material.rb +10 -0
  19. data/lib/atome/genesis/generators/spatial.rb +13 -0
  20. data/lib/atome/genesis/generators/utility.rb +31 -0
  21. data/lib/atome/genesis/genesis.rb +46 -0
  22. data/lib/atome/genesis/sparkle.rb +58 -0
  23. data/lib/atome/helpers/callbacks.rb +12 -0
  24. data/lib/atome/helpers/color_helper/color/cmyk.rb +263 -0
  25. data/lib/atome/helpers/color_helper/color/css.rb +7 -0
  26. data/lib/atome/helpers/color_helper/color/grayscale.rb +197 -0
  27. data/lib/atome/helpers/color_helper/color/hsl.rb +240 -0
  28. data/lib/atome/helpers/color_helper/color/palette/adobecolor.rb +260 -0
  29. data/lib/atome/helpers/color_helper/color/palette/gimp.rb +104 -0
  30. data/lib/atome/helpers/color_helper/color/palette/monocontrast.rb +164 -0
  31. data/lib/atome/helpers/color_helper/color/palette.rb +4 -0
  32. data/lib/atome/helpers/color_helper/color/rgb/colors.rb +167 -0
  33. data/lib/atome/helpers/color_helper/color/rgb/contrast.rb +57 -0
  34. data/lib/atome/helpers/color_helper/color/rgb/metallic.rb +28 -0
  35. data/lib/atome/helpers/color_helper/color/rgb.rb +715 -0
  36. data/lib/atome/helpers/color_helper/color/yiq.rb +62 -0
  37. data/lib/atome/helpers/color_helper/color.rb +196 -0
  38. data/lib/atome/helpers/essentials.rb +42 -0
  39. data/lib/atome/helpers/sanitizer.rb +23 -0
  40. data/lib/atome/helpers/utilities.rb +54 -0
  41. data/lib/atome/kernel/essentials.rb +23 -0
  42. data/lib/atome/kernel/universe.rb +92 -26
  43. data/lib/atome/presets/atome.rb +88 -0
  44. data/lib/atome/processors/utilities.rb +10 -0
  45. data/lib/atome/renderers/browser/atome.rb +108 -0
  46. data/lib/atome/renderers/browser/browser.rb +225 -0
  47. data/lib/atome/renderers/browser/effect.rb +23 -0
  48. data/lib/atome/renderers/browser/event.rb +37 -0
  49. data/lib/atome/renderers/browser/geometry.rb +11 -0
  50. data/lib/atome/renderers/browser/identity.rb +24 -0
  51. data/lib/atome/renderers/browser/material.rb +43 -0
  52. data/lib/atome/renderers/{opal → browser}/opal_browser.rb +0 -2
  53. data/lib/atome/renderers/browser/spatial.rb +23 -0
  54. data/lib/atome/renderers/browser/utility.rb +39 -0
  55. data/lib/atome/renderers/headless/headless.rb +10 -0
  56. data/lib/atome/renderers/headless/utility.rb +6 -0
  57. data/lib/atome/renderers/html/atome.rb +47 -0
  58. data/lib/atome/renderers/html/effect.rb +19 -0
  59. data/lib/atome/renderers/html/event.rb +9 -0
  60. data/lib/atome/renderers/html/geometry.rb +11 -0
  61. data/lib/atome/renderers/html/html.rb +42 -0
  62. data/lib/atome/renderers/html/identity.rb +14 -0
  63. data/lib/atome/renderers/html/opal_browser.rb +6 -0
  64. data/lib/atome/renderers/html/spatial.rb +28 -0
  65. data/lib/atome/renderers/html/utility.rb +17 -0
  66. data/lib/atome/renderers/opal/atome_opal_extensions.rb +1 -1
  67. data/lib/atome/renderers/opal/extensions/atome.rb +29 -0
  68. data/lib/atome/renderers/opal/opal.rb +4 -0
  69. data/lib/atome/renderers/renderer.rb +7 -7
  70. data/lib/atome/renderers/server/server.rb +10 -0
  71. data/lib/atome/renderers/server/utility.rb +6 -0
  72. data/lib/atome/version.rb +1 -2
  73. data/lib/atome.rb +25 -44
  74. data/vendor/assets/application/index.rb +3 -1
  75. data/vendor/assets/application/required_example.rb +1 -0
  76. data/vendor/assets/{build/js/application.js → aui.rb} +0 -0
  77. data/vendor/assets/build/css/style.css +51 -0
  78. data/vendor/assets/build/index.html +7 -8
  79. data/vendor/assets/build/js/atome/atome.js +141 -68
  80. data/vendor/assets/build/medias/rubies/examples/_2_solve.rb +13 -0
  81. data/vendor/assets/build/medias/rubies/examples/{animation.rb → _animation.rb} +0 -0
  82. data/vendor/assets/build/medias/rubies/examples/{drag.rb → _drag.rb} +1 -0
  83. data/vendor/assets/build/medias/rubies/examples/atome.new.rb +13 -10
  84. data/vendor/assets/build/medias/rubies/examples/auto_height.rb +2 -0
  85. data/vendor/assets/build/medias/rubies/examples/auto_width.rb +2 -0
  86. data/vendor/assets/build/medias/rubies/examples/blur.rb +4 -0
  87. data/vendor/assets/build/medias/rubies/examples/bottom.rb +3 -1
  88. data/vendor/assets/build/medias/rubies/examples/box.rb +12 -8
  89. data/vendor/assets/build/medias/rubies/examples/circle.rb +2 -0
  90. data/vendor/assets/build/medias/rubies/examples/clear.rb +2 -1
  91. data/vendor/assets/build/medias/rubies/examples/code.rb +10 -4
  92. data/vendor/assets/build/medias/rubies/examples/color.rb +47 -8
  93. data/vendor/assets/build/medias/rubies/examples/create_atome_in_atome.rb +2 -0
  94. data/vendor/assets/build/medias/rubies/examples/delete.rb +7 -0
  95. data/vendor/assets/build/medias/rubies/examples/element.rb +6 -0
  96. data/vendor/assets/build/medias/rubies/examples/fullscreen.rb +15 -0
  97. data/vendor/assets/build/medias/rubies/examples/get_renderer_list.rb +3 -1
  98. data/vendor/assets/build/medias/rubies/examples/grab.rb +2 -0
  99. data/vendor/assets/build/medias/rubies/examples/height.rb +7 -2
  100. data/vendor/assets/build/medias/rubies/examples/id.rb +14 -0
  101. data/vendor/assets/build/medias/rubies/examples/image.rb +6 -2
  102. data/vendor/assets/build/medias/rubies/examples/left.rb +7 -2
  103. data/vendor/assets/build/medias/rubies/examples/link.rb +12 -3
  104. data/vendor/assets/build/medias/rubies/examples/monitoring.rb +33 -0
  105. data/vendor/assets/build/medias/rubies/examples/on.rb +11 -7
  106. data/vendor/assets/build/medias/rubies/examples/parent.rb +7 -5
  107. data/vendor/assets/build/medias/rubies/examples/read.rb +6 -2
  108. data/vendor/assets/build/medias/rubies/examples/refresh.rb +8 -0
  109. data/vendor/assets/build/medias/rubies/examples/repeat.rb +2 -0
  110. data/vendor/assets/build/medias/rubies/examples/right.rb +3 -1
  111. data/vendor/assets/build/medias/rubies/examples/rotate.rb +2 -0
  112. data/vendor/assets/build/medias/rubies/examples/schedule.rb +8 -11
  113. data/vendor/assets/build/medias/rubies/examples/shadow.rb +30 -0
  114. data/vendor/assets/build/medias/rubies/examples/smooth.rb +2 -0
  115. data/vendor/assets/build/medias/rubies/examples/text.rb +21 -7
  116. data/vendor/assets/build/medias/rubies/examples/top.rb +3 -0
  117. data/vendor/assets/build/medias/rubies/examples/touch.rb +7 -0
  118. data/vendor/assets/build/medias/rubies/examples/video.rb +32 -23
  119. data/vendor/assets/build/medias/rubies/examples/wait.rb +8 -3
  120. data/vendor/assets/build/medias/rubies/examples/web.rb +7 -4
  121. data/vendor/assets/build/medias/rubies/examples/width.rb +6 -2
  122. data/vendor/assets/server/atome_server.rb +3 -5
  123. metadata +76 -164
  124. data/lib/atome/atome_native_extensions.rb +0 -5
  125. data/lib/atome/extensions/helper.rb +0 -112
  126. data/lib/atome/kernel/atome.rb +0 -99
  127. data/lib/atome/kernel/generators/generator.rb +0 -517
  128. data/lib/atome/kernel/generators/genesis.rb +0 -277
  129. data/lib/atome/kernel/generators/sanitizer.rb +0 -73
  130. data/lib/atome/kernel/generators/shapes.rb +0 -55
  131. data/lib/atome/kernel/helpers/internal_methods.rb +0 -173
  132. data/lib/atome/kernel/helpers/utilities.rb +0 -39
  133. data/lib/atome/kernel/properties/essential.rb +0 -77
  134. data/lib/atome/kernel/sparkle.rb +0 -38
  135. data/lib/atome/renderers/opal/properties/generator.rb +0 -1
  136. data/lib/atome/renderers/server/properties/generator.rb +0 -9
  137. data/vendor/assets/build/medias/audios/guitar.wav +0 -0
  138. data/vendor/assets/build/medias/images/beach.jpg +0 -0
  139. data/vendor/assets/build/medias/rubies/examples/Old_examples/!demos.rb +0 -111
  140. data/vendor/assets/build/medias/rubies/examples/Old_examples/action.rb +0 -12
  141. data/vendor/assets/build/medias/rubies/examples/Old_examples/add.rb +0 -26
  142. data/vendor/assets/build/medias/rubies/examples/Old_examples/alignment.rb +0 -27
  143. data/vendor/assets/build/medias/rubies/examples/Old_examples/animation.rb +0 -92
  144. data/vendor/assets/build/medias/rubies/examples/Old_examples/atome_as_property.rb +0 -20
  145. data/vendor/assets/build/medias/rubies/examples/Old_examples/atome_list.rb +0 -4
  146. data/vendor/assets/build/medias/rubies/examples/Old_examples/atomiser.rb +0 -17
  147. data/vendor/assets/build/medias/rubies/examples/Old_examples/attach_extract.rb +0 -13
  148. data/vendor/assets/build/medias/rubies/examples/Old_examples/authorisation.rb +0 -22
  149. data/vendor/assets/build/medias/rubies/examples/Old_examples/batch.rb +0 -6
  150. data/vendor/assets/build/medias/rubies/examples/Old_examples/blend.rb +0 -15
  151. data/vendor/assets/build/medias/rubies/examples/Old_examples/blur.rb +0 -9
  152. data/vendor/assets/build/medias/rubies/examples/Old_examples/border.rb +0 -9
  153. data/vendor/assets/build/medias/rubies/examples/Old_examples/calendar.rb +0 -5
  154. data/vendor/assets/build/medias/rubies/examples/Old_examples/capture.rb +0 -57
  155. data/vendor/assets/build/medias/rubies/examples/Old_examples/center.rb +0 -21
  156. data/vendor/assets/build/medias/rubies/examples/Old_examples/child.rb +0 -18
  157. data/vendor/assets/build/medias/rubies/examples/Old_examples/clear.rb +0 -21
  158. data/vendor/assets/build/medias/rubies/examples/Old_examples/clip.rb +0 -11
  159. data/vendor/assets/build/medias/rubies/examples/Old_examples/code.rb +0 -7
  160. data/vendor/assets/build/medias/rubies/examples/Old_examples/code_editor.rb +0 -26
  161. data/vendor/assets/build/medias/rubies/examples/Old_examples/collaborate.rb +0 -115
  162. data/vendor/assets/build/medias/rubies/examples/Old_examples/convert_to_px.rb +0 -14
  163. data/vendor/assets/build/medias/rubies/examples/Old_examples/copy_paste.rb +0 -35
  164. data/vendor/assets/build/medias/rubies/examples/Old_examples/current_code.rb +0 -14
  165. data/vendor/assets/build/medias/rubies/examples/Old_examples/cursor.rb +0 -3
  166. data/vendor/assets/build/medias/rubies/examples/Old_examples/data.rb +0 -11
  167. data/vendor/assets/build/medias/rubies/examples/Old_examples/database.rb +0 -29
  168. data/vendor/assets/build/medias/rubies/examples/Old_examples/delete.rb +0 -12
  169. data/vendor/assets/build/medias/rubies/examples/Old_examples/display.rb +0 -19
  170. data/vendor/assets/build/medias/rubies/examples/Old_examples/disposition.rb +0 -10
  171. data/vendor/assets/build/medias/rubies/examples/Old_examples/double_and_long_touch.rb +0 -23
  172. data/vendor/assets/build/medias/rubies/examples/Old_examples/drag.rb +0 -61
  173. data/vendor/assets/build/medias/rubies/examples/Old_examples/drag_and_drop_import.rb +0 -1
  174. data/vendor/assets/build/medias/rubies/examples/Old_examples/drop.rb +0 -23
  175. data/vendor/assets/build/medias/rubies/examples/Old_examples/duplicate.rb +0 -11
  176. data/vendor/assets/build/medias/rubies/examples/Old_examples/edit.rb +0 -6
  177. data/vendor/assets/build/medias/rubies/examples/Old_examples/eval.rb +0 -9
  178. data/vendor/assets/build/medias/rubies/examples/Old_examples/extract_detach.rb +0 -23
  179. data/vendor/assets/build/medias/rubies/examples/Old_examples/fill.rb +0 -10
  180. data/vendor/assets/build/medias/rubies/examples/Old_examples/find.rb +0 -37
  181. data/vendor/assets/build/medias/rubies/examples/Old_examples/fit.rb +0 -44
  182. data/vendor/assets/build/medias/rubies/examples/Old_examples/fullscreen.rb +0 -28
  183. data/vendor/assets/build/medias/rubies/examples/Old_examples/generate.rb +0 -7
  184. data/vendor/assets/build/medias/rubies/examples/Old_examples/gradient.rb +0 -24
  185. data/vendor/assets/build/medias/rubies/examples/Old_examples/group.rb +0 -21
  186. data/vendor/assets/build/medias/rubies/examples/Old_examples/helper.rb +0 -64
  187. data/vendor/assets/build/medias/rubies/examples/Old_examples/history.rb +0 -7
  188. data/vendor/assets/build/medias/rubies/examples/Old_examples/hue.rb +0 -10
  189. data/vendor/assets/build/medias/rubies/examples/Old_examples/input_text.rb +0 -54
  190. data/vendor/assets/build/medias/rubies/examples/Old_examples/insert_attach.rb +0 -13
  191. data/vendor/assets/build/medias/rubies/examples/Old_examples/internationalisation.rb +0 -10
  192. data/vendor/assets/build/medias/rubies/examples/Old_examples/key.rb +0 -19
  193. data/vendor/assets/build/medias/rubies/examples/Old_examples/keyboard_shortcut.rb +0 -69
  194. data/vendor/assets/build/medias/rubies/examples/Old_examples/list_methods.rb +0 -4
  195. data/vendor/assets/build/medias/rubies/examples/Old_examples/list_types.rb +0 -4
  196. data/vendor/assets/build/medias/rubies/examples/Old_examples/listen.rb +0 -47
  197. data/vendor/assets/build/medias/rubies/examples/Old_examples/mail.rb +0 -9
  198. data/vendor/assets/build/medias/rubies/examples/Old_examples/map.rb +0 -6
  199. data/vendor/assets/build/medias/rubies/examples/Old_examples/mask.rb +0 -15
  200. data/vendor/assets/build/medias/rubies/examples/Old_examples/media_recorder.rb +0 -24
  201. data/vendor/assets/build/medias/rubies/examples/Old_examples/media_streaming.rb +0 -41
  202. data/vendor/assets/build/medias/rubies/examples/Old_examples/meteo.rb +0 -41
  203. data/vendor/assets/build/medias/rubies/examples/Old_examples/methods_chaining.rb +0 -8
  204. data/vendor/assets/build/medias/rubies/examples/Old_examples/midi.rb +0 -37
  205. data/vendor/assets/build/medias/rubies/examples/Old_examples/monitoring.rb +0 -47
  206. data/vendor/assets/build/medias/rubies/examples/Old_examples/mulitrendering.rb +0 -7
  207. data/vendor/assets/build/medias/rubies/examples/Old_examples/noise_gradient_texture.rb +0 -26
  208. data/vendor/assets/build/medias/rubies/examples/Old_examples/notification.rb +0 -9
  209. data/vendor/assets/build/medias/rubies/examples/Old_examples/object_in_object.rb +0 -13
  210. data/vendor/assets/build/medias/rubies/examples/Old_examples/on_resize.rb +0 -12
  211. data/vendor/assets/build/medias/rubies/examples/Old_examples/over.rb +0 -15
  212. data/vendor/assets/build/medias/rubies/examples/Old_examples/overflow.rb +0 -22
  213. data/vendor/assets/build/medias/rubies/examples/Old_examples/parameter.rb +0 -14
  214. data/vendor/assets/build/medias/rubies/examples/Old_examples/parent.rb +0 -19
  215. data/vendor/assets/build/medias/rubies/examples/Old_examples/particle.rb +0 -15
  216. data/vendor/assets/build/medias/rubies/examples/Old_examples/pay.rb +0 -7
  217. data/vendor/assets/build/medias/rubies/examples/Old_examples/ping.rb +0 -7
  218. data/vendor/assets/build/medias/rubies/examples/Old_examples/play.rb +0 -24
  219. data/vendor/assets/build/medias/rubies/examples/Old_examples/play_audio.rb +0 -6
  220. data/vendor/assets/build/medias/rubies/examples/Old_examples/position.rb +0 -7
  221. data/vendor/assets/build/medias/rubies/examples/Old_examples/read_file.rb +0 -9
  222. data/vendor/assets/build/medias/rubies/examples/Old_examples/reboot.rb +0 -15
  223. data/vendor/assets/build/medias/rubies/examples/Old_examples/refresh.rb +0 -17
  224. data/vendor/assets/build/medias/rubies/examples/Old_examples/remote_server.rb +0 -31
  225. data/vendor/assets/build/medias/rubies/examples/Old_examples/render.rb +0 -17
  226. data/vendor/assets/build/medias/rubies/examples/Old_examples/repeat.rb +0 -19
  227. data/vendor/assets/build/medias/rubies/examples/Old_examples/require_remote.rb +0 -3
  228. data/vendor/assets/build/medias/rubies/examples/Old_examples/restore_atome.rb +0 -11
  229. data/vendor/assets/build/medias/rubies/examples/Old_examples/resurect.rb +0 -30
  230. data/vendor/assets/build/medias/rubies/examples/Old_examples/ruby_version.rb +0 -1
  231. data/vendor/assets/build/medias/rubies/examples/Old_examples/say.rb +0 -3
  232. data/vendor/assets/build/medias/rubies/examples/Old_examples/scale.rb +0 -41
  233. data/vendor/assets/build/medias/rubies/examples/Old_examples/schedule.rb +0 -39
  234. data/vendor/assets/build/medias/rubies/examples/Old_examples/scroll.rb +0 -9
  235. data/vendor/assets/build/medias/rubies/examples/Old_examples/select.rb +0 -32
  236. data/vendor/assets/build/medias/rubies/examples/Old_examples/selector.rb +0 -6
  237. data/vendor/assets/build/medias/rubies/examples/Old_examples/shadow.rb +0 -30
  238. data/vendor/assets/build/medias/rubies/examples/Old_examples/shape_with_path.rb +0 -7
  239. data/vendor/assets/build/medias/rubies/examples/Old_examples/size.rb +0 -109
  240. data/vendor/assets/build/medias/rubies/examples/Old_examples/smooth.rb +0 -5
  241. data/vendor/assets/build/medias/rubies/examples/Old_examples/speech_renderer.rb +0 -5
  242. data/vendor/assets/build/medias/rubies/examples/Old_examples/synth.rb +0 -6
  243. data/vendor/assets/build/medias/rubies/examples/Old_examples/system.rb +0 -3
  244. data/vendor/assets/build/medias/rubies/examples/Old_examples/tags.rb +0 -18
  245. data/vendor/assets/build/medias/rubies/examples/Old_examples/text.rb +0 -33
  246. data/vendor/assets/build/medias/rubies/examples/Old_examples/text_selection.rb +0 -33
  247. data/vendor/assets/build/medias/rubies/examples/Old_examples/text_to_midi.rb +0 -22
  248. data/vendor/assets/build/medias/rubies/examples/Old_examples/touch.rb +0 -23
  249. data/vendor/assets/build/medias/rubies/examples/Old_examples/touch_stop_propagation.rb +0 -27
  250. data/vendor/assets/build/medias/rubies/examples/Old_examples/treat_object_in_object.rb +0 -26
  251. data/vendor/assets/build/medias/rubies/examples/Old_examples/type_mutations.rb +0 -27
  252. data/vendor/assets/build/medias/rubies/examples/Old_examples/video_callback.rb +0 -46
  253. data/vendor/assets/build/medias/rubies/examples/Old_examples/view_mode.rb +0 -29
  254. data/vendor/assets/build/medias/rubies/examples/Old_examples/virtual_events.rb +0 -17
  255. data/vendor/assets/build/medias/rubies/examples/Old_examples/visual.rb +0 -23
  256. data/vendor/assets/build/medias/rubies/examples/Old_examples/vr_display.rb +0 -5
  257. data/vendor/assets/build/medias/rubies/examples/Old_examples/wait.rb +0 -21
  258. data/vendor/assets/build/medias/rubies/examples/Old_examples/web.rb +0 -10
  259. data/vendor/assets/build/medias/rubies/examples/Old_examples/web_address_bar.rb +0 -14
  260. data/vendor/assets/build/medias/rubies/examples/Old_examples/websocket.rb +0 -16
  261. data/vendor/assets/build/medias/rubies/examples/Old_examples/webstate.rb +0 -10
  262. data/vendor/assets/build/medias/videos/lion_king.mp4 +0 -0
@@ -0,0 +1,197 @@
1
+ # A colour object representing shades of grey. Used primarily in PDF
2
+ # document creation.
3
+ class Color::GrayScale
4
+ include Color
5
+
6
+ # The format of a DeviceGrey colour for PDF. In color-tools 2.0 this will
7
+ # be removed from this package and added back as a modification by the
8
+ # PDF::Writer package.
9
+ PDF_FORMAT_STR = "%.3f %s"
10
+
11
+ class << self
12
+ # Creates a greyscale colour object from fractional values 0..1.
13
+ #
14
+ # Color::GreyScale.from_fraction(0.5)
15
+ def from_fraction(g = 0, &block)
16
+ new(g, 1.0, &block)
17
+ end
18
+
19
+ # Creates a greyscale colour object from percentages 0..100.
20
+ #
21
+ # Color::GrayScale.from_percent(50)
22
+ def from_percent(g = 0, &block)
23
+ new(g, &block)
24
+ end
25
+ end
26
+
27
+ # Creates a greyscale colour object from percentages 0..100.
28
+ #
29
+ # Color::GrayScale.new(50)
30
+ def initialize(g = 0, radix = 100.0, &block) # :yields self:
31
+ @g = Color.normalize(g / radix)
32
+ block.call if block
33
+ end
34
+
35
+ # Coerces the other Color object to grayscale.
36
+ def coerce(other)
37
+ other.to_grayscale
38
+ end
39
+
40
+ # Present the colour as a DeviceGrey fill colour string for PDF. This will
41
+ # be removed from the default package in color-tools 2.0.
42
+ def pdf_fill
43
+ PDF_FORMAT_STR % [ @g, "g" ]
44
+ end
45
+
46
+ # Present the colour as a DeviceGrey stroke colour string for PDF. This
47
+ # will be removed from the default package in color-tools 2.0.
48
+ def pdf_stroke
49
+ PDF_FORMAT_STR % [ @g, "G" ]
50
+ end
51
+
52
+ def to_255
53
+ [(@g * 255).round, 255].min
54
+ end
55
+ private :to_255
56
+
57
+ # Present the colour as an HTML/CSS colour string.
58
+ def html
59
+ gs = "%02x" % to_255
60
+ "##{gs * 3}"
61
+ end
62
+
63
+ # Present the colour as an RGB HTML/CSS colour string (e.g., "rgb(0%, 50%,
64
+ # 100%)").
65
+ def css_rgb
66
+ "rgb(%3.2f%%, %3.2f%%, %3.2f%%)" % [ gray, gray, gray ]
67
+ end
68
+
69
+ # Present the colour as an RGBA (with alpha) HTML/CSS colour string (e.g.,
70
+ # "rgb(0%, 50%, 100%, 1)").
71
+ def css_rgba(alpha = 1)
72
+ "rgba(%3.2f%%, %3.2f%%, %3.2f%%, %1.2f)" % [ gray, gray, gray, alpha ]
73
+ end
74
+
75
+ # Present the colour as an HSL HTML/CSS colour string (e.g., "hsl(180,
76
+ # 25%, 35%)"). Note that this will perform a #to_hsl operation.
77
+ def css_hsl
78
+ to_hsl.css_hsl
79
+ end
80
+
81
+ # Present the colour as an HSLA (with alpha) HTML/CSS colour string (e.g.,
82
+ # "hsla(180, 25%, 35%, 1)"). Note that this will perform a #to_hsl
83
+ # operation.
84
+ def css_hsla
85
+ to_hsl.css_hsla
86
+ end
87
+
88
+ # Convert the greyscale colour to CMYK.
89
+ def to_cmyk
90
+ k = 1.0 - @g.to_f
91
+ Color::CMYK.from_fraction(0, 0, 0, k)
92
+ end
93
+
94
+ # Convert the greyscale colour to RGB.
95
+ def to_rgb(ignored = true)
96
+ Color::RGB.from_fraction(g, g, g)
97
+ end
98
+
99
+ # Reflexive conversion.
100
+ def to_grayscale
101
+ self
102
+ end
103
+ alias to_greyscale to_grayscale
104
+
105
+ # Lightens the greyscale colour by the stated percent.
106
+ def lighten_by(percent)
107
+ g = [@g + (@g * (percent / 100.0)), 1.0].min
108
+ Color::GrayScale.from_fraction(g)
109
+ end
110
+
111
+ # Darken the greyscale colour by the stated percent.
112
+ def darken_by(percent)
113
+ g = [@g - (@g * (percent / 100.0)), 0.0].max
114
+ Color::GrayScale.from_fraction(g)
115
+ end
116
+
117
+ # Returns the YIQ (NTSC) colour encoding of the greyscale value. This is
118
+ # an approximation, as the values for I and Q are calculated by treating
119
+ # the greyscale value as an RGB value. The Y (intensity or brightness)
120
+ # value is the same as the greyscale value.
121
+ def to_yiq
122
+ y = @g
123
+ i = (@g * 0.596) + (@g * -0.275) + (@g * -0.321)
124
+ q = (@g * 0.212) + (@g * -0.523) + (@g * 0.311)
125
+ Color::YIQ.from_fraction(y, i, q)
126
+ end
127
+
128
+ # Returns the HSL colour encoding of the greyscale value.
129
+ def to_hsl
130
+ Color::HSL.from_fraction(0, 0, @g)
131
+ end
132
+
133
+ # Returns the brightness value for this greyscale value; this is the
134
+ # greyscale value itself.
135
+ def brightness
136
+ @g
137
+ end
138
+
139
+ # Returns the grayscale value as a percentage of white (100% gray is
140
+ # white).
141
+ def gray
142
+ @g * 100.0
143
+ end
144
+ alias grey gray
145
+ # Returns the grayscale value as a fractional value of white in the range
146
+ # 0.0 .. 1.0.
147
+ def g
148
+ @g
149
+ end
150
+ # Sets the grayscale value as a percentage of white.
151
+ def gray=(gg)
152
+ @g = Color.normalize(gg / 100.0)
153
+ end
154
+ alias grey= gray= ;
155
+ # Returns the grayscale value as a fractional value of white in the range
156
+ # 0.0 .. 1.0.
157
+ def g=(gg)
158
+ @g = Color.normalize(gg)
159
+ end
160
+
161
+ # Adds another colour to the current colour. The other colour will be
162
+ # converted to grayscale before addition. This conversion depends upon a
163
+ # #to_grayscale method on the other colour.
164
+ #
165
+ # The addition is done using the grayscale accessor methods to ensure a
166
+ # valid colour in the result.
167
+ def +(other)
168
+ self.class.from_fraction(g + other.to_grayscale.g)
169
+ end
170
+
171
+ # Subtracts another colour to the current colour. The other colour will be
172
+ # converted to grayscale before subtraction. This conversion depends upon
173
+ # a #to_grayscale method on the other colour.
174
+ #
175
+ # The subtraction is done using the grayscale accessor methods to ensure a
176
+ # valid colour in the result.
177
+ def -(other)
178
+ self + (-other)
179
+ end
180
+
181
+ def inspect
182
+ "Gray [%.2f%%]" % [ gray ]
183
+ end
184
+
185
+ def to_a
186
+ [ g ]
187
+ end
188
+
189
+ def -@
190
+ gs = self.dup
191
+ gs.instance_variable_set(:@g, -g)
192
+ gs
193
+ end
194
+ end
195
+
196
+ # A synonym for Color::GrayScale.
197
+ Color::GreyScale = Color::GrayScale
@@ -0,0 +1,240 @@
1
+ # -*- ruby encoding: utf-8 -*-
2
+
3
+ # An HSL colour object. Internally, the hue (#h), saturation (#s), and
4
+ # luminosity/lightness (#l) values are dealt with as fractional values in
5
+ # the range 0..1.
6
+ class Color::HSL
7
+ include Color
8
+
9
+ class << self
10
+ # Creates an HSL colour object from fractional values 0..1.
11
+ def from_fraction(h = 0.0, s = 0.0, l = 0.0, &block)
12
+ new(h, s, l, 1.0, 1.0, &block)
13
+ end
14
+ end
15
+
16
+ # Coerces the other Color object into HSL.
17
+ def coerce(other)
18
+ other.to_hsl
19
+ end
20
+
21
+ # Creates an HSL colour object from the standard values of degrees and
22
+ # percentages (e.g., 145 deg, 30%, 50%).
23
+ def initialize(h = 0, s = 0, l = 0, radix1 = 360.0, radix2 = 100.0, &block) # :yields self:
24
+ @h = Color.normalize(h / radix1)
25
+ @s = Color.normalize(s / radix2)
26
+ @l = Color.normalize(l / radix2)
27
+ block.call if block
28
+ end
29
+
30
+ # Present the colour as an HTML/CSS colour string.
31
+ def html
32
+ to_rgb.html
33
+ end
34
+
35
+ # Present the colour as an RGB HTML/CSS colour string (e.g., "rgb(0%, 50%,
36
+ # 100%)"). Note that this will perform a #to_rgb operation using the
37
+ # default conversion formula.
38
+ def css_rgb
39
+ to_rgb.css_rgb
40
+ end
41
+
42
+ # Present the colour as an RGBA (with alpha) HTML/CSS colour string (e.g.,
43
+ # "rgb(0%, 50%, 100%, 1)"). Note that this will perform a #to_rgb
44
+ # operation using the default conversion formula.
45
+ def css_rgba(alpha = 1)
46
+ to_rgb.css_rgba(alpha)
47
+ end
48
+
49
+ # Present the colour as an HSL HTML/CSS colour string (e.g., "hsl(180,
50
+ # 25%, 35%)").
51
+ def css_hsl
52
+ "hsl(%3.2f, %3.2f%%, %3.2f%%)" % [ hue, saturation, luminosity ]
53
+ end
54
+
55
+ # Present the colour as an HSLA (with alpha) HTML/CSS colour string (e.g.,
56
+ # "hsla(180, 25%, 35%, 1)").
57
+ def css_hsla
58
+ "hsla(%3.2f, %3.2f%%, %3.2f%%, %3.2f)" % [ hue, saturation, luminosity, 1 ]
59
+ end
60
+
61
+ # Converting from HSL to RGB. As with all colour conversions, this is
62
+ # approximate at best. The code here is adapted from fvd and van Dam,
63
+ # originally found at [1] (implemented similarly at [2]).
64
+ #
65
+ # This simplifies the calculations with the following assumptions:
66
+ # - Luminance values <= 0 always translate to Color::RGB::Black.
67
+ # - Luminance values >= 1 always translate to Color::RGB::White.
68
+ # - Saturation values <= 0 always translate to a shade of gray using
69
+ # luminance as a percentage of gray.
70
+ #
71
+ # [1] http://bobpowell.net/RGBHSB.aspx
72
+ # [2] http://support.microsoft.com/kb/29240
73
+ def to_rgb(*)
74
+ if Color.near_zero_or_less?(l)
75
+ Color::RGB::Black
76
+ elsif Color.near_one_or_more?(l)
77
+ Color::RGB::White
78
+ elsif Color.near_zero?(s)
79
+ Color::RGB.from_grayscale_fraction(l)
80
+ else
81
+ # Only needed for Ruby 1.8. For Ruby 1.9+, we can do:
82
+ # Color::RGB.new(*compute_fvd_rgb, 1.0)
83
+ Color::RGB.new(*(compute_fvd_rgb + [ 1.0 ]))
84
+ end
85
+ end
86
+
87
+ # Converts to RGB then YIQ.
88
+ def to_yiq
89
+ to_rgb.to_yiq
90
+ end
91
+
92
+ # Converts to RGB then CMYK.
93
+ def to_cmyk
94
+ to_rgb.to_cmyk
95
+ end
96
+
97
+ # Returns the luminosity (#l) of the colour.
98
+ def brightness
99
+ @l
100
+ end
101
+ def to_greyscale
102
+ Color::GrayScale.from_fraction(@l)
103
+ end
104
+ alias to_grayscale to_greyscale
105
+
106
+ # Returns the hue of the colour in degrees.
107
+ def hue
108
+ @h * 360.0
109
+ end
110
+ # Returns the hue of the colour in the range 0.0 .. 1.0.
111
+ def h
112
+ @h
113
+ end
114
+ # Sets the hue of the colour in degrees. Colour is perceived as a wheel,
115
+ # so values should be set properly even with negative degree values.
116
+ def hue=(hh)
117
+ hh = hh / 360.0
118
+
119
+ hh += 1.0 if hh < 0.0
120
+ hh -= 1.0 if hh > 1.0
121
+
122
+ @h = Color.normalize(hh)
123
+ end
124
+ # Sets the hue of the colour in the range 0.0 .. 1.0.
125
+ def h=(hh)
126
+ @h = Color.normalize(hh)
127
+ end
128
+ # Returns the percentage of saturation of the colour.
129
+ def saturation
130
+ @s * 100.0
131
+ end
132
+ # Returns the saturation of the colour in the range 0.0 .. 1.0.
133
+ def s
134
+ @s
135
+ end
136
+ # Sets the percentage of saturation of the colour.
137
+ def saturation=(ss)
138
+ @s = Color.normalize(ss / 100.0)
139
+ end
140
+ # Sets the saturation of the colour in the ragne 0.0 .. 1.0.
141
+ def s=(ss)
142
+ @s = Color.normalize(ss)
143
+ end
144
+
145
+ # Returns the percentage of luminosity of the colour.
146
+ def luminosity
147
+ @l * 100.0
148
+ end
149
+ alias lightness luminosity
150
+ # Returns the luminosity of the colour in the range 0.0 .. 1.0.
151
+ def l
152
+ @l
153
+ end
154
+ # Sets the percentage of luminosity of the colour.
155
+ def luminosity=(ll)
156
+ @l = Color.normalize(ll / 100.0)
157
+ end
158
+ alias lightness= luminosity= ;
159
+ # Sets the luminosity of the colour in the ragne 0.0 .. 1.0.
160
+ def l=(ll)
161
+ @l = Color.normalize(ll)
162
+ end
163
+
164
+ def to_hsl
165
+ self
166
+ end
167
+
168
+ def inspect
169
+ "HSL [%.2f deg, %.2f%%, %.2f%%]" % [ hue, saturation, luminosity ]
170
+ end
171
+
172
+ # Mix the mask colour (which will be converted to an HSL colour) with the
173
+ # current colour at the stated mix percentage as a decimal value.
174
+ #
175
+ # NOTE:: This differs from Color::RGB#mix_with.
176
+ def mix_with(color, mix_percent = 0.5)
177
+ v = to_a.zip(coerce(color).to_a).map { |(x, y)|
178
+ ((y - x) * mix_percent) + x
179
+ }
180
+ self.class.from_fraction(*v)
181
+ end
182
+
183
+ def to_a
184
+ [ h, s, l ]
185
+ end
186
+
187
+ private
188
+
189
+ # This algorithm calculates based on a mixture of the saturation and
190
+ # luminance, and then takes the RGB values from the hue + 1/3, hue, and
191
+ # hue - 1/3 positions in a circular representation of colour divided into
192
+ # four parts (confusing, I know, but it's the way that it works). See
193
+ # #hue_to_rgb for more information.
194
+ def compute_fvd_rgb
195
+ t1, t2 = fvd_mix_sat_lum
196
+ [ h + (1 / 3.0), h, h - (1 / 3.0) ].map { |v|
197
+ hue_to_rgb(rotate_hue(v), t1, t2)
198
+ }
199
+ end
200
+
201
+ # Mix saturation and luminance for use in hue_to_rgb. The base value is
202
+ # different depending on whether luminance is <= 50% or > 50%.
203
+ def fvd_mix_sat_lum
204
+ t = if Color.near_zero_or_less?(l - 0.5)
205
+ l * (1.0 + s.to_f)
206
+ else
207
+ l + s - (l * s.to_f)
208
+ end
209
+ [ 2.0 * l - t, t ]
210
+ end
211
+
212
+ # In HSL, hues are referenced as degrees in a colour circle. The flow
213
+ # itself is endless; therefore, we can rotate around. The only thing our
214
+ # implementation restricts is that you should not be > 1.0.
215
+ def rotate_hue(h)
216
+ h += 1.0 if Color.near_zero_or_less?(h)
217
+ h -= 1.0 if Color.near_one_or_more?(h)
218
+ h
219
+ end
220
+
221
+ # We calculate the interaction of the saturation/luminance mix (calculated
222
+ # earlier) based on the position of the hue in the circular colour space
223
+ # divided into quadrants. Our hue range is [0, 1), not [0, 360º).
224
+ #
225
+ # - The first quadrant covers the first 60º [0, 60º].
226
+ # - The second quadrant covers the next 120º (60º, 180º].
227
+ # - The third quadrant covers the next 60º (180º, 240º].
228
+ # - The fourth quadrant covers the final 120º (240º, 360º).
229
+ def hue_to_rgb(h, t1, t2)
230
+ if Color.near_zero_or_less?((6.0 * h) - 1.0)
231
+ t1 + ((t2 - t1) * h * 6.0)
232
+ elsif Color.near_zero_or_less?((2.0 * h) - 1.0)
233
+ t2
234
+ elsif Color.near_zero_or_less?((3.0 * h) - 2.0)
235
+ t1 + (t2 - t1) * ((2 / 3.0) - h) * 6.0
236
+ else
237
+ t1
238
+ end
239
+ end
240
+ end
@@ -0,0 +1,260 @@
1
+ require 'color/palette'
2
+
3
+ # A class that can read an Adobe Color palette file (used for Photoshop
4
+ # swatches) and provide a Hash-like interface to the contents. Not all
5
+ # colour formats in ACO files are supported. Based largely off the
6
+ # information found by Larry Tesler[http://www.nomodes.com/aco.html].
7
+ #
8
+ # Not all Adobe Color files have named colours; all named entries are
9
+ # returned as an array.
10
+ #
11
+ # pal = Color::Palette::AdobeColor.from_file(my_aco_palette)
12
+ # pal[0] => Color::RGB<...>
13
+ # pal["white"] => [ Color::RGB<...> ]
14
+ # pal["unknown"] => [ Color::RGB<...>, Color::RGB<...>, ... ]
15
+ #
16
+ # AdobeColor palettes are always indexable by insertion order (an integer
17
+ # key).
18
+ #
19
+ # Version 2 palettes use UTF-16 colour names.
20
+ class Color::Palette::AdobeColor
21
+ include Enumerable
22
+
23
+ class << self
24
+ # Create an AdobeColor palette object from the named file.
25
+ def from_file(filename)
26
+ File.open(filename, "rb") { |io| Color::Palette::AdobeColor.from_io(io) }
27
+ end
28
+
29
+ # Create an AdobeColor palette object from the provided IO.
30
+ def from_io(io)
31
+ Color::Palette::AdobeColor.new(io.read)
32
+ end
33
+ end
34
+
35
+ # Returns statistics about the nature of the colours loaded.
36
+ attr_reader :statistics
37
+ # Contains the "lost" colours in the palette. These colours could not be
38
+ # properly loaded (e.g., L*a*b* is not supported by Color, so it is
39
+ # "lost") or are not understood by the algorithms.
40
+ attr_reader :lost
41
+
42
+ # Use this to convert the unsigned word to the signed word, if necessary.
43
+ UwToSw = proc { |n| (n >= (2 ** 16)) ? n - (2 ** 32) : n } #:nodoc:
44
+
45
+ # Create a new AdobeColor palette from the palette file as a string.
46
+ def initialize(palette)
47
+ @colors = []
48
+ @names = {}
49
+ @statistics = Hash.new(0)
50
+ @lost = []
51
+ @order = []
52
+ @version = nil
53
+
54
+ class << palette
55
+ def readwords(count = 1)
56
+ @offset ||= 0
57
+ raise IndexError if @offset >= self.size
58
+ val = self[@offset, count * 2]
59
+ raise IndexError if val.nil? or val.size < (count * 2)
60
+ val = val.unpack("n" * count)
61
+ @offset += count * 2
62
+ val
63
+ end
64
+
65
+ def readutf16(count = 1)
66
+ @offset ||= 0
67
+ raise IndexError if @offset >= self.size
68
+ val = self[@offset, count * 2]
69
+ raise IndexError if val.nil? or val.size < (count * 2)
70
+ @offset += count * 2
71
+ val
72
+ end
73
+ end
74
+
75
+ @version, count = palette.readwords 2
76
+
77
+ raise "Unknown AdobeColor palette version #@version." unless @version.between?(1, 2)
78
+
79
+ count.times do
80
+ space, w, x, y, z = palette.readwords 5
81
+ name = nil
82
+ if @version == 2
83
+ raise IndexError unless palette.readwords == [ 0 ]
84
+ len = palette.readwords
85
+ name = palette.readutf16(len[0] - 1)
86
+ raise IndexError unless palette.readwords == [ 0 ]
87
+ end
88
+
89
+ color = case space
90
+ when 0 then # RGB
91
+ @statistics[:rgb] += 1
92
+
93
+ Color::RGB.new(w / 256, x / 256, y / 256)
94
+ when 1 then # HS[BV] -- Convert to RGB
95
+ @statistics[:hsb] += 1
96
+
97
+ h = w / 65535.0
98
+ s = x / 65535.0
99
+ v = y / 65535.0
100
+
101
+ if defined?(Color::HSB)
102
+ Color::HSB.from_fraction(h, s, v)
103
+ else
104
+ @statistics[:converted] += 1
105
+ if Color.near_zero_or_less?(s)
106
+ Color::RGB.from_fraction(v, v, v)
107
+ else
108
+ if Color.near_one_or_more?(h)
109
+ vh = 0
110
+ else
111
+ vh = h * 6.0
112
+ end
113
+
114
+ vi = vh.floor
115
+ v1 = v.to_f * (1 - s.to_f)
116
+ v2 = v.to_f * (1 - s.to_f * (vh - vi))
117
+ v3 = v.to_f * (1 - s.to_f * (1 - (vh - vi)))
118
+
119
+ case vi
120
+ when 0 then Color::RGB.from_fraction(v, v3, v1)
121
+ when 1 then Color::RGB.from_fraction(v2, v, v1)
122
+ when 2 then Color::RGB.from_fraction(v1, v, v3)
123
+ when 3 then Color::RGB.from_fraction(v1, v2, v)
124
+ when 4 then Color::RGB.from_fraction(v3, v1, v)
125
+ else Color::RGB.from_fraction(v, v1, v2)
126
+ end
127
+ end
128
+ end
129
+ when 2 then # CMYK
130
+ @statistics[:cmyk] += 1
131
+ Color::CMYK.from_percent(100 - (w / 655.35),
132
+ 100 - (x / 655.35),
133
+ 100 - (y / 655.35),
134
+ 100 - (z / 655.35))
135
+ when 7 then # L*a*b*
136
+ @statistics[:lab] += 1
137
+
138
+ l = [w, 10000].min / 100.0
139
+ a = [[-12800, UwToSw[x]].max, 12700].min / 100.0
140
+ b = [[-12800, UwToSw[x]].max, 12700].min / 100.0
141
+
142
+ if defined? Color::Lab
143
+ Color::Lab.new(l, a, b)
144
+ else
145
+ [ space, w, x, y, z ]
146
+ end
147
+ when 8 then # Grayscale
148
+ @statistics[:gray] += 1
149
+
150
+ g = [w, 10000].min / 100.0
151
+ Color::GrayScale.new(g)
152
+ when 9 then # Wide CMYK
153
+ @statistics[:wcmyk] += 1
154
+
155
+ c = [w, 10000].min / 100.0
156
+ m = [x, 10000].min / 100.0
157
+ y = [y, 10000].min / 100.0
158
+ k = [z, 10000].min / 100.0
159
+ Color::CMYK.from_percent(c, m, y, k)
160
+ else
161
+ @statistics[space] += 1
162
+ [ space, w, x, y, z ]
163
+ end
164
+
165
+ @order << [ color, name ]
166
+
167
+ if color.kind_of? Array
168
+ @lost << color
169
+ else
170
+ @colors << color
171
+
172
+ if name
173
+ @names[name] ||= []
174
+ @names[name] << color
175
+ end
176
+ end
177
+ end
178
+ end
179
+
180
+ # Provides the colour or colours at the provided selectors.
181
+ def values_at(*selectors)
182
+ @colors.values_at(*selectors)
183
+ end
184
+
185
+ # If a Numeric +key+ is provided, the single colour value at that position
186
+ # will be returned. If a String +key+ is provided, the colour set (an
187
+ # array) for that colour name will be returned.
188
+ def [](key)
189
+ if key.kind_of?(Numeric)
190
+ @colors[key]
191
+ else
192
+ @names[key]
193
+ end
194
+ end
195
+
196
+ # Loops through each colour.
197
+ def each
198
+ @colors.each { |el| yield el }
199
+ end
200
+
201
+ # Loops through each named colour set.
202
+ def each_name #:yields color_name, color_set:#
203
+ @names.each { |color_name, color_set| yield color_name, color_set }
204
+ end
205
+
206
+ def size
207
+ @colors.size
208
+ end
209
+
210
+ attr_reader :version
211
+
212
+ def to_aco(version = @version) #:nodoc:
213
+ res = ""
214
+
215
+ res << [ version, @order.size ].pack("nn")
216
+
217
+ @order.each do |cnpair|
218
+ color, name = *cnpair
219
+
220
+ # Note: HSB and CMYK formats are lost by the conversions performed on
221
+ # import. They are turned into RGB and WCMYK, respectively.
222
+
223
+ cstr = case color
224
+ when Array
225
+ color
226
+ when Color::RGB
227
+ r = [(color.red * 256).round, 65535].min
228
+ g = [(color.green * 256).round, 65535].min
229
+ b = [(color.blue * 256).round, 65535].min
230
+ [ 0, r, g, b, 0 ]
231
+ when Color::GrayScale
232
+ g = [(color.gray * 100).round, 10000].min
233
+ [ 8, g, 0, 0, 0 ]
234
+ when Color::CMYK
235
+ c = [(color.cyan * 100).round, 10000].min
236
+ m = [(color.magenta * 100).round, 10000].min
237
+ y = [(color.yellow * 100).round, 10000].min
238
+ k = [(color.black * 100).round, 10000].min
239
+ [ 9, c, m, y, k ]
240
+ end
241
+ cstr = cstr.pack("nnnnn")
242
+
243
+ nstr = ""
244
+
245
+ if version == 2
246
+ if (name.size / 2 * 2) == name.size # only where s[0] == byte!
247
+ nstr << [ 0, (name.size / 2) + 1 ].pack("nn")
248
+ nstr << name
249
+ nstr << [ 0 ].pack("n")
250
+ else
251
+ nstr << [ 0, 1, 0 ].pack("nnn")
252
+ end
253
+ end
254
+
255
+ res << cstr << nstr
256
+ end
257
+
258
+ res
259
+ end
260
+ end