cairo 1.4.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of cairo might be problematic. Click here for more details.
- data/AUTHORS +4 -0
- data/COPYING +59 -0
- data/ChangeLog +792 -0
- data/GPL +340 -0
- data/NEWS +29 -0
- data/README +32 -0
- data/Rakefile +103 -0
- data/extconf.rb +115 -0
- data/pkg-config.rb +126 -0
- data/samples/pac.rb +106 -0
- data/samples/pac2.rb +177 -0
- data/samples/png.rb +43 -0
- data/samples/scalable.rb +58 -0
- data/samples/text-on-path.rb +61 -0
- data/samples/text2.rb +127 -0
- data/src/cairo.def +58 -0
- data/src/lib/cairo.rb +77 -0
- data/src/lib/cairo/context.rb +13 -0
- data/src/lib/cairo/context/circle.rb +9 -0
- data/src/lib/cairo/context/path.rb +127 -0
- data/src/lib/cairo/context/quad.rb +19 -0
- data/src/lib/cairo/context/rectangle.rb +33 -0
- data/src/rb_cairo.c +90 -0
- data/src/rb_cairo.h +180 -0
- data/src/rb_cairo_constants.c +342 -0
- data/src/rb_cairo_context.c +1403 -0
- data/src/rb_cairo_exception.c +192 -0
- data/src/rb_cairo_font_extents.c +124 -0
- data/src/rb_cairo_font_face.c +63 -0
- data/src/rb_cairo_font_options.c +195 -0
- data/src/rb_cairo_glyph.c +158 -0
- data/src/rb_cairo_matrix.c +257 -0
- data/src/rb_cairo_path.c +88 -0
- data/src/rb_cairo_pattern.c +480 -0
- data/src/rb_cairo_private.c +51 -0
- data/src/rb_cairo_private.h +23 -0
- data/src/rb_cairo_scaled_font.c +184 -0
- data/src/rb_cairo_surface.c +837 -0
- data/src/rb_cairo_text_extents.c +137 -0
- metadata +89 -0
data/samples/png.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
top = File.expand_path(File.join(File.dirname(__FILE__), ".."))
|
4
|
+
src = File.join(top, "src")
|
5
|
+
$LOAD_PATH.unshift src
|
6
|
+
$LOAD_PATH.unshift File.join(src, "lib")
|
7
|
+
|
8
|
+
require 'cairo'
|
9
|
+
|
10
|
+
width = 200
|
11
|
+
height = 200
|
12
|
+
|
13
|
+
surface = Cairo::ImageSurface.new(width, height)
|
14
|
+
cr = Cairo::Context.new(surface)
|
15
|
+
|
16
|
+
# fill background with white
|
17
|
+
cr.set_source_rgba(1.0, 1.0, 1.0, 0.8)
|
18
|
+
cr.paint
|
19
|
+
|
20
|
+
# create shape
|
21
|
+
cr.move_to(50, 50)
|
22
|
+
cr.curve_to(100, 25, 100, 75, 150, 50)
|
23
|
+
cr.line_to(150, 150)
|
24
|
+
cr.line_to(50, 150)
|
25
|
+
cr.close_path
|
26
|
+
|
27
|
+
cr.set_source_rgb(0.0, 0.0, 0.0)
|
28
|
+
cr.fill_preserve
|
29
|
+
cr.set_source_rgb(1.0, 0.0, 0.0)
|
30
|
+
cr.set_line_join(Cairo::LINE_JOIN_MITER)
|
31
|
+
cr.set_line_width(4)
|
32
|
+
cr.stroke
|
33
|
+
|
34
|
+
cr.target.write_to_png("test.png")
|
35
|
+
|
36
|
+
data = cr.target.data
|
37
|
+
stride = cr.target.stride
|
38
|
+
|
39
|
+
cr.target.finish
|
40
|
+
|
41
|
+
surface = Cairo::ImageSurface.new(data, Cairo::FORMAT_ARGB32,
|
42
|
+
width, height, stride)
|
43
|
+
surface.write_to_png("test-renew.png")
|
data/samples/scalable.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
top = File.expand_path(File.join(File.dirname(__FILE__), ".."))
|
4
|
+
src = File.join(top, "src")
|
5
|
+
$LOAD_PATH.unshift src
|
6
|
+
$LOAD_PATH.unshift File.join(src, "lib")
|
7
|
+
|
8
|
+
require 'cairo'
|
9
|
+
require 'stringio'
|
10
|
+
|
11
|
+
def render(output, surface_class)
|
12
|
+
surface = surface_class.new(output, 200, 200)
|
13
|
+
cr = Cairo::Context.new(surface)
|
14
|
+
|
15
|
+
# fill background with white
|
16
|
+
cr.set_source_rgba(1.0, 1.0, 1.0, 0.8)
|
17
|
+
cr.paint
|
18
|
+
|
19
|
+
# create shape
|
20
|
+
cr.move_to(50, 50)
|
21
|
+
cr.curve_to(100, 25, 100, 75, 150, 50)
|
22
|
+
cr.line_to(150, 150)
|
23
|
+
cr.line_to(50, 150)
|
24
|
+
cr.close_path
|
25
|
+
|
26
|
+
cr.set_source_rgb(0.0, 0.0, 0.0)
|
27
|
+
cr.fill_preserve
|
28
|
+
cr.set_source_rgb(1.0, 0.0, 0.0)
|
29
|
+
cr.set_line_join(Cairo::LINE_JOIN_MITER)
|
30
|
+
cr.set_line_width(4)
|
31
|
+
cr.stroke
|
32
|
+
|
33
|
+
cr.show_page
|
34
|
+
|
35
|
+
cr.target.finish
|
36
|
+
|
37
|
+
cr
|
38
|
+
end
|
39
|
+
|
40
|
+
def output(surface_class_name, suffix)
|
41
|
+
if Cairo.const_defined?(surface_class_name)
|
42
|
+
surface_class = Cairo.const_get(surface_class_name)
|
43
|
+
render("test.#{suffix}", surface_class)
|
44
|
+
|
45
|
+
output = StringIO.new
|
46
|
+
render(output, surface_class)
|
47
|
+
output.rewind
|
48
|
+
File.open("test2.#{suffix}", "wb") do |f|
|
49
|
+
f.print(output.read)
|
50
|
+
end
|
51
|
+
else
|
52
|
+
puts("#{surface_class_name} isn't supported.")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
output("PSSurface", "ps")
|
57
|
+
output("PDFSurface", "pdf")
|
58
|
+
output("SVGSurface", "svg")
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
top = File.expand_path(File.join(File.dirname(__FILE__), ".."))
|
4
|
+
src = File.join(top, "src")
|
5
|
+
$LOAD_PATH.unshift src
|
6
|
+
$LOAD_PATH.unshift File.join(src, "lib")
|
7
|
+
|
8
|
+
require 'cairo'
|
9
|
+
require 'pango'
|
10
|
+
|
11
|
+
def render_background(cr)
|
12
|
+
cr.set_source_rgba(1.0, 1.0, 1.0)
|
13
|
+
cr.paint
|
14
|
+
end
|
15
|
+
|
16
|
+
def make_layout(cr, text)
|
17
|
+
layout = cr.create_pango_layout
|
18
|
+
layout.text = text
|
19
|
+
layout.font_description = Pango::FontDescription.new("Serif 36")
|
20
|
+
cr.update_pango_layout(layout)
|
21
|
+
layout
|
22
|
+
end
|
23
|
+
|
24
|
+
def render(surface)
|
25
|
+
text = "It was a dream... Oh Just a dream..."
|
26
|
+
|
27
|
+
cr = Cairo::Context.new(surface)
|
28
|
+
|
29
|
+
render_background(cr)
|
30
|
+
|
31
|
+
cr.set_source_rgba(1, 0, 0, 1)
|
32
|
+
cr.move_to(25, 350)
|
33
|
+
cr.line_to(150, 375)
|
34
|
+
cr.curve_to(275, 400, 450, 350, 450, 200)
|
35
|
+
cr.curve_to(450, 0, 300, 150, 50, 50)
|
36
|
+
cr.stroke_preserve
|
37
|
+
path = cr.copy_path_flat
|
38
|
+
|
39
|
+
cr.line_width = 1
|
40
|
+
cr.new_path
|
41
|
+
layout = make_layout(cr, text)
|
42
|
+
cr.pango_layout_line_path(layout.get_line(0))
|
43
|
+
cr.map_path_onto(path)
|
44
|
+
|
45
|
+
cr.set_source_rgba(0.3, 0.3, 1.0, 0.3)
|
46
|
+
cr.fill_preserve
|
47
|
+
cr.set_source_rgba(0.1, 0.1, 0.1)
|
48
|
+
cr.stroke
|
49
|
+
|
50
|
+
cr.show_page
|
51
|
+
|
52
|
+
cr
|
53
|
+
end
|
54
|
+
|
55
|
+
def output
|
56
|
+
surface = Cairo::ImageSurface.new(500, 500)
|
57
|
+
render(surface)
|
58
|
+
surface.write_to_png("text-on-path.png")
|
59
|
+
end
|
60
|
+
|
61
|
+
output
|
data/samples/text2.rb
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
top = File.expand_path(File.join(File.dirname(__FILE__), ".."))
|
4
|
+
src = File.join(top, "src")
|
5
|
+
$LOAD_PATH.unshift src
|
6
|
+
$LOAD_PATH.unshift File.join(src, "lib")
|
7
|
+
|
8
|
+
require 'optparse'
|
9
|
+
require 'ostruct'
|
10
|
+
|
11
|
+
require 'cairo'
|
12
|
+
require 'pango'
|
13
|
+
|
14
|
+
def parse(args=ARGV)
|
15
|
+
options = OpenStruct.new
|
16
|
+
options.width = 595.275590551181.round
|
17
|
+
options.height = 841.889763779528.round
|
18
|
+
options.font_description = "Monospace 12"
|
19
|
+
options.fade_out = false
|
20
|
+
|
21
|
+
opts = OptionParser.new do |opts|
|
22
|
+
opts.on("--width=WIDTH", Integer, "paper width") {|options.width|}
|
23
|
+
opts.on("--height=HEIGHT", Integer, "paper height") {|options.height|}
|
24
|
+
opts.on("--font-description=DESCRIPTION",
|
25
|
+
"font description (e.g. 'Monospace 14')") do |desc|
|
26
|
+
options.font_description = desc
|
27
|
+
end
|
28
|
+
opts.on("--[no-]fade-out",
|
29
|
+
"fade-out one-third of page") {|options.fade_out|}
|
30
|
+
end
|
31
|
+
|
32
|
+
opts.parse!(args)
|
33
|
+
|
34
|
+
options
|
35
|
+
end
|
36
|
+
|
37
|
+
def render_background(cr)
|
38
|
+
cr.set_source_rgba(1.0, 1.0, 1.0)
|
39
|
+
cr.paint
|
40
|
+
end
|
41
|
+
|
42
|
+
def make_layout(cr, text, width, font_description)
|
43
|
+
layout = cr.create_pango_layout
|
44
|
+
layout.text = text
|
45
|
+
layout.width = width * Pango::SCALE
|
46
|
+
layout.font_description = Pango::FontDescription.new(font_description)
|
47
|
+
cr.update_pango_layout(layout)
|
48
|
+
layout
|
49
|
+
end
|
50
|
+
|
51
|
+
def setup_fade_out(cr, width)
|
52
|
+
fade_out = Cairo::LinearPattern.new(0, 0, width, 0)
|
53
|
+
fade_out.add_color_stop_rgba(0, 0, 0, 0, 1)
|
54
|
+
fade_out.add_color_stop_rgba(0.66, 0, 0, 0, 1)
|
55
|
+
fade_out.add_color_stop_rgba(1, 0, 0, 0, 0)
|
56
|
+
|
57
|
+
cr.set_source(fade_out)
|
58
|
+
end
|
59
|
+
|
60
|
+
def render_layout(cr, layout, margin_left, margin_top, body_height)
|
61
|
+
x = margin_left
|
62
|
+
y = margin_top
|
63
|
+
limit_y = margin_top + body_height
|
64
|
+
|
65
|
+
iter = layout.iter
|
66
|
+
prev_baseline = iter.baseline / Pango::SCALE
|
67
|
+
begin
|
68
|
+
line = iter.line
|
69
|
+
ink_rect, logical_rect = iter.line_extents
|
70
|
+
y_begin, y_end = iter.line_yrange
|
71
|
+
if limit_y < (y + y_end / Pango::SCALE)
|
72
|
+
cr.show_page
|
73
|
+
y = margin_top - prev_baseline
|
74
|
+
end
|
75
|
+
baseline = iter.baseline / Pango::SCALE
|
76
|
+
cr.move_to(x + logical_rect.x / Pango::SCALE, y + baseline)
|
77
|
+
cr.show_pango_layout_line(line)
|
78
|
+
prev_baseline = baseline
|
79
|
+
end while iter.next_line!
|
80
|
+
end
|
81
|
+
|
82
|
+
def render(options, output, surface_class)
|
83
|
+
text = options.text
|
84
|
+
width = options.width
|
85
|
+
height = options.height
|
86
|
+
font_description = options.font_description
|
87
|
+
fade_out = options.fade_out
|
88
|
+
|
89
|
+
margin_left = (width * 0.05).ceil
|
90
|
+
margin_right = (width * 0.05).ceil
|
91
|
+
margin_top = (height * 0.05).ceil
|
92
|
+
margin_bottom = (height * 0.05).ceil
|
93
|
+
body_width = width - margin_left - margin_right
|
94
|
+
body_height = height - margin_top - margin_bottom
|
95
|
+
|
96
|
+
surface = surface_class.new(output, width, height)
|
97
|
+
cr = Cairo::Context.new(surface)
|
98
|
+
|
99
|
+
render_background(cr)
|
100
|
+
layout = make_layout(cr, text, body_width, font_description)
|
101
|
+
if fade_out
|
102
|
+
setup_fade_out(cr, body_width)
|
103
|
+
else
|
104
|
+
cr.set_source_rgba(0, 0, 0, 1)
|
105
|
+
end
|
106
|
+
render_layout(cr, layout, margin_left, margin_top, body_height)
|
107
|
+
|
108
|
+
cr.show_page
|
109
|
+
|
110
|
+
cr.target.finish
|
111
|
+
cr
|
112
|
+
end
|
113
|
+
|
114
|
+
def output(options, surface_class_name, suffix)
|
115
|
+
if Cairo.const_defined?(surface_class_name)
|
116
|
+
surface_class = Cairo.const_get(surface_class_name)
|
117
|
+
render(options, "text2.#{suffix}", surface_class)
|
118
|
+
else
|
119
|
+
puts("#{surface_class_name} isn't supported.")
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
options = parse
|
124
|
+
options.text = ARGF.read
|
125
|
+
output(options, "PSSurface", "ps")
|
126
|
+
output(options, "PDFSurface", "pdf")
|
127
|
+
output(options, "SVGSurface", "svg")
|
data/src/cairo.def
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
EXPORTS
|
2
|
+
Init_cairo
|
3
|
+
rb_mCairo DATA
|
4
|
+
rb_cCairo_Context DATA
|
5
|
+
rb_cCairo_Path DATA
|
6
|
+
rb_cCairo_Matrix DATA
|
7
|
+
rb_cCairo_Pattern DATA
|
8
|
+
rb_cCairo_SolidPattern DATA
|
9
|
+
rb_cCairo_SurfacePattern DATA
|
10
|
+
rb_cCairo_GradientPattern DATA
|
11
|
+
rb_cCairo_LinearPattern DATA
|
12
|
+
rb_cCairo_RadialPattern DATA
|
13
|
+
rb_cCairo_FontFace DATA
|
14
|
+
rb_cCairo_FontExtents DATA
|
15
|
+
rb_cCairo_FontOptions DATA
|
16
|
+
rb_cCairo_ScaledFont DATA
|
17
|
+
rb_cCairo_TextExtents DATA
|
18
|
+
rb_cCairo_Glyph DATA
|
19
|
+
rb_cCairo_Surface DATA
|
20
|
+
rb_cairo_context_from_ruby_object
|
21
|
+
rb_cairo_context_to_ruby_object
|
22
|
+
rb_cairo_path_from_ruby_object
|
23
|
+
rb_cairo_path_to_ruby_object
|
24
|
+
rb_cairo_matrix_from_ruby_object
|
25
|
+
rb_cairo_matrix_to_ruby_object
|
26
|
+
rb_cairo_pattern_from_ruby_object
|
27
|
+
rb_cairo_pattern_to_ruby_object
|
28
|
+
rb_cairo_font_face_from_ruby_object
|
29
|
+
rb_cairo_font_face_to_ruby_object
|
30
|
+
rb_cairo_font_extents_from_ruby_object
|
31
|
+
rb_cairo_font_extents_to_ruby_object
|
32
|
+
rb_cairo_font_options_to_ruby_object
|
33
|
+
rb_cairo_font_options_from_ruby_object
|
34
|
+
rb_cairo_scaled_font_to_ruby_object
|
35
|
+
rb_cairo_scaled_font_from_ruby_object
|
36
|
+
rb_cairo_text_extents_from_ruby_object
|
37
|
+
rb_cairo_text_extents_to_ruby_object
|
38
|
+
rb_cairo_glyph_from_ruby_object
|
39
|
+
rb_cairo_glyph_to_ruby_object
|
40
|
+
rb_cairo_surface_from_ruby_object
|
41
|
+
rb_cairo_surface_to_ruby_object
|
42
|
+
rb_cairo_operator_from_ruby_object
|
43
|
+
rb_cairo_antialias_from_ruby_object
|
44
|
+
rb_cairo_fill_rule_from_ruby_object
|
45
|
+
rb_cairo_line_cap_from_ruby_object
|
46
|
+
rb_cairo_line_join_from_ruby_object
|
47
|
+
rb_cairo_font_slant_from_ruby_object
|
48
|
+
rb_cairo_font_weight_from_ruby_object
|
49
|
+
rb_cairo_subpixel_order_from_ruby_object
|
50
|
+
rb_cairo_hint_style_from_ruby_object
|
51
|
+
rb_cairo_hint_metrics_from_ruby_object
|
52
|
+
rb_cairo_path_data_type_from_ruby_object
|
53
|
+
rb_cairo_content_from_ruby_object
|
54
|
+
rb_cairo_format_from_ruby_object
|
55
|
+
rb_cairo_extend_from_ruby_object
|
56
|
+
rb_cairo_filter_from_ruby_object
|
57
|
+
rb_cairo_svg_version_from_ruby_object
|
58
|
+
rb_cairo_check_status
|
data/src/lib/cairo.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
# vim: filetype=ruby:expandtab:shiftwidth=2:tabstop=8:softtabstop=2 :
|
2
|
+
|
3
|
+
if /mingw|mswin|mswin32/ =~ RUBY_PLATFORM
|
4
|
+
require 'rbconfig'
|
5
|
+
ENV['PATH'] = %w(bin lib).collect do |dir|
|
6
|
+
"#{Config::CONFIG["prefix"]}\\lib\\GTK\\#{dir};"
|
7
|
+
end.join('') + ENV['PATH']
|
8
|
+
end
|
9
|
+
|
10
|
+
module Cairo
|
11
|
+
def self.__add_one_arg_setter(klass)
|
12
|
+
names = klass.instance_methods(false)
|
13
|
+
names.each do |name|
|
14
|
+
if /^set_(.*)/ =~ name and
|
15
|
+
not names.include? "#{$1}=" and
|
16
|
+
klass.instance_method(name).arity == 1
|
17
|
+
klass.module_eval("def #{$1}=(val); set_#{$1}(val); val; end")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
require 'cairo.so'
|
24
|
+
|
25
|
+
module Cairo
|
26
|
+
class << self
|
27
|
+
undef __add_one_arg_setter
|
28
|
+
end
|
29
|
+
|
30
|
+
module_function
|
31
|
+
def bindings_version
|
32
|
+
major, minor, micro, tag = BINDINGS_VERSION
|
33
|
+
version = [major, minor, micro].join('.')
|
34
|
+
version << "-#{tag}" if tag
|
35
|
+
version
|
36
|
+
end
|
37
|
+
|
38
|
+
class Surface
|
39
|
+
def dup
|
40
|
+
raise NotImplementedError
|
41
|
+
end
|
42
|
+
def clone
|
43
|
+
raise NotImplementedError
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class SVGSurface
|
48
|
+
class << self
|
49
|
+
def versions_as_string
|
50
|
+
versions.collect do |version|
|
51
|
+
version_to_string(version)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class Matrix
|
58
|
+
def dup
|
59
|
+
Matrix.new(*to_a)
|
60
|
+
end
|
61
|
+
|
62
|
+
def clone
|
63
|
+
copy = dup
|
64
|
+
copy.freeze if self.frozen?
|
65
|
+
copy
|
66
|
+
end
|
67
|
+
|
68
|
+
def translate(tx, ty); dup.translate!(tx, ty); end
|
69
|
+
def scale(sx, sy); dup.scale!(sx, sy); end
|
70
|
+
def rotate(radians); dup.rotate!(radians); end
|
71
|
+
def invert; dup.invert!; end
|
72
|
+
def multiply(other); dup.multiply!(other); end
|
73
|
+
alias * multiply
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
require 'cairo/context'
|