Class: Quilt::Identicon

Inherits:
Object
  • Object
show all
Defined in:
lib/quilt.rb

Constant Summary collapse

PATCHES =
[
 [0, 4, 24, 20, 0],
 [0, 4, 20, 0],
 [2, 24, 20, 2],
 [0, 2, 22, 20, 0],
 [2, 14, 22, 10, 2],
 [0, 14, 24, 22, 0],
 [2, 24, 22, 13, 11, 22, 20, 2],
 [0, 14, 22, 0],
 [6, 8, 18, 16, 6],
 [4, 20, 10, 12, 2, 4],
 [0, 2, 12, 10, 0],
 [10, 14, 22, 10],
 [20, 12, 24, 20],
 [10, 2, 12, 10],
 [0, 2, 10, 0],
 [],
]
CENTER_PATCHES =
[0, 4, 8, 15]
PATCH_SIZE =
5
@@image_lib =
ImageRmagick
@@salt =
''

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(str = '', opt = {}) ⇒ Identicon

Returns a new instance of Identicon.



199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/quilt.rb', line 199

def initialize str = '', opt = {}
  case opt[:type]
  when :code
    @code = str.to_i
  when :ip
    @code = Identicon.ip2code str
  else
    @code = Identicon.calc_code str.to_s
  end
  @decode = decode @code

  if opt[:size]
    @scale = opt[:size].to_f / (PATCH_SIZE * 3)
  else
    @scale = opt[:scale] || 1
  end

  if opt[:format].to_s == 'svg'
    @image_lib = ImageSVG
  else
    @image_lib = @@image_lib
  end

  @transparent = !!opt[:transparent] &&
    [ImageRmagick, ImageSVG].include?(@image_lib)
  @patch_width = PATCH_SIZE * @scale
  @image = @image_lib.new(@patch_width * 3, @patch_width * 3,
    :transparent => @transparent)
  @back_color = @image.color 255, 255, 255
  @fore_color = @image.color @decode[:red], @decode[:green], @decode[:blue]
  render
end

Instance Attribute Details

#codeObject (readonly)

Returns the value of attribute code.



197
198
199
# File 'lib/quilt.rb', line 197

def code
  @code
end

Class Method Details

.calc_code(str) ⇒ Object



326
327
328
# File 'lib/quilt.rb', line 326

def self.calc_code str
  extract_code Identicon.digest(str)
end

.digest(str) ⇒ Object



335
336
337
# File 'lib/quilt.rb', line 335

def self.digest str
  Digest::SHA1.digest(str + @@salt)
end

.extract_code(list) ⇒ Object



339
340
341
342
343
344
345
346
347
348
349
350
# File 'lib/quilt.rb', line 339

def self.extract_code list
  if list.respond_to? :getbyte
    tmp = [list.getbyte(0) << 24, list.getbyte(1) << 16,
           list.getbyte(2) << 8, list.getbyte(3)]
  else
    tmp = [list[0].to_i << 24, list[1].to_i << 16,
           list[2].to_i << 8, list[3].to_i]
  end
  tmp.inject(0) do |r, i|
    r | ((i[31] == 1) ? -(i & 0x7fffffff) : i)
  end
end

.image_libObject



356
357
358
# File 'lib/quilt.rb', line 356

def self.image_lib
  @@image_lib
end

.image_lib=(image_lib) ⇒ Object



352
353
354
# File 'lib/quilt.rb', line 352

def self.image_lib= image_lib
  @@image_lib = image_lib
end

.ip2code(ip) ⇒ Object



330
331
332
333
# File 'lib/quilt.rb', line 330

def self.ip2code ip
  code_ip = extract_code(ip.split('.'))
  extract_code Identicon.digest(code_ip.to_s)
end

.saltObject



364
365
366
# File 'lib/quilt.rb', line 364

def self.salt
  @@salt
end

.salt=(salt) ⇒ Object



360
361
362
# File 'lib/quilt.rb', line 360

def self.salt= salt
  @@salt = salt
end

Instance Method Details

#decode(code) ⇒ Object



232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/quilt.rb', line 232

def decode code
  {
    :center_type   => (code & 0x3),
    :center_invert => (((code >> 2) & 0x01) != 0),
    :corner_type   => ((code >> 3) & 0x0f),
    :corner_invert => (((code >> 7) & 0x01) != 0),
    :corner_turn   => ((code >> 8) & 0x03),
    :side_type     => ((code >> 10) & 0x0f),
    :side_invert   => (((code >> 14) & 0x01) != 0),
    :side_turn     => ((code >> 15) & 0x03),
    :red   => (((code >> 16) & 0x01f) << 3),
    :green => (((code >> 21) & 0x01f) << 3),
    :blue  => (((code >> 27) & 0x01f) << 3),
  }
end

#draw(opt = {}) ⇒ Object



269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
# File 'lib/quilt.rb', line 269

def draw opt = {}
  x = opt[:x] * @patch_width
  y = opt[:y] * @patch_width
  patch = opt[:patch] % PATCHES.size
  turn = opt[:turn] % 4

  if opt[:invert]
    fore, back = @back_color, @fore_color
  else
    fore, back = @fore_color, @back_color
  end

  offset = (@image_lib == Quilt::ImageSVG) ? 0 : 1

  if !(@transparent && back == @back_color)
    @image.fill_rect(x, y, x + @patch_width - offset,
      y + @patch_width - offset, back)
  end

  points = []
  PATCHES[patch].each do |pt|
    dx = pt % PATCH_SIZE
    dy = pt / PATCH_SIZE
    len = @patch_width - offset
    px = dx.to_f / (PATCH_SIZE - 1) * len
    py = dy.to_f / (PATCH_SIZE - 1) * len

    case turn
    when 1
      px, py = len - py, px
    when 2
      px, py = len - px, len - py
    when 3
      px, py = py, len - px
    end
    points << [x + px, y + py]
  end

  if @transparent
    if fore == @back_color
      @image.polygon_clip points
    else
      @image.polygon points, fore
    end
  else
    @image.polygon points, fore
  end
end

#draw_patches(list, patch, turn, invert) ⇒ Object



261
262
263
264
265
266
267
# File 'lib/quilt.rb', line 261

def draw_patches list, patch, turn, invert
  list.each do |i|
    draw(:x => i[0], :y => i[1], :patch => patch,
         :turn => turn, :invert => invert)
    turn += 1
  end
end

#renderObject



248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/quilt.rb', line 248

def render
  center = [[1, 1]]
  side   = [[1, 0], [2, 1], [1, 2], [0, 1]]
  corner = [[0, 0], [2, 0], [2, 2], [0, 2]]

  draw_patches(center, CENTER_PATCHES[@decode[:center_type]],
               0, @decode[:center_invert])
  draw_patches(side, @decode[:side_type],
               @decode[:side_turn], @decode[:side_invert])
  draw_patches(corner, @decode[:corner_type],
               @decode[:corner_turn], @decode[:corner_invert])
end

#to_blobObject



322
323
324
# File 'lib/quilt.rb', line 322

def to_blob
  @image.to_blob
end

#write(path = "#{@code}.png") ⇒ Object



318
319
320
# File 'lib/quilt.rb', line 318

def write path = "#{@code}.png"
  @image.write path
end