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
data/ext/context.h ADDED
@@ -0,0 +1,33 @@
1
+ /*
2
+ Copyright (c) 2006, The Omni Group, Inc. All rights reserved.
3
+
4
+ OPEN PERMISSION TO USE AND REPRODUCE OMNI SOURCE CODE SOFTWARE
5
+
6
+ Omni Source Code software is available from The Omni Group on their web
7
+ site at www.omnigroup.com.
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a
10
+ copy of this software and associated documentation files (the "Software"),
11
+ to deal in the Software without restriction, including without limitation
12
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
13
+ and/or sell copies of the Software, and to permit persons to whom the
14
+ Software is furnished to do so, subject to the following conditions:
15
+
16
+ Any original copyright notices and this permission notice shall be included
17
+ in all copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25
+ DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+ #include "ruby.h"
29
+
30
+ extern void Init_context(void);
31
+ extern VALUE context_class;
32
+
33
+ extern CGContextRef context_get(VALUE self);
data/ext/extconf.rb ADDED
@@ -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
+ require 'rbconfig'
27
+ # Xcode 2.2 moved ruby.h
28
+ unless File.exists? File.join(Config::CONFIG['archdir'], 'ruby.h')
29
+ Config::CONFIG['archdir'] = Config::CONFIG['archdir'].sub(/powerpc/, 'universal')
30
+ end
31
+
32
+ require 'mkmf'
33
+
34
+ # If your ruby is non-Universal, you can't build Univeral gems. So, we'll just build the gem for the current architecture. You can change this if you have a Universal ruby install.
35
+ #$ARCH_FLAGS = '-arch ppc -arch i386'
36
+ $ARCH_FLAGS = '-arch ' + `arch`.chomp
37
+
38
+ # Only export our main Init function, allowing us to use extern functions between the bundles w/o worries
39
+ # TODO: Does Ruby load the bundle within a private namespace anyway?
40
+ $CFLAGS = $ARCH_FLAGS + ' -include rubyquartz_prefix.h -x objective-c -fobjc-exceptions -g -Werror -Wall -Wno-trigraphs -Wreturn-type -Wformat -Wmissing-braces -Wparentheses -Wswitch -Wunused-function -Wunused-label -Wunused-variable -Wunused-value -Wunknown-pragmas -Wsign-compare -Wnewline-eof -Wno-\#warnings'
41
+
42
+ # Pick one of these for release vs. debug
43
+ #$CFLAGS += ' -O2 -Wuninitialized'
44
+ $CFLAGS += ' -DDEBUG -O0 -fno-inline-functions'
45
+
46
+ $LDFLAGS = $ARCH_FLAGS + ' -framework Cocoa -framework ApplicationServices -framework CoreFoundation -exported_symbols_list ExportedSymbols.txt'
47
+
48
+ create_makefile("rubyquartz_api")
data/ext/font.c ADDED
@@ -0,0 +1,148 @@
1
+ /*
2
+ * Copyright (c) 2006, The Omni Group. All rights reserved.
3
+ *
4
+ * Redistribution and use in source and binary forms, with or without
5
+ * modification, are permitted provided that the following conditions
6
+ * are met:
7
+ * 1. Redistributions of source code must retain the above copyright
8
+ * notice, this list of conditions and the following disclaimer.
9
+ * 2. Redistributions in binary form must reproduce the above copyright
10
+ * notice, this list of conditions and the following disclaimer in the
11
+ * documentation and/or other materials provided with the distribution.
12
+ * 3. Neither the name of The Omni Group ("Omni") nor the names of
13
+ * its contributors may be used to endorse or promote products derived
14
+ * from this software without specific prior written permission.
15
+ *
16
+ * THIS SOFTWARE IS PROVIDED BY OMNI AND ITS CONTRIBUTORS "AS IS" AND
17
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
+ * ARE DISCLAIMED. IN NO EVENT SHALL OMNI OR ITS CONTRIBUTORS BE LIABLE FOR
20
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
25
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
+ * POSSIBILITY OF SUCH DAMAGE.
27
+ */
28
+
29
+ #include "font.h"
30
+
31
+ #import <Cocoa/Cocoa.h>
32
+
33
+ VALUE font_class;
34
+
35
+ NSFont *font_get(VALUE self)
36
+ {
37
+ return (NSFont *)_objc_type_get(self, [NSFont class]);
38
+ }
39
+ void font_set(VALUE self, NSFont *font)
40
+ {
41
+ _objc_type_set(self, [NSFont class], font);
42
+ }
43
+
44
+ static VALUE font_families(VALUE self)
45
+ {
46
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
47
+ @try {
48
+ NSArray *families = [[NSFontManager sharedFontManager] availableFontFamilies];
49
+ VALUE names = rb_ary_new();
50
+ unsigned familyIndex = [families count];
51
+ while (familyIndex--) {
52
+ NSString *familyName = [families objectAtIndex:familyIndex];
53
+ const char *utf8Name = [familyName UTF8String];
54
+ rb_ary_unshift(names, rb_str_new(utf8Name, strlen(utf8Name)));
55
+ }
56
+ return names;
57
+ } @catch (NSException *exc) {
58
+ NSLog(@"%s -- %@", __PRETTY_FUNCTION__, exc);
59
+ } @finally {
60
+ [pool release];
61
+ }
62
+ rb_raise(rb_eException, "Unable to create array of font family names");
63
+ }
64
+
65
+ static VALUE fonts_in_family(VALUE self, VALUE family)
66
+ {
67
+ // Ruby and ObjC exceptions aren't the same, so do this first to make sure that 'family' is string-y
68
+ NSString *familyName = (NSString *)_copy_string_for_str(family);
69
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
70
+ @try {
71
+ [familyName autorelease];
72
+ NSArray *members = [[NSFontManager sharedFontManager] availableMembersOfFontFamily:familyName];
73
+
74
+ VALUE names = rb_ary_new();
75
+ unsigned memberIndex = [members count];
76
+ while (memberIndex--) {
77
+ NSString *memberName = [[members objectAtIndex:memberIndex] objectAtIndex:0];
78
+ const char *utf8Name = [memberName UTF8String];
79
+ rb_ary_unshift(names, rb_str_new(utf8Name, strlen(utf8Name)));
80
+ }
81
+ return names;
82
+ } @catch (NSException *exc) {
83
+ NSLog(@"%s -- %@", __PRETTY_FUNCTION__, exc);
84
+ } @finally {
85
+ [pool release];
86
+ }
87
+ rb_raise(rb_eException, "Unable to create array of fonts in specified family");
88
+ return self;
89
+ }
90
+
91
+ static VALUE _initialize_with_name_and_size(VALUE self, VALUE name, VALUE size)
92
+ {
93
+ // Transform Ruby values before entry ObjC exception domain
94
+ float s = NIL_P(size) ? 12.0f : NUM2DBL(size);
95
+ NSString *fontName = NIL_P(name) ? @"LucidaGrande" : (NSString *)_copy_string_for_str(name);
96
+
97
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
98
+ @try {
99
+ [fontName autorelease];
100
+ NSFont *font = [NSFont fontWithName:fontName size:s];
101
+ if (font) {
102
+ font_set(self, font);
103
+ return self;
104
+ }
105
+ } @catch (NSException *exc) {
106
+ NSLog(@"%s -- %@", __PRETTY_FUNCTION__, exc);
107
+ } @finally {
108
+ [pool release];
109
+ }
110
+ rb_raise(rb_eException, "Unable to create font");
111
+ return self;
112
+ }
113
+
114
+ static VALUE font_name(VALUE self)
115
+ {
116
+ NSFont *font = font_get(self);
117
+
118
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
119
+ @try {
120
+ return _value_for_string((CFStringRef)[font fontName]);
121
+ } @catch (NSException *exc) {
122
+ NSLog(@"%s -- %@", __PRETTY_FUNCTION__, exc);
123
+ } @finally {
124
+ [pool release];
125
+ }
126
+ rb_raise(rb_eException, "Unable to get font name");
127
+ return self;
128
+ }
129
+
130
+ static VALUE font_size(VALUE self)
131
+ {
132
+ NSFont *font = font_get(self);
133
+ return rb_float_new([font pointSize]);
134
+ }
135
+
136
+ void Init_font(void)
137
+ {
138
+ font_class = rb_define_class_under(module, "Font", rb_cObject);
139
+ rb_define_alloc_func(font_class, _cftype_alloc);
140
+
141
+ // TODO: Not private
142
+ rb_define_module_function(font_class, "_families", font_families, 0);
143
+ rb_define_module_function(font_class, "_fonts_in_family", fonts_in_family, 1);
144
+
145
+ rb_define_private_method(font_class, "_initialize_with_name_and_size", _initialize_with_name_and_size, 2);
146
+ rb_define_method(font_class, "name", font_name, 0);
147
+ rb_define_method(font_class, "size", font_size, 0);
148
+ }
data/ext/font.h ADDED
@@ -0,0 +1,32 @@
1
+ /*
2
+ Copyright (c) 2006, The Omni Group, Inc. All rights reserved.
3
+
4
+ OPEN PERMISSION TO USE AND REPRODUCE OMNI SOURCE CODE SOFTWARE
5
+
6
+ Omni Source Code software is available from The Omni Group on their web
7
+ site at www.omnigroup.com.
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a
10
+ copy of this software and associated documentation files (the "Software"),
11
+ to deal in the Software without restriction, including without limitation
12
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
13
+ and/or sell copies of the Software, and to permit persons to whom the
14
+ Software is furnished to do so, subject to the following conditions:
15
+
16
+ Any original copyright notices and this permission notice shall be included
17
+ in all copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25
+ DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+ extern void Init_font(void);
29
+ extern VALUE font_class;
30
+
31
+ @class NSFont;
32
+ extern NSFont *font_get(VALUE self);
data/ext/function.c ADDED
@@ -0,0 +1,124 @@
1
+ /*
2
+ Copyright (c) 2006, The Omni Group, Inc. All rights reserved.
3
+
4
+ OPEN PERMISSION TO USE AND REPRODUCE OMNI SOURCE CODE SOFTWARE
5
+
6
+ Omni Source Code software is available from The Omni Group on their web
7
+ site at www.omnigroup.com.
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a
10
+ copy of this software and associated documentation files (the "Software"),
11
+ to deal in the Software without restriction, including without limitation
12
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
13
+ and/or sell copies of the Software, and to permit persons to whom the
14
+ Software is furnished to do so, subject to the following conditions:
15
+
16
+ Any original copyright notices and this permission notice shall be included
17
+ in all copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25
+ DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+
29
+ #include "function.h"
30
+
31
+ VALUE function_class;
32
+ static ID evaluate_id;
33
+
34
+ typedef struct {
35
+ VALUE self; // We should NOT mark this as this info is just a backpointer to the object that owns this info via the CGFunctionRef
36
+ unsigned int domain_length;
37
+ unsigned int range_length;
38
+ } function_info;
39
+
40
+ CGFunctionRef function_get(VALUE self)
41
+ {
42
+ return (CGFunctionRef)_cftype_get(self, CGFunctionGetTypeID(), "CGFunctionRef");
43
+ }
44
+
45
+ static void _function_evaluate(void *info, const float *in, float *out)
46
+ {
47
+ function_info *finfo = (function_info *)info;
48
+
49
+ // create arrays to pass into Ruby land. We'll fill out the inputs and #evaluate should fill in the output
50
+ VALUE input_ary = rb_ary_new2(finfo->domain_length);
51
+ VALUE output_ary = rb_ary_new2(finfo->range_length);
52
+
53
+ // TODO: Need to catch Ruby exceptions in all of this code to avoid blowing past CG's call stack
54
+
55
+ unsigned int i;
56
+ for (i = 0; i < finfo->domain_length; i++)
57
+ rb_ary_unshift(input_ary, rb_float_new(in[i]));
58
+
59
+ rb_funcall(finfo->self, evaluate_id, 2, input_ary, output_ary);
60
+
61
+ for (i = 0; i < finfo->range_length; i++)
62
+ out[i] = NUM2DBL(rb_ary_entry(output_ary, i));
63
+ }
64
+
65
+ static void _function_info_release(void *info)
66
+ {
67
+ free(info);
68
+ }
69
+
70
+ static VALUE function_init(VALUE self, VALUE domain_length, VALUE domain, VALUE range_length, VALUE range)
71
+ {
72
+ unsigned int _domain_length = NUM2UINT(domain_length);
73
+ unsigned int _range_length = NUM2UINT(range_length);
74
+ domain = rb_check_convert_type(domain, T_ARRAY, "Array", "to_a");
75
+ range = rb_check_convert_type(range, T_ARRAY, "Array", "to_a");
76
+
77
+ // Actually, it can probably be > 4, but this lets us avoid a malloc
78
+ if (_domain_length == 0 || _domain_length > 4)
79
+ rb_raise(rb_eArgError, "Domain must be within 1 to 4");
80
+ if (_range_length == 0 || _range_length > 4)
81
+ rb_raise(rb_eArgError, "Range must be within 1 to 4");
82
+
83
+ // Enough for 4 ranges, start and end interleaved
84
+ float domainFloats[8], rangeFloats[8];
85
+
86
+ unsigned int i;
87
+ for (i = 0; i < _domain_length; i++) {
88
+ domainFloats[2*i+0] = NUM2DBL(rb_ary_entry(domain, 2*i+0));
89
+ domainFloats[2*i+1] = NUM2DBL(rb_ary_entry(domain, 2*i+1));
90
+ }
91
+ for (i = 0; i < _range_length; i++) {
92
+ rangeFloats[2*i+0] = NUM2DBL(rb_ary_entry(range, 2*i+0));
93
+ rangeFloats[2*i+1] = NUM2DBL(rb_ary_entry(range, 2*i+1));
94
+ }
95
+
96
+ struct CGFunctionCallbacks callbacks;
97
+ memset(&callbacks, 0, sizeof(callbacks));
98
+ callbacks.evaluate = _function_evaluate;
99
+ callbacks.releaseInfo = _function_info_release;
100
+
101
+ function_info *info = calloc(1, sizeof(function_info));
102
+ info->self = self;
103
+ info->domain_length = _domain_length;
104
+ info->range_length = _range_length;
105
+
106
+ CGFunctionRef *func;
107
+ Data_Get_Struct(self, CGFunctionRef, func);
108
+ if (!func)
109
+ rb_raise(rb_eException, "Function not initialized correctly");
110
+ *func = CGFunctionCreate(info, _domain_length, domainFloats, _range_length, rangeFloats, &callbacks);
111
+ if (!*func)
112
+ rb_raise(rb_eException, "Unable to create function");
113
+
114
+ return self;
115
+ }
116
+
117
+ void Init_function()
118
+ {
119
+ function_class = rb_define_class_under(module, "Function", rb_cObject);
120
+ rb_define_alloc_func(function_class, _cftype_alloc);
121
+
122
+ evaluate_id = rb_intern("evaluate");
123
+ rb_define_private_method(function_class, "_initialize", function_init, 4);
124
+ }
data/ext/function.h ADDED
@@ -0,0 +1,32 @@
1
+ /*
2
+ Copyright (c) 2006, The Omni Group, Inc. All rights reserved.
3
+
4
+ OPEN PERMISSION TO USE AND REPRODUCE OMNI SOURCE CODE SOFTWARE
5
+
6
+ Omni Source Code software is available from The Omni Group on their web
7
+ site at www.omnigroup.com.
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a
10
+ copy of this software and associated documentation files (the "Software"),
11
+ to deal in the Software without restriction, including without limitation
12
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
13
+ and/or sell copies of the Software, and to permit persons to whom the
14
+ Software is furnished to do so, subject to the following conditions:
15
+
16
+ Any original copyright notices and this permission notice shall be included
17
+ in all copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25
+ DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+
29
+ extern void Init_function(void);
30
+ extern VALUE function_class;
31
+
32
+ extern CGFunctionRef function_get(VALUE self);
data/ext/image.c ADDED
@@ -0,0 +1,140 @@
1
+ /*
2
+ Copyright (c) 2006, The Omni Group, Inc. All rights reserved.
3
+
4
+ OPEN PERMISSION TO USE AND REPRODUCE OMNI SOURCE CODE SOFTWARE
5
+
6
+ Omni Source Code software is available from The Omni Group on their web
7
+ site at www.omnigroup.com.
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a
10
+ copy of this software and associated documentation files (the "Software"),
11
+ to deal in the Software without restriction, including without limitation
12
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
13
+ and/or sell copies of the Software, and to permit persons to whom the
14
+ Software is furnished to do so, subject to the following conditions:
15
+
16
+ Any original copyright notices and this permission notice shall be included
17
+ in all copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25
+ DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+
29
+ #include "image.h"
30
+
31
+ #include "bitmap_context.h"
32
+ #include "image_source.h"
33
+ #include "size.h"
34
+
35
+ VALUE image_class;
36
+
37
+ CGImageRef image_get(VALUE self)
38
+ {
39
+ return (CGImageRef)_cftype_get(self, CGImageGetTypeID(), "CGImageRef");
40
+ }
41
+
42
+ static void image_set(VALUE self, CGImageRef image)
43
+ {
44
+ _cftype_set(self, CGImageGetTypeID(), "CGImageRef", image);
45
+ }
46
+
47
+ static VALUE _initialize_with_bitmap_context(VALUE self, VALUE bitmap_context)
48
+ {
49
+ CGContextRef ctx = bitmap_context_get(bitmap_context);
50
+ CGImageRef img = CGBitmapContextCreateImage(ctx);
51
+ if (!img)
52
+ rb_raise(rb_eException, "Unable to create an image from the BitmapContext");
53
+ image_set(self, img);
54
+ CFRelease(img);
55
+
56
+ return self;
57
+ }
58
+
59
+ static VALUE _initialize_with_image_source_at_index(VALUE self, VALUE image_source, VALUE index)
60
+ {
61
+ CFDictionaryRef options = NULL;
62
+ CGImageRef img = CGImageSourceCreateImageAtIndex(image_source_get(image_source), NUM2INT(index), options);
63
+ if (!img)
64
+ rb_raise(rb_eException, "Unable to create image");
65
+
66
+ image_set(self, img);
67
+ CFRelease(img);
68
+
69
+ return self;
70
+ }
71
+
72
+ static VALUE _image_size(VALUE self)
73
+ {
74
+ CGImageRef image = image_get(self);
75
+ return size_value_from_size(CGSizeMake(CGImageGetWidth(image), CGImageGetHeight(image)));
76
+ }
77
+
78
+ static VALUE _image_png_data(VALUE self)
79
+ {
80
+ CGImageRef img = image_get(self);
81
+
82
+ CFMutableDataRef data = CFDataCreateMutable(kCFAllocatorDefault, 0);
83
+ CGImageDestinationRef imageDest = CGImageDestinationCreateWithData(data, CFSTR("public.png"), 1/*image count*/, NULL/*options*/);
84
+
85
+ if (!imageDest) {
86
+ CFRelease(data);
87
+ rb_raise(rb_eException, "Unable to create image destination");
88
+ }
89
+
90
+ CGImageDestinationAddImage(imageDest, img, NULL/*options*/);
91
+ if (!CGImageDestinationFinalize(imageDest)) {
92
+ CFRelease(imageDest);
93
+ CFRelease(data);
94
+ rb_raise(rb_eException, "Unable to finalize image destination");
95
+ }
96
+ CFRelease(imageDest);
97
+
98
+ VALUE str = rb_str_new((const char *)CFDataGetBytePtr(data), CFDataGetLength(data));
99
+ CFRelease(data);
100
+
101
+ return str;
102
+ }
103
+
104
+ static VALUE _write_png_to_file(VALUE self, VALUE path)
105
+ {
106
+ CGImageRef img = image_get(self);
107
+ CFURLRef url = _create_url_for_path(path);
108
+
109
+ //CFShow(CGImageDestinationCopyTypeIdentifiers());
110
+
111
+ CGImageDestinationRef imageDest = CGImageDestinationCreateWithURL(url, CFSTR("public.png"), 1/*image count*/, NULL/*options*/);
112
+ CFRelease(url);
113
+
114
+ if (!imageDest)
115
+ rb_raise(rb_eException, "Unable to create image destination");
116
+
117
+ CGImageDestinationAddImage(imageDest, img, NULL/*options*/);
118
+ if (!CGImageDestinationFinalize(imageDest)) {
119
+ CFRelease(imageDest);
120
+ rb_raise(rb_eException, "Unable to finalize image destination");
121
+ }
122
+ CFRelease(imageDest);
123
+
124
+ return self;
125
+ }
126
+
127
+ void Init_image(void)
128
+ {
129
+ image_class = rb_define_class_under(module, "Image", rb_cObject);
130
+ rb_define_alloc_func(image_class, _cftype_alloc);
131
+
132
+ rb_define_private_method(image_class, "_initialize_with_bitmap_context", _initialize_with_bitmap_context, 1);
133
+ rb_define_private_method(image_class, "_initialize_with_image_source_at_index", _initialize_with_image_source_at_index, 2);
134
+
135
+ rb_define_method(image_class, "size", _image_size, 0);
136
+
137
+ // TODO: Expose the full CGImageDestination API and rewrite this using it
138
+ rb_define_method(image_class, "png_data", _image_png_data, 0);
139
+ rb_define_method(image_class, "write_png_to_file", _write_png_to_file, 1);
140
+ }