rubyquartz 0.1.2

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.
Files changed (96) hide show
  1. data/COPYRIGHT +24 -0
  2. data/History.txt +9 -0
  3. data/Manifest.txt +95 -0
  4. data/README.txt +71 -0
  5. data/Rakefile +51 -0
  6. data/ext/ExportedSymbols.txt +1 -0
  7. data/ext/bitmap.c +129 -0
  8. data/ext/bitmap.h +38 -0
  9. data/ext/bitmap_context.c +67 -0
  10. data/ext/bitmap_context.h +31 -0
  11. data/ext/color.c +145 -0
  12. data/ext/color.h +34 -0
  13. data/ext/colorspace.c +94 -0
  14. data/ext/colorspace.h +33 -0
  15. data/ext/context.c +393 -0
  16. data/ext/context.h +33 -0
  17. data/ext/extconf.rb +48 -0
  18. data/ext/font.c +148 -0
  19. data/ext/font.h +32 -0
  20. data/ext/function.c +124 -0
  21. data/ext/function.h +32 -0
  22. data/ext/image.c +140 -0
  23. data/ext/image.h +31 -0
  24. data/ext/image_source.c +143 -0
  25. data/ext/image_source.h +31 -0
  26. data/ext/pdf_document.c +91 -0
  27. data/ext/pdf_document.h +31 -0
  28. data/ext/pdf_page.c +79 -0
  29. data/ext/pdf_page.h +31 -0
  30. data/ext/point.c +42 -0
  31. data/ext/point.h +32 -0
  32. data/ext/rect.c +45 -0
  33. data/ext/rect.h +32 -0
  34. data/ext/rubyquartz.c +80 -0
  35. data/ext/rubyquartz.h +29 -0
  36. data/ext/rubyquartz_prefix.h +45 -0
  37. data/ext/shading.c +68 -0
  38. data/ext/shading.h +32 -0
  39. data/ext/size.c +42 -0
  40. data/ext/size.h +32 -0
  41. data/ext/text.c +258 -0
  42. data/ext/text.h +39 -0
  43. data/ext/utilities.c +181 -0
  44. data/ext/utilities.h +43 -0
  45. data/lib/rubyquartz.rb +59 -0
  46. data/lib/rubyquartz/bitmap.rb +62 -0
  47. data/lib/rubyquartz/bitmap_context.rb +50 -0
  48. data/lib/rubyquartz/color.rb +68 -0
  49. data/lib/rubyquartz/colorspace.rb +42 -0
  50. data/lib/rubyquartz/context.rb +116 -0
  51. data/lib/rubyquartz/font.rb +48 -0
  52. data/lib/rubyquartz/function.rb +57 -0
  53. data/lib/rubyquartz/image.rb +48 -0
  54. data/lib/rubyquartz/image_source.rb +50 -0
  55. data/lib/rubyquartz/pdf_document.rb +47 -0
  56. data/lib/rubyquartz/pdf_page.rb +54 -0
  57. data/lib/rubyquartz/point.rb +63 -0
  58. data/lib/rubyquartz/rect.rb +127 -0
  59. data/lib/rubyquartz/shading.rb +48 -0
  60. data/lib/rubyquartz/size.rb +39 -0
  61. data/lib/rubyquartz/text.rb +50 -0
  62. data/test/images/TestContext.test_begin_path.png +0 -0
  63. data/test/images/TestContext.test_draw_image.png +0 -0
  64. data/test/images/TestContext.test_draw_path.png +0 -0
  65. data/test/images/TestContext.test_draw_pdf.png +0 -0
  66. data/test/images/TestContext.test_draw_shading_axial.png +0 -0
  67. data/test/images/TestContext.test_draw_text.png +0 -0
  68. data/test/images/TestContext.test_draw_text_baseline_aligned.png +0 -0
  69. data/test/images/TestContext.test_draw_text_flipped.png +0 -0
  70. data/test/images/TestContext.test_draw_text_flipped_non_zero_point.png +0 -0
  71. data/test/images/TestContext.test_draw_text_non_zero_point.png +0 -0
  72. data/test/images/TestContext.test_fill.png +0 -0
  73. data/test/images/TestContext.test_gsave.png +0 -0
  74. data/test/images/TestContext.test_gsave_block.png +0 -0
  75. data/test/images/TestContext.test_line_width.png +0 -0
  76. data/test/images/TestContext.test_lineto.png +0 -0
  77. data/test/images/TestContext.test_rotate.png +0 -0
  78. data/test/images/TestContext.test_rounded_rect.png +0 -0
  79. data/test/images/TestContext.test_scale.png +0 -0
  80. data/test/images/TestContext.test_set_line_dash.png +0 -0
  81. data/test/images/TestContext.test_shadow.png +0 -0
  82. data/test/images/TestContext.test_stroke_rect.png +0 -0
  83. data/test/images/TestContext.test_text_bounds.png +0 -0
  84. data/test/images/TestContext.test_translate.png +0 -0
  85. data/test/inputs/circle.pdf +0 -0
  86. data/test/inputs/wash.png +0 -0
  87. data/test/rubyquartz_test.rb +51 -0
  88. data/test/tc_bitmap_context.rb +43 -0
  89. data/test/tc_color.rb +43 -0
  90. data/test/tc_context.rb +315 -0
  91. data/test/tc_font.rb +54 -0
  92. data/test/tc_image_source.rb +69 -0
  93. data/test/tc_pdf_document.rb +63 -0
  94. data/test/tc_pdf_page.rb +53 -0
  95. data/test/tc_text.rb +39 -0
  96. metadata +156 -0
