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.
- data/COPYRIGHT +24 -0
- data/History.txt +9 -0
- data/Manifest.txt +95 -0
- data/README.txt +71 -0
- data/Rakefile +51 -0
- data/ext/ExportedSymbols.txt +1 -0
- data/ext/bitmap.c +129 -0
- data/ext/bitmap.h +38 -0
- data/ext/bitmap_context.c +67 -0
- data/ext/bitmap_context.h +31 -0
- data/ext/color.c +145 -0
- data/ext/color.h +34 -0
- data/ext/colorspace.c +94 -0
- data/ext/colorspace.h +33 -0
- data/ext/context.c +393 -0
- data/ext/context.h +33 -0
- data/ext/extconf.rb +48 -0
- data/ext/font.c +148 -0
- data/ext/font.h +32 -0
- data/ext/function.c +124 -0
- data/ext/function.h +32 -0
- data/ext/image.c +140 -0
- data/ext/image.h +31 -0
- data/ext/image_source.c +143 -0
- data/ext/image_source.h +31 -0
- data/ext/pdf_document.c +91 -0
- data/ext/pdf_document.h +31 -0
- data/ext/pdf_page.c +79 -0
- data/ext/pdf_page.h +31 -0
- data/ext/point.c +42 -0
- data/ext/point.h +32 -0
- data/ext/rect.c +45 -0
- data/ext/rect.h +32 -0
- data/ext/rubyquartz.c +80 -0
- data/ext/rubyquartz.h +29 -0
- data/ext/rubyquartz_prefix.h +45 -0
- data/ext/shading.c +68 -0
- data/ext/shading.h +32 -0
- data/ext/size.c +42 -0
- data/ext/size.h +32 -0
- data/ext/text.c +258 -0
- data/ext/text.h +39 -0
- data/ext/utilities.c +181 -0
- data/ext/utilities.h +43 -0
- data/lib/rubyquartz.rb +59 -0
- data/lib/rubyquartz/bitmap.rb +62 -0
- data/lib/rubyquartz/bitmap_context.rb +50 -0
- data/lib/rubyquartz/color.rb +68 -0
- data/lib/rubyquartz/colorspace.rb +42 -0
- data/lib/rubyquartz/context.rb +116 -0
- data/lib/rubyquartz/font.rb +48 -0
- data/lib/rubyquartz/function.rb +57 -0
- data/lib/rubyquartz/image.rb +48 -0
- data/lib/rubyquartz/image_source.rb +50 -0
- data/lib/rubyquartz/pdf_document.rb +47 -0
- data/lib/rubyquartz/pdf_page.rb +54 -0
- data/lib/rubyquartz/point.rb +63 -0
- data/lib/rubyquartz/rect.rb +127 -0
- data/lib/rubyquartz/shading.rb +48 -0
- data/lib/rubyquartz/size.rb +39 -0
- data/lib/rubyquartz/text.rb +50 -0
- data/test/images/TestContext.test_begin_path.png +0 -0
- data/test/images/TestContext.test_draw_image.png +0 -0
- data/test/images/TestContext.test_draw_path.png +0 -0
- data/test/images/TestContext.test_draw_pdf.png +0 -0
- data/test/images/TestContext.test_draw_shading_axial.png +0 -0
- data/test/images/TestContext.test_draw_text.png +0 -0
- data/test/images/TestContext.test_draw_text_baseline_aligned.png +0 -0
- data/test/images/TestContext.test_draw_text_flipped.png +0 -0
- data/test/images/TestContext.test_draw_text_flipped_non_zero_point.png +0 -0
- data/test/images/TestContext.test_draw_text_non_zero_point.png +0 -0
- data/test/images/TestContext.test_fill.png +0 -0
- data/test/images/TestContext.test_gsave.png +0 -0
- data/test/images/TestContext.test_gsave_block.png +0 -0
- data/test/images/TestContext.test_line_width.png +0 -0
- data/test/images/TestContext.test_lineto.png +0 -0
- data/test/images/TestContext.test_rotate.png +0 -0
- data/test/images/TestContext.test_rounded_rect.png +0 -0
- data/test/images/TestContext.test_scale.png +0 -0
- data/test/images/TestContext.test_set_line_dash.png +0 -0
- data/test/images/TestContext.test_shadow.png +0 -0
- data/test/images/TestContext.test_stroke_rect.png +0 -0
- data/test/images/TestContext.test_text_bounds.png +0 -0
- data/test/images/TestContext.test_translate.png +0 -0
- data/test/inputs/circle.pdf +0 -0
- data/test/inputs/wash.png +0 -0
- data/test/rubyquartz_test.rb +51 -0
- data/test/tc_bitmap_context.rb +43 -0
- data/test/tc_color.rb +43 -0
- data/test/tc_context.rb +315 -0
- data/test/tc_font.rb +54 -0
- data/test/tc_image_source.rb +69 -0
- data/test/tc_pdf_document.rb +63 -0
- data/test/tc_pdf_page.rb +53 -0
- data/test/tc_text.rb +39 -0
- 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
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
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
|
data/test/tc_context.rb
ADDED
|
@@ -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
|