chunky_png 1.0.0.beta2 → 1.0.0.rc1
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/.infinity_test +1 -1
- data/README.rdoc +2 -2
- data/chunky_png.gemspec +4 -4
- data/lib/chunky_png.rb +14 -8
- data/lib/chunky_png/canvas.rb +110 -38
- data/lib/chunky_png/canvas/drawing.rb +175 -34
- data/lib/chunky_png/canvas/masking.rb +91 -0
- data/lib/chunky_png/canvas/operations.rb +141 -112
- data/lib/chunky_png/canvas/png_decoding.rb +13 -13
- data/lib/chunky_png/canvas/resampling.rb +42 -0
- data/lib/chunky_png/color.rb +252 -11
- data/lib/chunky_png/compatibility.rb +5 -5
- data/lib/chunky_png/dimension.rb +106 -0
- data/lib/chunky_png/point.rb +110 -0
- data/lib/chunky_png/vector.rb +92 -0
- data/spec/chunky_png/canvas/drawing_spec.rb +107 -14
- data/spec/chunky_png/canvas/masking_spec.rb +51 -0
- data/spec/chunky_png/canvas/operations_spec.rb +142 -75
- data/spec/chunky_png/canvas/resampling_spec.rb +31 -0
- data/spec/chunky_png/canvas/stream_exporting_spec.rb +20 -0
- data/spec/chunky_png/canvas/stream_importing_spec.rb +22 -0
- data/spec/chunky_png/canvas_spec.rb +151 -22
- data/spec/chunky_png/color_spec.rb +53 -0
- data/spec/chunky_png/dimension_spec.rb +43 -0
- data/spec/chunky_png/point_spec.rb +71 -0
- data/spec/chunky_png/vector_spec.rb +58 -0
- data/spec/resources/circles.png +0 -0
- data/spec/resources/clock_nn_xdown_ydown.png +0 -0
- data/spec/resources/clock_nn_xdown_yup.png +0 -0
- data/spec/resources/clock_nn_xup_yup.png +0 -0
- data/spec/resources/lines.png +0 -0
- data/spec/resources/partial_circles.png +0 -0
- data/spec/resources/polygon_filled_horizontal.png +0 -0
- data/spec/resources/polygon_filled_vertical.png +0 -0
- data/spec/resources/polygon_triangle_filled.png +0 -0
- data/spec/resources/polygon_unfilled.png +0 -0
- data/spec/resources/rect.png +0 -0
- metadata +31 -9
- data/spec/resources/clock_flip_horizontally.png +0 -0
- data/spec/resources/clock_flip_vertically.png +0 -0
- data/spec/resources/clock_rotate_180.png +0 -0
- data/spec/resources/clock_rotate_left.png +0 -0
- data/spec/resources/clock_rotate_right.png +0 -0
- data/spec/resources/clock_stubbed.png +0 -0
@@ -0,0 +1,42 @@
|
|
1
|
+
module ChunkyPNG
|
2
|
+
class Canvas
|
3
|
+
|
4
|
+
# The ChunkyPNG::Canvas::Resampling module defines methods to perform image resampling to
|
5
|
+
# a {ChunkyPNG::Canvas}.
|
6
|
+
#
|
7
|
+
# Currently, only the nearest neighbor algorithm is implemented. Bilinear and cubic
|
8
|
+
# algorithms may be added later on.
|
9
|
+
#
|
10
|
+
# @see ChunkyPNG::Canvas
|
11
|
+
module Resampling
|
12
|
+
|
13
|
+
# Resamples the canvas.
|
14
|
+
# @param [Integer] new_width The width of the resamples canvas.
|
15
|
+
# @param [Integer] new_height The height of the resamples canvas.
|
16
|
+
# @param [ChunkyPNG::Canvas] A new canvas instance with the resamples pixels.
|
17
|
+
def resample_nearest_neighbor(new_width, new_height)
|
18
|
+
|
19
|
+
resampled_image = self.class.new(new_width.to_i, new_height.to_i)
|
20
|
+
|
21
|
+
width_ratio = width.to_f / new_width.to_f
|
22
|
+
height_ratio = height.to_f / new_height.to_f
|
23
|
+
|
24
|
+
for y in 1..new_height do
|
25
|
+
source_y = (y - 0.5) * height_ratio + 0.5
|
26
|
+
input_y = source_y.to_i
|
27
|
+
|
28
|
+
for x in 1..new_width do
|
29
|
+
source_x = (x - 0.5) * width_ratio + 0.5
|
30
|
+
input_x = source_x.to_i
|
31
|
+
|
32
|
+
resampled_image.set_pixel(x - 1, y - 1, get_pixel([input_x - 1, 0].max, [input_y - 1, 0].max))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
return resampled_image
|
37
|
+
end
|
38
|
+
|
39
|
+
alias_method :resample, :resample_nearest_neighbor
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/chunky_png/color.rb
CHANGED
@@ -1,4 +1,48 @@
|
|
1
1
|
module ChunkyPNG
|
2
|
+
|
3
|
+
# Factory method to return a color value, based on the arguments given.
|
4
|
+
#
|
5
|
+
# - When given 1 argument, it can either be a color integer, which is returned as is,
|
6
|
+
# or it can be a HTML named color or a color in hex notation.
|
7
|
+
# - When given 2 arguments, the 1st argument is parsed as color value and the second
|
8
|
+
# argument is used as opacity value (range: 0-255)
|
9
|
+
#
|
10
|
+
# @overload Color(r, g, b, a)
|
11
|
+
# @param (see ChunkyPNG::Color.rgba)
|
12
|
+
# @return [Integer] The rgba color value.
|
13
|
+
#
|
14
|
+
# @overload Color(r, g, b)
|
15
|
+
# @param (see ChunkyPNG::Color.rgb)
|
16
|
+
# @return [Integer] The rgb color value.
|
17
|
+
#
|
18
|
+
# @overload Color(hex_value, opacity = nil)
|
19
|
+
# @param (see ChunkyPNG::Color.from_hex)
|
20
|
+
# @return [Integer] The hex color value, with the opacity applied if one was given.
|
21
|
+
#
|
22
|
+
# @overload Color(color_name, opacity = nil)
|
23
|
+
# @param (see ChunkyPNG::Color.html_color)
|
24
|
+
# @return [Integer] The hex color value, with the opacity applied if one was given.
|
25
|
+
#
|
26
|
+
# @overload Color(color_value, opacity = nil)
|
27
|
+
# @param [Integer, :to_i] The color value.
|
28
|
+
# @return [Integer] The color value, with the opacity applied if one was given.
|
29
|
+
#
|
30
|
+
# @raise [ChunkyPNG::ExpectationFailed] if the arguments weren't understood as a color.
|
31
|
+
def self.Color(*args)
|
32
|
+
case args.length
|
33
|
+
when 4; ChunkyPNG::Color.rgba(*args)
|
34
|
+
when 3; ChunkyPNG::Color.rgb(*args)
|
35
|
+
when 2; (ChunkyPNG::Color(args[0]) & 0xffffff00) | args[1].to_i
|
36
|
+
when 1
|
37
|
+
case source = args.first.to_s
|
38
|
+
when Integer, /^\d+$/; source.to_i
|
39
|
+
when ChunkyPNG::Color::HEX_COLOR_REGEXP; ChunkyPNG::Color.from_hex(source)
|
40
|
+
when ChunkyPNG::Color::HTML_COLOR_REGEXP; ChunkyPNG::Color.html_color(source)
|
41
|
+
else raise ChunkyPNG::ExpectationFailed; "Don't know how to create a color from #{source.inspect}!"
|
42
|
+
end
|
43
|
+
else raise ChunkyPNG::ExpectationFailed; "Don't know how to create a color from #{args.inspect}!"
|
44
|
+
end
|
45
|
+
end
|
2
46
|
|
3
47
|
# The Color module defines methods for handling colors. Within the ChunkyPNG
|
4
48
|
# library, the concepts of pixels and colors are both used, and they are
|
@@ -16,32 +60,48 @@ module ChunkyPNG
|
|
16
60
|
module Color
|
17
61
|
extend self
|
18
62
|
|
19
|
-
# The maximum value of each color component.
|
63
|
+
# @return [Integer] The maximum value of each color component.
|
20
64
|
MAX = 0xff
|
21
|
-
|
65
|
+
|
66
|
+
# @return [Regexp] The regexp to parse hex color values.
|
67
|
+
HEX_COLOR_REGEXP = /^(?:#|0x)?([0-9a-f]{6})([0-9a-f]{2})?$/i
|
68
|
+
|
69
|
+
# @return [Regexp] The regexp to parse named color values.
|
70
|
+
HTML_COLOR_REGEXP = /^([a-z][a-z_ ]+[a-z])(?:\ ?\@\ ?(1\.0|0\.\d+))?$/i
|
71
|
+
|
22
72
|
####################################################################
|
23
73
|
# CONSTRUCTING COLOR VALUES
|
24
74
|
####################################################################
|
25
75
|
|
26
76
|
# Creates a new color using an r, g, b triple and an alpha value.
|
77
|
+
# @param [Integer] r The r-component (0-255)
|
78
|
+
# @param [Integer] g The r-component (0-255)
|
79
|
+
# @param [Integer] b The r-component (0-255)
|
80
|
+
# @param [Integer] a The opacity (0-255)
|
27
81
|
# @return [Integer] The newly constructed color value.
|
28
82
|
def rgba(r, g, b, a)
|
29
83
|
r << 24 | g << 16 | b << 8 | a
|
30
84
|
end
|
31
85
|
|
32
86
|
# Creates a new color using an r, g, b triple.
|
87
|
+
# @param [Integer] r The r-component (0-255)
|
88
|
+
# @param [Integer] g The r-component (0-255)
|
89
|
+
# @param [Integer] b The r-component (0-255)
|
33
90
|
# @return [Integer] The newly constructed color value.
|
34
91
|
def rgb(r, g, b)
|
35
92
|
r << 24 | g << 16 | b << 8 | 0xff
|
36
93
|
end
|
37
94
|
|
38
95
|
# Creates a new color using a grayscale teint.
|
96
|
+
# @param [Integer] teint The grayscale teint (0-255), will be used as r, g, and b value.
|
39
97
|
# @return [ChunkyPNG::Color] The newly constructed color value.
|
40
98
|
def grayscale(teint)
|
41
99
|
teint << 24 | teint << 16 | teint << 8 | 0xff
|
42
100
|
end
|
43
101
|
|
44
102
|
# Creates a new color using a grayscale teint and alpha value.
|
103
|
+
# @param [Integer] teint The grayscale teint (0-255), will be used as r, g, and b value.
|
104
|
+
# @param [Integer] a The opacity (0-255)
|
45
105
|
# @return [Integer] The newly constructed color value.
|
46
106
|
def grayscale_alpha(teint, a)
|
47
107
|
teint << 24 | teint << 16 | teint << 8 | a
|
@@ -77,12 +137,17 @@ module ChunkyPNG
|
|
77
137
|
# Color strings may include the prefix "0x" or "#".
|
78
138
|
#
|
79
139
|
# @param [String] str The color in hex notation. @return [Integer] The
|
80
|
-
#
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
140
|
+
# converted color value.
|
141
|
+
# @param [Integer] opacity The opacity value for the color. Overrides any
|
142
|
+
# opacity value given in the hex value if given.
|
143
|
+
# @return [Integer] The color value.
|
144
|
+
def from_hex(hex_value, opacity = nil)
|
145
|
+
if HEX_COLOR_REGEXP =~ hex_value
|
146
|
+
base_color = $1.hex << 8
|
147
|
+
opacity ||= $2 ? $2.hex : 0xff
|
148
|
+
base_color | opacity
|
149
|
+
else
|
150
|
+
raise ChunkyPNG::ExpectationFailed, "Not a valid hex color notation: #{hex_value.inspect}!"
|
86
151
|
end
|
87
152
|
end
|
88
153
|
|
@@ -373,13 +438,189 @@ module ChunkyPNG
|
|
373
438
|
# COLOR CONSTANTS
|
374
439
|
####################################################################
|
375
440
|
|
376
|
-
#
|
441
|
+
# @return [Hash<Symbol, Integer>] All the prefined color names in HTML.
|
442
|
+
PREDEFINED_COLORS = {
|
443
|
+
:aliceblue => 0xf0f8ff00,
|
444
|
+
:antiquewhite => 0xfaebd700,
|
445
|
+
:aqua => 0x00ffff00,
|
446
|
+
:aquamarine => 0x7fffd400,
|
447
|
+
:azure => 0xf0ffff00,
|
448
|
+
:beige => 0xf5f5dc00,
|
449
|
+
:bisque => 0xffe4c400,
|
450
|
+
:black => 0x00000000,
|
451
|
+
:blanchedalmond => 0xffebcd00,
|
452
|
+
:blue => 0x0000ff00,
|
453
|
+
:blueviolet => 0x8a2be200,
|
454
|
+
:brown => 0xa52a2a00,
|
455
|
+
:burlywood => 0xdeb88700,
|
456
|
+
:cadetblue => 0x5f9ea000,
|
457
|
+
:chartreuse => 0x7fff0000,
|
458
|
+
:chocolate => 0xd2691e00,
|
459
|
+
:coral => 0xff7f5000,
|
460
|
+
:cornflowerblue => 0x6495ed00,
|
461
|
+
:cornsilk => 0xfff8dc00,
|
462
|
+
:crimson => 0xdc143c00,
|
463
|
+
:cyan => 0x00ffff00,
|
464
|
+
:darkblue => 0x00008b00,
|
465
|
+
:darkcyan => 0x008b8b00,
|
466
|
+
:darkgoldenrod => 0xb8860b00,
|
467
|
+
:darkgray => 0xa9a9a900,
|
468
|
+
:darkgrey => 0xa9a9a900,
|
469
|
+
:darkgreen => 0x00640000,
|
470
|
+
:darkkhaki => 0xbdb76b00,
|
471
|
+
:darkmagenta => 0x8b008b00,
|
472
|
+
:darkolivegreen => 0x556b2f00,
|
473
|
+
:darkorange => 0xff8c0000,
|
474
|
+
:darkorchid => 0x9932cc00,
|
475
|
+
:darkred => 0x8b000000,
|
476
|
+
:darksalmon => 0xe9967a00,
|
477
|
+
:darkseagreen => 0x8fbc8f00,
|
478
|
+
:darkslateblue => 0x483d8b00,
|
479
|
+
:darkslategray => 0x2f4f4f00,
|
480
|
+
:darkslategrey => 0x2f4f4f00,
|
481
|
+
:darkturquoise => 0x00ced100,
|
482
|
+
:darkviolet => 0x9400d300,
|
483
|
+
:deeppink => 0xff149300,
|
484
|
+
:deepskyblue => 0x00bfff00,
|
485
|
+
:dimgray => 0x69696900,
|
486
|
+
:dimgrey => 0x69696900,
|
487
|
+
:dodgerblue => 0x1e90ff00,
|
488
|
+
:firebrick => 0xb2222200,
|
489
|
+
:floralwhite => 0xfffaf000,
|
490
|
+
:forestgreen => 0x228b2200,
|
491
|
+
:fuchsia => 0xff00ff00,
|
492
|
+
:gainsboro => 0xdcdcdc00,
|
493
|
+
:ghostwhite => 0xf8f8ff00,
|
494
|
+
:gold => 0xffd70000,
|
495
|
+
:goldenrod => 0xdaa52000,
|
496
|
+
:gray => 0x80808000,
|
497
|
+
:grey => 0x80808000,
|
498
|
+
:green => 0x00800000,
|
499
|
+
:greenyellow => 0xadff2f00,
|
500
|
+
:honeydew => 0xf0fff000,
|
501
|
+
:hotpink => 0xff69b400,
|
502
|
+
:indianred => 0xcd5c5c00,
|
503
|
+
:indigo => 0x4b008200,
|
504
|
+
:ivory => 0xfffff000,
|
505
|
+
:khaki => 0xf0e68c00,
|
506
|
+
:lavender => 0xe6e6fa00,
|
507
|
+
:lavenderblush => 0xfff0f500,
|
508
|
+
:lawngreen => 0x7cfc0000,
|
509
|
+
:lemonchiffon => 0xfffacd00,
|
510
|
+
:lightblue => 0xadd8e600,
|
511
|
+
:lightcoral => 0xf0808000,
|
512
|
+
:lightcyan => 0xe0ffff00,
|
513
|
+
:lightgoldenrodyellow => 0xfafad200,
|
514
|
+
:lightgray => 0xd3d3d300,
|
515
|
+
:lightgrey => 0xd3d3d300,
|
516
|
+
:lightgreen => 0x90ee9000,
|
517
|
+
:lightpink => 0xffb6c100,
|
518
|
+
:lightsalmon => 0xffa07a00,
|
519
|
+
:lightseagreen => 0x20b2aa00,
|
520
|
+
:lightskyblue => 0x87cefa00,
|
521
|
+
:lightslategray => 0x77889900,
|
522
|
+
:lightslategrey => 0x77889900,
|
523
|
+
:lightsteelblue => 0xb0c4de00,
|
524
|
+
:lightyellow => 0xffffe000,
|
525
|
+
:lime => 0x00ff0000,
|
526
|
+
:limegreen => 0x32cd3200,
|
527
|
+
:linen => 0xfaf0e600,
|
528
|
+
:magenta => 0xff00ff00,
|
529
|
+
:maroon => 0x80000000,
|
530
|
+
:mediumaquamarine => 0x66cdaa00,
|
531
|
+
:mediumblue => 0x0000cd00,
|
532
|
+
:mediumorchid => 0xba55d300,
|
533
|
+
:mediumpurple => 0x9370d800,
|
534
|
+
:mediumseagreen => 0x3cb37100,
|
535
|
+
:mediumslateblue => 0x7b68ee00,
|
536
|
+
:mediumspringgreen => 0x00fa9a00,
|
537
|
+
:mediumturquoise => 0x48d1cc00,
|
538
|
+
:mediumvioletred => 0xc7158500,
|
539
|
+
:midnightblue => 0x19197000,
|
540
|
+
:mintcream => 0xf5fffa00,
|
541
|
+
:mistyrose => 0xffe4e100,
|
542
|
+
:moccasin => 0xffe4b500,
|
543
|
+
:navajowhite => 0xffdead00,
|
544
|
+
:navy => 0x00008000,
|
545
|
+
:oldlace => 0xfdf5e600,
|
546
|
+
:olive => 0x80800000,
|
547
|
+
:olivedrab => 0x6b8e2300,
|
548
|
+
:orange => 0xffa50000,
|
549
|
+
:orangered => 0xff450000,
|
550
|
+
:orchid => 0xda70d600,
|
551
|
+
:palegoldenrod => 0xeee8aa00,
|
552
|
+
:palegreen => 0x98fb9800,
|
553
|
+
:paleturquoise => 0xafeeee00,
|
554
|
+
:palevioletred => 0xd8709300,
|
555
|
+
:papayawhip => 0xffefd500,
|
556
|
+
:peachpuff => 0xffdab900,
|
557
|
+
:peru => 0xcd853f00,
|
558
|
+
:pink => 0xffc0cb00,
|
559
|
+
:plum => 0xdda0dd00,
|
560
|
+
:powderblue => 0xb0e0e600,
|
561
|
+
:purple => 0x80008000,
|
562
|
+
:red => 0xff000000,
|
563
|
+
:rosybrown => 0xbc8f8f00,
|
564
|
+
:royalblue => 0x4169e100,
|
565
|
+
:saddlebrown => 0x8b451300,
|
566
|
+
:salmon => 0xfa807200,
|
567
|
+
:sandybrown => 0xf4a46000,
|
568
|
+
:seagreen => 0x2e8b5700,
|
569
|
+
:seashell => 0xfff5ee00,
|
570
|
+
:sienna => 0xa0522d00,
|
571
|
+
:silver => 0xc0c0c000,
|
572
|
+
:skyblue => 0x87ceeb00,
|
573
|
+
:slateblue => 0x6a5acd00,
|
574
|
+
:slategray => 0x70809000,
|
575
|
+
:slategrey => 0x70809000,
|
576
|
+
:snow => 0xfffafa00,
|
577
|
+
:springgreen => 0x00ff7f00,
|
578
|
+
:steelblue => 0x4682b400,
|
579
|
+
:tan => 0xd2b48c00,
|
580
|
+
:teal => 0x00808000,
|
581
|
+
:thistle => 0xd8bfd800,
|
582
|
+
:tomato => 0xff634700,
|
583
|
+
:turquoise => 0x40e0d000,
|
584
|
+
:violet => 0xee82ee00,
|
585
|
+
:wheat => 0xf5deb300,
|
586
|
+
:white => 0xffffff00,
|
587
|
+
:whitesmoke => 0xf5f5f500,
|
588
|
+
:yellow => 0xffff0000,
|
589
|
+
:yellowgreen => 0x9acd3200
|
590
|
+
}
|
591
|
+
|
592
|
+
# Gets a color value based on a HTML color name.
|
593
|
+
#
|
594
|
+
# The color name is flexible. E.g. <tt>'yellowgreen'</tt>, <tt>'Yellow green'</tt>,
|
595
|
+
# <tt>'YellowGreen'</tt>, <tt>'YELLOW_GREEN'</tt> and <tt>:yellow_green</tt> will
|
596
|
+
# all return the same color value.
|
597
|
+
#
|
598
|
+
# You can include a opacity level in the color name (e.g. <tt>'red @ 0.5'</tt>) or give
|
599
|
+
# an explit opacity value as second argument. If no opacity value is given, the color
|
600
|
+
# will be fully opaque.
|
601
|
+
#
|
602
|
+
# @param [Symbol, String] color_name The color name. It may include an opacity specifier
|
603
|
+
# like <tt>@ 0.8</tt> to set the color's opacity.
|
604
|
+
# @param [Integer] opacity The opacity value for the color between 0 and 255. Overrides
|
605
|
+
# any opacity value given in the color name.
|
606
|
+
# @return [Integer] The color value.
|
607
|
+
# @raise [ChunkyPNG::Exception] If the color name was not recognized.
|
608
|
+
def html_color(color_name, opacity = nil)
|
609
|
+
if color_name.to_s =~ HTML_COLOR_REGEXP
|
610
|
+
opacity ||= $2 ? ($2.to_f * 255.0).round : 0xff
|
611
|
+
base_color_name = $1.gsub(/[^a-z]+/i, '').downcase.to_sym
|
612
|
+
return PREDEFINED_COLORS[base_color_name] | opacity if PREDEFINED_COLORS.has_key?(base_color_name)
|
613
|
+
end
|
614
|
+
raise ChunkyPNG::Exception, "Unknown color name #{color_name}!"
|
615
|
+
end
|
616
|
+
|
617
|
+
# @return [Integer] Black pixel/color
|
377
618
|
BLACK = rgb( 0, 0, 0)
|
378
619
|
|
379
|
-
# White pixel/color
|
620
|
+
# @return [Integer] White pixel/color
|
380
621
|
WHITE = rgb(255, 255, 255)
|
381
622
|
|
382
|
-
# Fully transparent pixel/color
|
623
|
+
# @return [Integer] Fully transparent pixel/color
|
383
624
|
TRANSPARENT = rgba(0, 0, 0, 0)
|
384
625
|
|
385
626
|
####################################################################
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# Define the byte-operators on a string if they're not defined (Ruby 1.8)
|
1
2
|
|
2
3
|
class String
|
3
4
|
alias_method :getbyte, :[] unless method_defined?(:getbyte)
|
@@ -5,11 +6,10 @@ class String
|
|
5
6
|
alias_method :bytesize, :size unless method_defined?(:bytesize)
|
6
7
|
end
|
7
8
|
|
8
|
-
|
9
|
-
unless method_defined?(:
|
10
|
-
def
|
11
|
-
|
12
|
-
return self
|
9
|
+
module Enumerable
|
10
|
+
unless method_defined?(:minmax)
|
11
|
+
def minmax
|
12
|
+
[min, max]
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module ChunkyPNG
|
2
|
+
|
3
|
+
# Creates a {ChunkyPNG::Dimension} instance using arguments that can be interpreted
|
4
|
+
# as width and height.
|
5
|
+
#
|
6
|
+
# @overload Dimension(width, height)
|
7
|
+
# @param [Integer] width The width-component of the dimension.
|
8
|
+
# @param [Integer] height The height-component of the dimension.
|
9
|
+
# @return [ChunkyPNG::Dimension] The instantiated dimension.
|
10
|
+
#
|
11
|
+
# @overload Dimension(string)
|
12
|
+
# @param [String] string A string from which a width and height value can be parsed, e.g.
|
13
|
+
# <tt>'10x20'</tt> or <tt>'[10, 20]'</tt>.
|
14
|
+
# @return [ChunkyPNG::Dimension] The instantiated dimension.
|
15
|
+
#
|
16
|
+
# @overload Dimension(ary)
|
17
|
+
# @param [Array] ary An array with the desired width as first element and the
|
18
|
+
# desired height as second element, e.g. <tt>[10, 20]</tt>.
|
19
|
+
# @return [ChunkyPNG::Dimension] The instantiated dimension.
|
20
|
+
#
|
21
|
+
# @overload Dimension(hash)
|
22
|
+
# @param [Hash] hash An hash with a <tt>'height'</tt> or <tt>:height</tt> key for the
|
23
|
+
# desired height and with a <tt>'width'</tt> or <tt>:width</tt> key for the desired
|
24
|
+
# width.
|
25
|
+
# @return [ChunkyPNG::Dimension] The instantiated dimension.
|
26
|
+
#
|
27
|
+
# @see ChunkyPNG::Dimension
|
28
|
+
def self.Dimension(*args)
|
29
|
+
|
30
|
+
case args.length
|
31
|
+
when 2; ChunkyPNG::Dimension.new(*args)
|
32
|
+
when 1; case source = args.first
|
33
|
+
when ChunkyPNG::Dimension; source
|
34
|
+
when ChunkyPNG::Point; ChunkyPNG::Dimension.new(source.x, source.y)
|
35
|
+
when Array; ChunkyPNG::Dimension.new(source[0], source[1])
|
36
|
+
when Hash; ChunkyPNG::Dimension.new(source[:width] || source['width'], source[:height] || source['height'])
|
37
|
+
when /^[\(\[\{]?(\d+)\s*[x,]?\s*(\d+)[\)\]\}]?$/; ChunkyPNG::Dimension.new($1, $2)
|
38
|
+
else
|
39
|
+
if source.respond_to?(:width) && source.respond_to?(:height)
|
40
|
+
ChunkyPNG::Dimension.new(source.width, source.height)
|
41
|
+
else
|
42
|
+
raise ChunkyPNG::ExpectationFailed, "Don't know how to construct a point from #{source.inspect}!"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
else raise ChunkyPNG::ExpectationFailed, "Don't know how to construct a point from #{args.inspect}!"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Class that represents the dimension of something, e.g. a {ChunkyPNG::Canvas}.
|
50
|
+
#
|
51
|
+
# This class contains some methods to simplify performing dimension related checks.
|
52
|
+
class Dimension
|
53
|
+
|
54
|
+
# @return [Integer] The width-compontent of this dimension.
|
55
|
+
attr_accessor :width
|
56
|
+
|
57
|
+
# @return [Integer] The height-compontent of this dimension.
|
58
|
+
attr_accessor :height
|
59
|
+
|
60
|
+
# Initializes a new dimension instance.
|
61
|
+
# @param [Integer] width The width-compontent of the new dimension.
|
62
|
+
# @param [Integer] height The height-compontent of the new dimension.
|
63
|
+
def initialize(width, height)
|
64
|
+
@width, @height = width.to_i, height.to_i
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns the area of this dimension.
|
68
|
+
# @return [Integer] The area in number of pixels.
|
69
|
+
def area
|
70
|
+
width * height
|
71
|
+
end
|
72
|
+
|
73
|
+
# Checks whether a point is within bounds of this dimension.
|
74
|
+
# @param [ChunkyPNG::Point, ...] A point-like to bounds-check.
|
75
|
+
# @return [true, false] True iff the the x and y coordinate fall in this dimension.
|
76
|
+
def include?(*point_like)
|
77
|
+
point = ChunkyPNG::Point(*point_like)
|
78
|
+
point.x >= 0 && point.x < width && point.y >= 0 && point.y < height
|
79
|
+
end
|
80
|
+
|
81
|
+
# Checks whether 2 dimensions are identical.
|
82
|
+
# @param [ChunkyPNG::Dimension] The dimension to compare with.
|
83
|
+
# @return [true, false] <tt>true</tt> iff width and height match.
|
84
|
+
def eql?(other)
|
85
|
+
other.width == width && other.height == height
|
86
|
+
end
|
87
|
+
|
88
|
+
alias_method :==, :eql?
|
89
|
+
|
90
|
+
# Compares the size of 2 dimensions.
|
91
|
+
# @param [ChunkyPNG::Dimension] The dimension to compare with.
|
92
|
+
# @return [-1, 0, 1] -1 if the other dimension has a larger area, 1 of this
|
93
|
+
# dimension is larger, 0 if both are identical in size.
|
94
|
+
def <=>(other)
|
95
|
+
other.area <=> area
|
96
|
+
end
|
97
|
+
|
98
|
+
# Casts this dimension into an array.
|
99
|
+
# @return [Array<Integer>] <tt>[width, height]</tt> for this dimension.
|
100
|
+
def to_a
|
101
|
+
[width, height]
|
102
|
+
end
|
103
|
+
|
104
|
+
alias_method :to_ary, :to_a
|
105
|
+
end
|
106
|
+
end
|