@@ -0,0 +1,48 @@
1
+ # Copyright (c) 2006, The Omni Group, Inc. All rights reserved.
2
+ #
3
+ # OPEN PERMISSION TO USE AND REPRODUCE OMNI SOURCE CODE SOFTWARE
4
+ #
5
+ # Omni Source Code software is available from The Omni Group on their web
6
+ # site at www.omnigroup.com.
7
+ #
8
+ # Permission is hereby granted, free of charge, to any person obtaining a
9
+ # copy of this software and associated documentation files (the "Software"),
10
+ # to deal in the Software without restriction, including without limitation
11
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
12
+ # and/or sell copies of the Software, and to permit persons to whom the
13
+ # Software is furnished to do so, subject to the following conditions:
14
+ #
15
+ # Any original copyright notices and this permission notice shall be included
16
+ # in all copies or substantial portions of the Software.
17
+ #
18
+ # THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
+ # DEALINGS IN THE SOFTWARE.
25
+
26
+ module Quartz
27
+ class Shading
28
+ attr_reader :function
29
+
30
+ def initialize(function, options={})
31
+ type = options[:type] || :axial
32
+ case type
33
+ when :axial
34
+ @function = function # Hold onto this so it doesn't get GC'd
35
+
36
+ colorspace = options[:colorspace] || ColorSpace.new(:name => ColorSpace::GENERIC_RGB)
37
+ start_point = options[:start] || Point.new(0, 0)
38
+ end_point = options[:end] || Point.new(1, 0)
39
+ extend_start = options[:extend_start] || false
40
+ extend_end = options[:extend_end] || false
41
+ _initialize_axial(colorspace, start_point.x, start_point.y, end_point.x, end_point.y,
42
+ function, extend_start, extend_end)
43
+ else
44
+ raise "Unknown shading type '#{type}'"
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,39 @@
1
+ # Copyright (c) 2006, The Omni Group, Inc. All rights reserved.
2
+ #
3
+ # OPEN PERMISSION TO USE AND REPRODUCE OMNI SOURCE CODE SOFTWARE
4
+ #
5
+ # Omni Source Code software is available from The Omni Group on their web
6
+ # site at www.omnigroup.com.
7
+ #
8
+ # Permission is hereby granted, free of charge, to any person obtaining a
9
+ # copy of this software and associated documentation files (the "Software"),
10
+ # to deal in the Software without restriction, including without limitation
11
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
12
+ # and/or sell copies of the Software, and to permit persons to whom the
13
+ # Software is furnished to do so, subject to the following conditions:
14
+ #
15
+ # Any original copyright notices and this permission notice shall be included
16
+ # in all copies or substantial portions of the Software.
17
+ #
18
+ # THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
+ # DEALINGS IN THE SOFTWARE.
25
+
26
+ module Quartz
27
+ class Size
28
+ attr_accessor :width, :height
29
+
30
+ def initialize(width, height)
31
+ @width = width
32
+ @height = height
33
+ end
34
+
35
+ def to_s
36
+ "(#{@width}, #{@height})"
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,50 @@
1
+ # Copyright (c) 2006, The Omni Group, Inc. All rights reserved.
2
+ #
3
+ # OPEN PERMISSION TO USE AND REPRODUCE OMNI SOURCE CODE SOFTWARE
4
+ #
5
+ # Omni Source Code software is available from The Omni Group on their web
6
+ # site at www.omnigroup.com.
7
+ #
8
+ # Permission is hereby granted, free of charge, to any person obtaining a
9
+ # copy of this software and associated documentation files (the "Software"),
10
+ # to deal in the Software without restriction, including without limitation
11
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
12
+ # and/or sell copies of the Software, and to permit persons to whom the
13
+ # Software is furnished to do so, subject to the following conditions:
14
+ #
15
+ # Any original copyright notices and this permission notice shall be included
16
+ # in all copies or substantial portions of the Software.
17
+ #
18
+ # THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
+ # DEALINGS IN THE SOFTWARE.
25
+
26
+ module Quartz
27
+ class Text
28
+
29
+ # NSTextAlignment
30
+ @@AlignmentNameToNumber = {
31
+ :left => 0,
32
+ :right => 1,
33
+ :center => 2,
34
+ :justified => 3,
35
+ :natural => 4,
36
+ }
37
+
38
+ # This is really basic, not exposing the full power of the Cocoa text system
39
+ def initialize(string, options={})
40
+ font = options[:font]
41
+ color = options[:color]
42
+ alignment = options[:align] || :left
43
+ _initialize(string, font, color, @@AlignmentNameToNumber[alignment])
44
+ end
45
+
46
+ def size
47
+ Size.new(width_used, height_used)
48
+ end
49
+ end
50
+ end
Binary file
Binary file
@@ -0,0 +1,51 @@
1
+ # Copyright (c) 2006, The Omni Group, Inc. All rights reserved.
2
+ #
3
+ # OPEN PERMISSION TO USE AND REPRODUCE OMNI SOURCE CODE SOFTWARE
4
+ #
5
+ # Omni Source Code software is available from The Omni Group on their web
6
+ # site at www.omnigroup.com.
7
+ #
8
+ # Permission is hereby granted, free of charge, to any person obtaining a
9
+ # copy of this software and associated documentation files (the "Software"),
10
+ # to deal in the Software without restriction, including without limitation
11
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
12
+ # and/or sell copies of the Software, and to permit persons to whom the
13
+ # Software is furnished to do so, subject to the following conditions:
14
+ #
15
+ # Any original copyright notices and this permission notice shall be included
16
+ # in all copies or substantial portions of the Software.
17
+ #
18
+ # THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
+ # DEALINGS IN THE SOFTWARE.
25
+
26
+ require 'test/unit'
27
+ require 'rubyquartz'
28
+
29
+ module TestQuartz
30
+ class TestCase < Test::Unit::TestCase
31
+ def default_test
32
+ super if not TestCase === self
33
+ end
34
+
35
+ # For now we just to byte-to-byte comparisons of the images
36
+ def assert_image_equal(ctx)
37
+ image_name = "#{self.class.name}.#{method_name}.png"
38
+ current_img = ctx.copy_image
39
+ current_image_path = "/tmp/#{image_name}"
40
+ current_img.write_png_to_file(current_image_path)
41
+ expected_image_path = "test/images/#{image_name}"
42
+
43
+ output = `cmp '#{current_image_path}' '#{expected_image_path}' 2>&1`
44
+ if $? != 0
45
+ add_failure("image differs for #{method_name}; output #{output}")
46
+ else
47
+ File.unlink(current_image_path)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,43 @@
1
+ # Copyright (c) 2006, The Omni Group, Inc. All rights reserved.
2
+ #
3
+ # OPEN PERMISSION TO USE AND REPRODUCE OMNI SOURCE CODE SOFTWARE
4
+ #
5
+ # Omni Source Code software is available from The Omni Group on their web
6
+ # site at www.omnigroup.com.
7
+ #
8
+ # Permission is hereby granted, free of charge, to any person obtaining a
9
+ # copy of this software and associated documentation files (the "Software"),
10
+ # to deal in the Software without restriction, including without limitation
11
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
12
+ # and/or sell copies of the Software, and to permit persons to whom the
13
+ # Software is furnished to do so, subject to the following conditions:
14
+ #
15
+ # Any original copyright notices and this permission notice shall be included
16
+ # in all copies or substantial portions of the Software.
17
+ #
18
+ # THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
+ # DEALINGS IN THE SOFTWARE.
25
+
26
+ require 'rubyquartz_test'
27
+ include Quartz
28
+
29
+ class TestBitmapContext < TestQuartz::TestCase
30
+ def setup
31
+ super
32
+ @rgb = ColorSpace.new(:name => ColorSpace::GENERIC_RGB)
33
+ end
34
+ def teardown
35
+ @rgb = nil
36
+ super
37
+ end
38
+
39
+ def test_init
40
+ ctx = BitmapContext.new(100, 100, :colorspace => @rgb, :alpha => Bitmap::ALPHA_PREMULTIPLIED_FIRST)
41
+ assert_not_nil(ctx)
42
+ end
43
+ end
data/test/tc_color.rb ADDED
@@ -0,0 +1,43 @@
1
+ # Copyright (c) 2006, The Omni Group, Inc. All rights reserved.
2
+ #
3
+ # OPEN PERMISSION TO USE AND REPRODUCE OMNI SOURCE CODE SOFTWARE
4
+ #
5
+ # Omni Source Code software is available from The Omni Group on their web
6
+ # site at www.omnigroup.com.
7
+ #
8
+ # Permission is hereby granted, free of charge, to any person obtaining a
9
+ # copy of this software and associated documentation files (the "Software"),
10
+ # to deal in the Software without restriction, including without limitation
11
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
12
+ # and/or sell copies of the Software, and to permit persons to whom the
13
+ # Software is furnished to do so, subject to the following conditions:
14
+ #
15
+ # Any original copyright notices and this permission notice shall be included
16
+ # in all copies or substantial portions of the Software.
17
+ #
18
+ # THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
+ # DEALINGS IN THE SOFTWARE.
25
+
26
+ require 'rubyquartz_test'
27
+ include Quartz
28
+
29
+ class TestColor < TestQuartz::TestCase
30
+ def setup
31
+ super
32
+ @rgb = ColorSpace.new(:name => ColorSpace::GENERIC_RGB)
33
+ end
34
+ def teardown
35
+ @rgb = nil
36
+ super
37
+ end
38
+
39
+ def test_init_red
40
+ red = Color.new(@rgb, 1, 0, 0, 1)
41
+ assert_raise(TypeError) {Quartz::Context.new}
42
+ end
43
+ end
@@ -0,0 +1,315 @@
1
+ # Copyright (c) 2006, The Omni Group, Inc. All rights reserved.
2
+ #
3
+ # OPEN PERMISSION TO USE AND REPRODUCE OMNI SOURCE CODE SOFTWARE
4
+ #
5
+ # Omni Source Code software is available from The Omni Group on their web
6
+ # site at www.omnigroup.com.
7
+ #
8
+ # Permission is hereby granted, free of charge, to any person obtaining a
9
+ # copy of this software and associated documentation files (the "Software"),
10
+ # to deal in the Software without restriction, including without limitation
11
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
12
+ # and/or sell copies of the Software, and to permit persons to whom the
13
+ # Software is furnished to do so, subject to the following conditions:
14
+ #
15
+ # Any original copyright notices and this permission notice shall be included
16
+ # in all copies or substantial portions of the Software.
17
+ #
18
+ # THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
+ # DEALINGS IN THE SOFTWARE.
25
+
26
+ require 'rubyquartz_test'
27
+ include Quartz
28
+
29
+ class TestContext < TestQuartz::TestCase
30
+ # For the tests that produce actual output, we use an instance of a subclass (since Context is abstract)
31
+ # TODO: Should really run all these tests once for bitmap and once for pdf?
32
+
33
+ def setup
34
+ super
35
+ @rgb = ColorSpace.new(:name => ColorSpace::GENERIC_RGB)
36
+ @ctx = BitmapContext.new(100, 100, :colorspace => @rgb, :alpha => Bitmap::ALPHA_PREMULTIPLIED_FIRST)
37
+ end
38
+ def teardown
39
+ @ctx = nil
40
+ @rgb = nil
41
+ super
42
+ end
43
+
44
+ def test_init
45
+ assert_raise(TypeError) {Context.new}
46
+ end
47
+
48
+
49
+ def test_fill
50
+ @ctx.fill_color = Color.new(@rgb, 1, 1, 1, 1)
51
+ @ctx.fill_rect(0, 0, 100, 100)
52
+ assert_image_equal(@ctx)
53
+ end
54
+
55
+ def test_gsave
56
+ @ctx.fill_color = Color.new(@rgb, 1, 0, 0, 0.5)
57
+ @ctx.gsave
58
+ @ctx.fill_color = Color.new(@rgb, 1, 1, 1, 1)
59
+ @ctx.fill_rect(0, 0, 100, 100)
60
+ @ctx.grestore
61
+ @ctx.fill_rect(10, 10, 80, 80)
62
+
63
+ assert_image_equal(@ctx)
64
+ end
65
+
66
+ def test_gsave_block
67
+ @ctx.fill_color = Color.new(@rgb, 1, 0, 0, 0.5)
68
+ @ctx.gsave {|c|
69
+ c.fill_color = Color.new(@rgb, 1, 1, 1, 1)
70
+ c.fill_rect(0, 0, 100, 100)
71
+ }
72
+ @ctx.fill_rect(10, 10, 80, 80)
73
+ assert_image_equal(@ctx)
74
+ end
75
+
76
+ def test_scale
77
+ @ctx.fill_color = Color.new(@rgb, 1, 0, 0, 1)
78
+ @ctx.fill_rect(10, 10, 10, 10)
79
+ @ctx.scale(2, 4)
80
+ @ctx.fill_color = Color.new(@rgb, 0, 1, 0, 1)
81
+ @ctx.fill_rect(10, 10, 10, 10)
82
+ assert_image_equal(@ctx)
83
+ end
84
+
85
+ def test_translate
86
+ @ctx.fill_color = Color.new(@rgb, 1, 0, 0, 1)
87
+ @ctx.fill_rect(10, 10, 10, 10)
88
+ @ctx.translate(0, 10)
89
+ @ctx.fill_color = Color.new(@rgb, 0, 1, 0, 1)
90
+ @ctx.fill_rect(10, 10, 10, 10)
91
+ @ctx.translate(10, 0)
92
+ @ctx.fill_color = Color.new(@rgb, 0, 0, 1, 1)
93
+ @ctx.fill_rect(10, 10, 10, 10)
94
+ assert_image_equal(@ctx)
95
+ end
96
+
97
+ def test_rotate
98
+ @ctx.stroke_color = Color.new(@rgb, 1, 0, 0, 1)
99
+ @ctx.moveto(0, 0)
100
+ @ctx.lineto(10, 0)
101
+ @ctx.stroke
102
+ @ctx.rotate(45)
103
+ @ctx.stroke_color = Color.new(@rgb, 0, 1, 0, 1)
104
+ @ctx.moveto(0, 0)
105
+ @ctx.lineto(10, 0)
106
+ @ctx.stroke
107
+ assert_image_equal(@ctx)
108
+ end
109
+
110
+ def test_lineto
111
+ @ctx.stroke_color = Color.new(@rgb, 1, 0, 0, 1)
112
+ @ctx.moveto(10, 10)
113
+ @ctx.lineto(10, 20)
114
+ @ctx.stroke
115
+ assert_image_equal(@ctx)
116
+ end
117
+
118
+ def test_line_width
119
+ @ctx.stroke_color = Color.new(@rgb, 1, 0, 0, 1)
120
+ @ctx.moveto(10, 10)
121
+ @ctx.lineto(10, 20)
122
+ @ctx.line_width = 4
123
+ @ctx.stroke
124
+ assert_image_equal(@ctx)
125
+ end
126
+
127
+ def test_set_line_dash
128
+ @ctx.stroke_color = Color.new(@rgb, 1, 0, 0, 1)
129
+ @ctx.moveto(10, 10)
130
+ @ctx.lineto(90, 90)
131
+ @ctx.line_width = 10
132
+ @ctx.set_line_dash(0, [2, 4, 1, 4])
133
+ @ctx.stroke
134
+ assert_image_equal(@ctx)
135
+ end
136
+
137
+ def test_begin_path
138
+ @ctx.moveto(10, 10)
139
+ @ctx.lineto(10, 20)
140
+ @ctx.begin_path
141
+ @ctx.moveto(20, 20)
142
+ @ctx.lineto(30, 20)
143
+ @ctx.stroke
144
+ assert_image_equal(@ctx)
145
+ end
146
+
147
+ def test_stroke_rect
148
+ @ctx.stroke_color = Color.new(@rgb, 0, 1, 0, 1)
149
+ @ctx.stroke_rect(10.5, 10.5, 80, 80)
150
+ assert_image_equal(@ctx)
151
+ end
152
+
153
+ def test_draw_text
154
+ @ctx.fill_color = Color.new(@rgb, 1, 1, 1, 1)
155
+ @ctx.fill_rect(0, 0, 100, 100)
156
+
157
+ red = Color.new(@rgb, 1, 0, 0, 1)
158
+ font = Font.new(:name => "Times-Roman", :size => 16)
159
+
160
+ text = Text.new("howdy!", :color => red, :font => font)
161
+ @ctx.draw_text(text)
162
+ assert_image_equal(@ctx)
163
+ end
164
+
165
+ def test_draw_text_non_zero_point
166
+ @ctx.fill_color = Color.new(@rgb, 1, 1, 1, 1)
167
+ @ctx.fill_rect(0, 0, 100, 100)
168
+
169
+ red = Color.new(@rgb, 1, 0, 0, 1)
170
+ font = Font.new(:name => "Times-Roman", :size => 16)
171
+
172
+ text = Text.new("howdy!", :color => red, :font => font)
173
+ @ctx.draw_text(text, :x => 10, :y => 10)
174
+ assert_image_equal(@ctx)
175
+ end
176
+
177
+ def test_draw_text_flipped
178
+ @ctx.fill_color = Color.new(@rgb, 1, 1, 1, 1)
179
+ @ctx.fill_rect(0, 0, 100, 100)
180
+
181
+ red = Color.new(@rgb, 1, 0, 0, 1)
182
+ font = Font.new(:name => "Times-Roman", :size => 16)
183
+
184
+ text = Text.new("howdy!", :color => red, :font => font)
185
+ @ctx.draw_text(text, :flip => true)
186
+ assert_image_equal(@ctx)
187
+ end
188
+
189
+ def test_draw_text_flipped_non_zero_point
190
+ @ctx.fill_color = Color.new(@rgb, 1, 1, 1, 1)
191
+ @ctx.fill_rect(0, 0, 100, 100)
192
+
193
+ red = Color.new(@rgb, 1, 0, 0, 1)
194
+ font = Font.new(:name => "Times-Roman", :size => 16)
195
+
196
+ text = Text.new("howdy!", :color => red, :font => font)
197
+ @ctx.draw_text(text, :x => 10, :y => 10, :flip => true)
198
+ assert_image_equal(@ctx)
199
+ end
200
+
201
+ def test_draw_text_baseline_aligned
202
+ @ctx.fill_color = Color.new(@rgb, 1, 1, 1, 1)
203
+ @ctx.fill_rect(0, 0, 100, 100)
204
+
205
+ font = Font.new(:name => "Times-Roman", :size => 32)
206
+ text = Text.new("A", :font => font)
207
+ @ctx.draw_text(text, :x => 10, :y => 10, :flip => true)
208
+
209
+ text = Text.new("g", :font => font)
210
+ @ctx.draw_text(text, :x => 32, :y => 10, :flip => true)
211
+
212
+ text = Text.new("Ag", :font => font)
213
+ @ctx.draw_text(text, :x => 55, :y => 10, :flip => true)
214
+
215
+ assert_image_equal(@ctx)
216
+ end
217
+
218
+ def test_text_align
219
+ @ctx.fill_color = Color.new(@rgb, 1, 1, 1, 1)
220
+ @ctx.fill_rect(0, 0, 100, 100)
221
+
222
+ text = Text.new("left", :align => :left)
223
+ @ctx.draw_text(text, :x => 10, :y => 10, :flip => true)
224
+
225
+ text = Text.new("center", :align => :center)
226
+ @ctx.draw_text(text, :x => 10, :y => 30, :flip => true)
227
+
228
+ text = Text.new("right", :align => :right)
229
+ @ctx.draw_text(text, :x => 10, :y => 50, :flip => true)
230
+
231
+ assert_image_equal(@ctx)
232
+ end
233
+
234
+ def test_text_bounds
235
+ @ctx.fill_color = Color.new(@rgb, 1, 1, 1, 1)
236
+ @ctx.fill_rect(0, 0, 100, 100)
237
+ @ctx.stroke_color = Color.new(@rgb, 0, 1, 0, 1)
238
+
239
+ font = Font.new(:name => "Times-Roman", :size => 32)
240
+
241
+ text = Text.new("A", :font => font)
242
+ @ctx.draw_text(text, :x => 10, :y => 10, :flip => true)
243
+ @ctx.stroke_rect(10.5, 10.5, text.width_used, text.height_used)
244
+
245
+ text = Text.new("x", :font => font)
246
+ @ctx.draw_text(text, :x => 40, :y => 10, :flip => true)
247
+ @ctx.stroke_rect(40.5, 10.5, text.width_used, text.height_used)
248
+
249
+ text = Text.new("y", :font => font)
250
+ @ctx.draw_text(text, :x => 60, :y => 10, :flip => true)
251
+ @ctx.stroke_rect(60.5, 10.5, text.width_used, text.height_used)
252
+
253
+ assert_image_equal(@ctx)
254
+ end
255
+
256
+ def test_rounded_rect
257
+ @ctx.fill_color = Color.new(@rgb, 1, 1, 1, 1)
258
+ @ctx.fill_rect(0, 0, 100, 100)
259
+ @ctx.stroke_color = Color.new(@rgb, 0, 1, 0, 1)
260
+ @ctx.add_rounded_rect(Rect.new(Point.new(10.5, 10.5), Size.new(80, 80)), 5)
261
+ @ctx.stroke
262
+ assert_image_equal(@ctx)
263
+ end
264
+
265
+ def test_shadow
266
+ @ctx.fill_color = Color.new(@rgb, 1, 1, 1, 1)
267
+ @ctx.fill_rect(0, 0, 100, 100)
268
+ @ctx.stroke_color = Color.new(@rgb, 0, 1, 0, 1)
269
+ @ctx.shadow(3, 3, 2, Color.new(@rgb, 0, 0, 0, 0.5))
270
+ @ctx.moveto(10.5, 10.5)
271
+ @ctx.lineto(10.5, 20.5)
272
+ @ctx.stroke
273
+ assert_image_equal(@ctx)
274
+ end
275
+
276
+ def test_draw_path
277
+ @ctx.fill_color = Color.new(@rgb, 1, 0, 0, 1)
278
+ @ctx.stroke_color = Color.new(@rgb, 0, 0, 1, 1)
279
+ @ctx.add_rect(10.5, 10.5, 80, 80)
280
+ @ctx.draw_path(:fill_stroke)
281
+ assert_image_equal(@ctx)
282
+ end
283
+
284
+ def test_draw_image
285
+ src = ImageSource.new(:path => "test/inputs/wash.png")
286
+ img = src[0]
287
+ @ctx.draw_image(0, 0, 50, 50, img)
288
+ @ctx.draw_image(0, 50, 25, 50, img)
289
+ @ctx.draw_image(50, 0, 50, 25, img)
290
+ @ctx.draw_image(50, 50, 25, 25, img)
291
+ assert_image_equal(@ctx)
292
+ end
293
+
294
+ def test_draw_shading_axial
295
+ function = Function.new([0..1], [0..1, 0..1, 0..1, 0..1]) # Map a linear value to RGBA
296
+ function.instance_eval {
297
+ def evaluate(input, output)
298
+ output[0] = 1.0; output[1] = 0.0; output[2] = 0.0; output[3] = input[0];
299
+ end
300
+ }
301
+
302
+ shading = Shading.new(function, :type => :axial, :start => Point.new(0, 0), :end => Point.new(0, 100))
303
+ @ctx.add_rect(10.5, 10.5, 80, 80)
304
+ @ctx.clip
305
+ @ctx.draw_shading(shading)
306
+ assert_image_equal(@ctx)
307
+ end
308
+
309
+ def test_draw_pdf
310
+ doc = PDFDocument.new(:path => "test/inputs/circle.pdf")
311
+ @ctx.draw_pdf_page(doc[0])
312
+ assert_image_equal(@ctx)
313
+ end
314
+
315
+ end