texplay 0.2.1-x86-mswin32-60
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/CHANGELOG +68 -0
 - data/README +21 -0
 - data/README1st +9 -0
 - data/Rakefile +85 -0
 - data/examples/basic.rb +48 -0
 - data/examples/basic2.rb +37 -0
 - data/examples/benchmark.rb +299 -0
 - data/examples/common.rb +8 -0
 - data/examples/example_alpha_blend.rb +31 -0
 - data/examples/example_bezier.rb +51 -0
 - data/examples/example_color_control.rb +68 -0
 - data/examples/example_color_transform.rb +29 -0
 - data/examples/example_dup.rb +52 -0
 - data/examples/example_each.rb +42 -0
 - data/examples/example_effect.rb +35 -0
 - data/examples/example_fill.rb +49 -0
 - data/examples/example_fill_old.rb +49 -0
 - data/examples/example_fluent.rb +31 -0
 - data/examples/example_gen_eval.rb +34 -0
 - data/examples/example_hash_arguments.rb +47 -0
 - data/examples/example_melt.rb +27 -0
 - data/examples/example_polyline.rb +43 -0
 - data/examples/example_simple.rb +35 -0
 - data/examples/example_sync.rb +60 -0
 - data/examples/example_turtle.rb +40 -0
 - data/examples/media/empty2.png +0 -0
 - data/examples/media/gosu.png +0 -0
 - data/examples/media/maria.png +0 -0
 - data/examples/media/rose.bmp +0 -0
 - data/examples/media/sand1.png +0 -0
 - data/examples/media/sunset.png +0 -0
 - data/examples/media/texplay.png +0 -0
 - data/examples/specs.rb +240 -0
 - data/examples/test.rb +70 -0
 - data/examples/test2.rb +72 -0
 - data/lib/ctexplay.18.so +0 -0
 - data/lib/ctexplay.19.so +0 -0
 - data/lib/texplay-contrib.rb +77 -0
 - data/lib/texplay.rb +134 -0
 - data/src/Makefile +181 -0
 - data/src/TAGS +286 -0
 - data/src/actions.c +1306 -0
 - data/src/actions.h +52 -0
 - data/src/actions.obj +0 -0
 - data/src/bindings.c +1081 -0
 - data/src/bindings.h +45 -0
 - data/src/bindings.obj +0 -0
 - data/src/cache.c +132 -0
 - data/src/cache.h +24 -0
 - data/src/cache.obj +0 -0
 - data/src/compat.h +23 -0
 - data/src/ctexplay-i386-mswin32.def +2 -0
 - data/src/ctexplay-i386-mswin32.exp +0 -0
 - data/src/ctexplay-i386-mswin32.lib +0 -0
 - data/src/ctexplay-i386-mswin32.pdb +0 -0
 - data/src/ctexplay.so +0 -0
 - data/src/extconf.rb +18 -0
 - data/src/gen_eval.c +209 -0
 - data/src/gen_eval.h +20 -0
 - data/src/gen_eval.obj +0 -0
 - data/src/mkmf.log +18 -0
 - data/src/object2module.c +171 -0
 - data/src/object2module.h +11 -0
 - data/src/object2module.obj +0 -0
 - data/src/texplay.c +136 -0
 - data/src/texplay.h +107 -0
 - data/src/texplay.obj +0 -0
 - data/src/utils.c +959 -0
 - data/src/utils.h +143 -0
 - data/src/utils.obj +0 -0
 - data/src/vc60.pdb +0 -0
 - metadata +132 -0
 
    
        data/src/TAGS
    ADDED
    
    | 
         @@ -0,0 +1,286 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            
         
     | 
| 
      
 2 
     | 
    
         
            +
            actions.c,3564
         
     | 
| 
      
 3 
     | 
    
         
            +
            do_sync(action_struct * cur, texture_info * tex) do_sync34,1286
         
     | 
| 
      
 4 
     | 
    
         
            +
            line_do_action(int x1, int y1, int x2, int y2, texture_info * tex, VALUE hash_arg,line_do_action44,1509
         
     | 
| 
      
 5 
     | 
    
         
            +
            #define SIMPLE_FORMAT SIMPLE_FORMAT126,3531
         
     | 
| 
      
 6 
     | 
    
         
            +
            #define POINT_FORMAT POINT_FORMAT127,3555
         
     | 
| 
      
 7 
     | 
    
         
            +
            polyline_point(VALUE points, int k, int * x, int * y, int format, int draw_offset_x,polyline_point131,3622
         
     | 
| 
      
 8 
     | 
    
         
            +
            polyline_do_action(VALUE points, texture_info * tex, VALUE hash_arg,polyline_do_action154,4324
         
     | 
| 
      
 9 
     | 
    
         
            +
            ngon_do_action(int x, int y, int r, int num_sides, texture_info * tex, VALUE hash_arg,ngon_do_action231,6780
         
     | 
| 
      
 10 
     | 
    
         
            +
            rect_do_action(int x1, int y1, int x2, int y2, texture_info * tex, VALUE hash_arg,rect_do_action275,8056
         
     | 
| 
      
 11 
     | 
    
         
            +
            circle_do_action(int x1, int y1, int r, texture_info * tex, VALUE hash_arg,circle_do_action329,9856
         
     | 
| 
      
 12 
     | 
    
         
            +
            pixel_do_action(int x1, int y1, texture_info * tex, VALUE hash_arg,pixel_do_action403,12271
         
     | 
| 
      
 13 
     | 
    
         
            +
            typedef struct { int x1, x2, y, dy; } LINESEGMENT;x1417,12704
         
     | 
| 
      
 14 
     | 
    
         
            +
            typedef struct { int x1, x2, y, dy; } LINESEGMENT;x2417,12704
         
     | 
| 
      
 15 
     | 
    
         
            +
            typedef struct { int x1, x2, y, dy; } LINESEGMENT;y417,12704
         
     | 
| 
      
 16 
     | 
    
         
            +
            typedef struct { int x1, x2, y, dy; } LINESEGMENT;dy417,12704
         
     | 
| 
      
 17 
     | 
    
         
            +
            typedef struct { int x1, x2, y, dy; } LINESEGMENT;LINESEGMENT417,12704
         
     | 
| 
      
 18 
     | 
    
         
            +
            #define MAXDEPTH MAXDEPTH419,12756
         
     | 
| 
      
 19 
     | 
    
         
            +
            #define PUSH(PUSH421,12780
         
     | 
| 
      
 20 
     | 
    
         
            +
            #define POP(POP425,12997
         
     | 
| 
      
 21 
     | 
    
         
            +
            flood_fill_do_action(int x, int y, texture_info * tex, VALUE hash_arg,flood_fill_do_action429,13142
         
     | 
| 
      
 22 
     | 
    
         
            +
            glow_floodFill( int x, int y, rgba * seed_color, action_struct * cur, texture_info * tex, texture_info * tex2 )glow_floodFill498,15194
         
     | 
| 
      
 23 
     | 
    
         
            +
            glow_fill_do_action(int x, int y, texture_info * tex, VALUE hash_arg,glow_fill_do_action552,17088
         
     | 
| 
      
 24 
     | 
    
         
            +
            #define stackSize stackSize586,18167
         
     | 
| 
      
 25 
     | 
    
         
            +
            int stack[stackSize];stack587,18194
         
     | 
| 
      
 26 
     | 
    
         
            +
            int stackPointer;stackPointer588,18216
         
     | 
| 
      
 27 
     | 
    
         
            +
            pop(int * x, int * y, int h) pop591,18247
         
     | 
| 
      
 28 
     | 
    
         
            +
            push(int x, int y, int h) push608,18559
         
     | 
| 
      
 29 
     | 
    
         
            +
            emptyStack() emptyStack623,18834
         
     | 
| 
      
 30 
     | 
    
         
            +
            scan_fill_do_action(int x, int y, texture_info * tex, VALUE hash_arg,scan_fill_do_action630,18902
         
     | 
| 
      
 31 
     | 
    
         
            +
            bezier_point(VALUE points, float u, float * x, float * y, int n, int format,bezier_point700,21601
         
     | 
| 
      
 32 
     | 
    
         
            +
            bezier_do_action(VALUE points, texture_info * tex, VALUE hash_arg, sync sync_mode,bezier_do_action731,22561
         
     | 
| 
      
 33 
     | 
    
         
            +
            set_color_array(VALUE ary, rgba * color)set_color_array831,25683
         
     | 
| 
      
 34 
     | 
    
         
            +
            each_pixel_do_action(int x1, int y1, int x2, int y2, VALUE proc, texture_info * tex, VALUE hash_arg,each_pixel_do_action840,25963
         
     | 
| 
      
 35 
     | 
    
         
            +
            splice_do_action(int x0, int y0, int cx1, int cy1, int cx2, int cy2, texture_info * splice_tex,splice_do_action869,26797
         
     | 
| 
      
 36 
     | 
    
         
            +
            process_common_hash_args(action_struct * cur, VALUE * hash_arg, sync sync_mode, bool primary)process_common_hash_args940,29218
         
     | 
| 
      
 37 
     | 
    
         
            +
            update_lazy_bounds(action_struct * cur, texture_info * tex)update_lazy_bounds1021,32185
         
     | 
| 
      
 38 
     | 
    
         
            +
            update_bounds(action_struct * cur, int xmin, int ymin, int xmax, int ymax)update_bounds1044,33016
         
     | 
| 
      
 39 
     | 
    
         
            +
            set_local_bounds(action_struct * cur, int xmin, int ymin, int xmax, int ymax, texture_info * tex)set_local_bounds1056,33341
         
     | 
| 
      
 40 
     | 
    
         
            +
            draw_prologue(action_struct * cur, texture_info * tex, int xmin, int ymin, int xmax, int ymax,draw_prologue1072,33773
         
     | 
| 
      
 41 
     | 
    
         
            +
            draw_epilogue(action_struct * cur, texture_info * tex, bool primary)draw_epilogue1089,34284
         
     | 
| 
      
 42 
     | 
    
         
            +
            prepare_color_control(action_struct * cur)prepare_color_control1119,34991
         
     | 
| 
      
 43 
     | 
    
         
            +
            exec_color_control_proc(action_struct * cur, texture_info * tex, int x, int y)exec_color_control_proc1135,35475
         
     | 
| 
      
 44 
     | 
    
         
            +
            prepare_fill_texture(action_struct * payload)prepare_fill_texture1179,37313
         
     | 
| 
      
 45 
     | 
    
         
            +
            set_pixel_color_with_style(action_struct * payload, texture_info * tex, int x, int y)set_pixel_color_with_style1195,37707
         
     | 
| 
      
 46 
     | 
    
         
            +
            
         
     | 
| 
      
 47 
     | 
    
         
            +
            actions.h,45
         
     | 
| 
      
 48 
     | 
    
         
            +
            #define GUARD_ACTIONS_HGUARD_ACTIONS_H2,24
         
     | 
| 
      
 49 
     | 
    
         
            +
            
         
     | 
| 
      
 50 
     | 
    
         
            +
            bindings.c,2070
         
     | 
| 
      
 51 
     | 
    
         
            +
            sync sync_mode = eager_sync;sync_mode31,585
         
     | 
| 
      
 52 
     | 
    
         
            +
            process_x_y_pairs(VALUE image, int num_pairs, VALUE * argv, ...)process_x_y_pairs34,627
         
     | 
| 
      
 53 
     | 
    
         
            +
            M_create_macro(VALUE self, VALUE method_name) M_create_macro78,1755
         
     | 
| 
      
 54 
     | 
    
         
            +
            M_remove_macro(VALUE self, VALUE method_name) M_remove_macro96,2138
         
     | 
| 
      
 55 
     | 
    
         
            +
            M_refresh_cache_all(VALUE self) M_refresh_cache_all107,2385
         
     | 
| 
      
 56 
     | 
    
         
            +
            M_create_blank(VALUE self, VALUE window, VALUE width, VALUE height)M_create_blank116,2500
         
     | 
| 
      
 57 
     | 
    
         
            +
            rb_lazy_bounds_to_image_bounds(VALUE image, image_bounds * bounds)rb_lazy_bounds_to_image_bounds128,2767
         
     | 
| 
      
 58 
     | 
    
         
            +
            parse_sync_mode(VALUE user_sync_mode)parse_sync_mode143,3223
         
     | 
| 
      
 59 
     | 
    
         
            +
            m_paint(int argc, VALUE * argv, VALUE self) m_paint166,3853
         
     | 
| 
      
 60 
     | 
    
         
            +
            m_force_sync(VALUE self, VALUE ary)m_force_sync239,5754
         
     | 
| 
      
 61 
     | 
    
         
            +
            m_dup_image(VALUE self)m_dup_image261,6219
         
     | 
| 
      
 62 
     | 
    
         
            +
            m_clone_image(VALUE self)m_clone_image290,7033
         
     | 
| 
      
 63 
     | 
    
         
            +
            m_user_set_options(VALUE self, VALUE options)m_user_set_options305,7329
         
     | 
| 
      
 64 
     | 
    
         
            +
            m_user_delete_options(VALUE self)m_user_delete_options318,7587
         
     | 
| 
      
 65 
     | 
    
         
            +
            m_get_options(VALUE self)m_get_options329,7723
         
     | 
| 
      
 66 
     | 
    
         
            +
            m_getpixel(int argc, VALUE * argv, VALUE self) m_getpixel338,7882
         
     | 
| 
      
 67 
     | 
    
         
            +
            m_circle(int argc, VALUE * argv, VALUE self) m_circle363,8384
         
     | 
| 
      
 68 
     | 
    
         
            +
            m_ngon(int argc, VALUE * argv, VALUE self)m_ngon392,8958
         
     | 
| 
      
 69 
     | 
    
         
            +
            m_flood_fill(int argc, VALUE * argv, VALUE self)m_flood_fill420,9519
         
     | 
| 
      
 70 
     | 
    
         
            +
            m_line(int argc, VALUE * argv, VALUE self) m_line463,10488
         
     | 
| 
      
 71 
     | 
    
         
            +
            m_rect(int argc, VALUE * argv, VALUE self) m_rect487,10973
         
     | 
| 
      
 72 
     | 
    
         
            +
            m_pixel(int argc, VALUE * argv, VALUE self) m_pixel513,11463
         
     | 
| 
      
 73 
     | 
    
         
            +
            m_bezier(int argc, VALUE * argv, VALUE self)m_bezier537,11925
         
     | 
| 
      
 74 
     | 
    
         
            +
            m_polyline(int argc, VALUE * argv, VALUE self)m_polyline563,12455
         
     | 
| 
      
 75 
     | 
    
         
            +
            m_splice(int argc, VALUE * argv, VALUE self) m_splice591,12982
         
     | 
| 
      
 76 
     | 
    
         
            +
            m_clear(int argc, VALUE * argv, VALUE self) m_clear638,14314
         
     | 
| 
      
 77 
     | 
    
         
            +
            m_offset(int argc, VALUE * argv, VALUE self) m_offset654,14599
         
     | 
| 
      
 78 
     | 
    
         
            +
            m_color(int argc, VALUE * argv, VALUE self) m_color688,15349
         
     | 
| 
      
 79 
     | 
    
         
            +
            m_missing(int argc, VALUE * argv, VALUE self) m_missing718,16182
         
     | 
| 
      
 80 
     | 
    
         
            +
            m_cache_refresh(VALUE self) m_cache_refresh736,16672
         
     | 
| 
      
 81 
     | 
    
         
            +
            m_quad_cached(VALUE self) m_quad_cached751,16895
         
     | 
| 
      
 82 
     | 
    
         
            +
            m_each(int argc, VALUE * argv, VALUE self)m_each777,17450
         
     | 
| 
      
 83 
     | 
    
         
            +
            
         
     | 
| 
      
 84 
     | 
    
         
            +
            bindings.h,47
         
     | 
| 
      
 85 
     | 
    
         
            +
            #define GUARD_BINDINGS_HGUARD_BINDINGS_H2,25
         
     | 
| 
      
 86 
     | 
    
         
            +
            
         
     | 
| 
      
 87 
     | 
    
         
            +
            cache.c,338
         
     | 
| 
      
 88 
     | 
    
         
            +
            static cache_t cache = {0}; cache16,219
         
     | 
| 
      
 89 
     | 
    
         
            +
            cache_create_entry(int tname) {cache_create_entry20,293
         
     | 
| 
      
 90 
     | 
    
         
            +
            find_in_cache(int tname) {find_in_cache59,1556
         
     | 
| 
      
 91 
     | 
    
         
            +
            find_or_create_cache_entry(int tname) {find_or_create_cache_entry73,1908
         
     | 
| 
      
 92 
     | 
    
         
            +
            cache_refresh_all(void) {cache_refresh_all84,2130
         
     | 
| 
      
 93 
     | 
    
         
            +
            cache_refresh_entry(int tname) {cache_refresh_entry109,2794
         
     | 
| 
      
 94 
     | 
    
         
            +
            
         
     | 
| 
      
 95 
     | 
    
         
            +
            cache.h,350
         
     | 
| 
      
 96 
     | 
    
         
            +
            #define GUARD_CACHE_HGUARD_CACHE_H5,71
         
     | 
| 
      
 97 
     | 
    
         
            +
            #define CACHE_SIZE CACHE_SIZE8,108
         
     | 
| 
      
 98 
     | 
    
         
            +
                int tname;tname12,167
         
     | 
| 
      
 99 
     | 
    
         
            +
                int sidelength;sidelength13,182
         
     | 
| 
      
 100 
     | 
    
         
            +
                float * tdata;tdata14,202
         
     | 
| 
      
 101 
     | 
    
         
            +
            } cache_entry;cache_entry15,221
         
     | 
| 
      
 102 
     | 
    
         
            +
                int len;len18,254
         
     | 
| 
      
 103 
     | 
    
         
            +
                cache_entry entry[CACHE_SIZE];                                          entry19,267
         
     | 
| 
      
 104 
     | 
    
         
            +
            } cache_t;cache_t20,344
         
     | 
| 
      
 105 
     | 
    
         
            +
            
         
     | 
| 
      
 106 
     | 
    
         
            +
            compat.h,241
         
     | 
| 
      
 107 
     | 
    
         
            +
            #define GUARD_COMPAT_HGUARD_COMPAT_H4,102
         
     | 
| 
      
 108 
     | 
    
         
            +
            # define RUBY_19RUBY_1910,218
         
     | 
| 
      
 109 
     | 
    
         
            +
            # define RCLASS_M_TBL(RCLASS_M_TBL15,309
         
     | 
| 
      
 110 
     | 
    
         
            +
            # define RCLASS_SUPER(RCLASS_SUPER16,353
         
     | 
| 
      
 111 
     | 
    
         
            +
            # define RCLASS_IV_TBL(RCLASS_IV_TBL17,397
         
     | 
| 
      
 112 
     | 
    
         
            +
            #define KLASS_OF(KLASS_OF21,534
         
     | 
| 
      
 113 
     | 
    
         
            +
            
         
     | 
| 
      
 114 
     | 
    
         
            +
            gen_eval.c,444
         
     | 
| 
      
 115 
     | 
    
         
            +
            retrieve_hidden_self(VALUE duped_context)retrieve_hidden_self11,247
         
     | 
| 
      
 116 
     | 
    
         
            +
            set_hidden_self(VALUE duped_context, VALUE hidden_self)set_hidden_self25,652
         
     | 
| 
      
 117 
     | 
    
         
            +
            rb_capture(VALUE self) {rb_capture38,1103
         
     | 
| 
      
 118 
     | 
    
         
            +
            redirect_iv_for_object(VALUE obj, VALUE dest)redirect_iv_for_object59,1553
         
     | 
| 
      
 119 
     | 
    
         
            +
            release_iv_for_object(VALUE obj)release_iv_for_object79,2305
         
     | 
| 
      
 120 
     | 
    
         
            +
            rb_gen_eval(int argc, VALUE * argv, VALUE self) {rb_gen_eval93,2658
         
     | 
| 
      
 121 
     | 
    
         
            +
            Init_gen_eval() {Init_gen_eval185,5307
         
     | 
| 
      
 122 
     | 
    
         
            +
            
         
     | 
| 
      
 123 
     | 
    
         
            +
            gen_eval.h,87
         
     | 
| 
      
 124 
     | 
    
         
            +
            #define GUARD_GEN_EVAL_HGUARD_GEN_EVAL_H4,43
         
     | 
| 
      
 125 
     | 
    
         
            +
            #define ADJUST_SELF(ADJUST_SELF14,345
         
     | 
| 
      
 126 
     | 
    
         
            +
            
         
     | 
| 
      
 127 
     | 
    
         
            +
            object2module.c,410
         
     | 
| 
      
 128 
     | 
    
         
            +
            class_alloc(VALUE flags, VALUE klass)class_alloc18,359
         
     | 
| 
      
 129 
     | 
    
         
            +
            j_class_new(VALUE module, VALUE sup)j_class_new34,752
         
     | 
| 
      
 130 
     | 
    
         
            +
            rb_to_module(VALUE self)rb_to_module81,1735
         
     | 
| 
      
 131 
     | 
    
         
            +
            rb_reset_tbls(VALUE self)rb_reset_tbls115,2493
         
     | 
| 
      
 132 
     | 
    
         
            +
            rb_gen_extend(int argc, VALUE * argv, VALUE self)rb_gen_extend124,2738
         
     | 
| 
      
 133 
     | 
    
         
            +
            rb_gen_include(int argc, VALUE * argv, VALUE self)rb_gen_include145,3259
         
     | 
| 
      
 134 
     | 
    
         
            +
            void Init_object2module()Init_object2module163,3696
         
     | 
| 
      
 135 
     | 
    
         
            +
            
         
     | 
| 
      
 136 
     | 
    
         
            +
            object2module.h,57
         
     | 
| 
      
 137 
     | 
    
         
            +
            #define GUARD_OBJECT2MODULE_HGUARD_OBJECT2MODULE_H4,53
         
     | 
| 
      
 138 
     | 
    
         
            +
            
         
     | 
| 
      
 139 
     | 
    
         
            +
            texplay.c,410
         
     | 
| 
      
 140 
     | 
    
         
            +
            Init_ctexplay() {Init_ctexplay29,843
         
     | 
| 
      
 141 
     | 
    
         
            +
            m_init_TPPoint(int argc, VALUE * argv, VALUE self)m_init_TPPoint133,5456
         
     | 
| 
      
 142 
     | 
    
         
            +
            m_init_EmptyImageStub(int argc, VALUE * argv, VALUE self)m_init_EmptyImageStub157,6066
         
     | 
| 
      
 143 
     | 
    
         
            +
            m_EmptyImageStub_columns(VALUE self)m_EmptyImageStub_columns176,6583
         
     | 
| 
      
 144 
     | 
    
         
            +
            m_EmptyImageStub_rows(VALUE self)m_EmptyImageStub_rows182,6672
         
     | 
| 
      
 145 
     | 
    
         
            +
            m_EmptyImageStub_to_blob(VALUE self)m_EmptyImageStub_to_blob188,6758
         
     | 
| 
      
 146 
     | 
    
         
            +
            
         
     | 
| 
      
 147 
     | 
    
         
            +
            texplay.h,2622
         
     | 
| 
      
 148 
     | 
    
         
            +
            #define GUARD_TEXPLAY_HGUARD_TEXPLAY_H8,201
         
     | 
| 
      
 149 
     | 
    
         
            +
            #define OOB_VAL OOB_VAL13,260
         
     | 
| 
      
 150 
     | 
    
         
            +
            #define XMAX_OOB XMAX_OOB14,281
         
     | 
| 
      
 151 
     | 
    
         
            +
            #define YMAX_OOB YMAX_OOB15,306
         
     | 
| 
      
 152 
     | 
    
         
            +
            #define XMIN_OOB XMIN_OOB16,331
         
     | 
| 
      
 153 
     | 
    
         
            +
            #define YMIN_OOB YMIN_OOB17,357
         
     | 
| 
      
 154 
     | 
    
         
            +
            #define PI PI19,384
         
     | 
| 
      
 155 
     | 
    
         
            +
            #define SWAP(SWAP22,426
         
     | 
| 
      
 156 
     | 
    
         
            +
            #define ROUND(ROUND23,485
         
     | 
| 
      
 157 
     | 
    
         
            +
            #define ARY_SIZE(ARY_SIZE24,519
         
     | 
| 
      
 158 
     | 
    
         
            +
            #define SGN(SGN25,562
         
     | 
| 
      
 159 
     | 
    
         
            +
            #define MAX(MAX26,597
         
     | 
| 
      
 160 
     | 
    
         
            +
            #define MIN(MIN27,638
         
     | 
| 
      
 161 
     | 
    
         
            +
            #define ABS(ABS28,680
         
     | 
| 
      
 162 
     | 
    
         
            +
            typedef enum e_bool {e_bool31,732
         
     | 
| 
      
 163 
     | 
    
         
            +
                false, truefalse32,754
         
     | 
| 
      
 164 
     | 
    
         
            +
                false, truetrue32,754
         
     | 
| 
      
 165 
     | 
    
         
            +
            } bool;bool33,770
         
     | 
| 
      
 166 
     | 
    
         
            +
            typedef enum e_color {e_color35,779
         
     | 
| 
      
 167 
     | 
    
         
            +
                red, green, blue, alphared36,802
         
     | 
| 
      
 168 
     | 
    
         
            +
                red, green, blue, alphagreen36,802
         
     | 
| 
      
 169 
     | 
    
         
            +
                red, green, blue, alphablue36,802
         
     | 
| 
      
 170 
     | 
    
         
            +
                red, green, blue, alphaalpha36,802
         
     | 
| 
      
 171 
     | 
    
         
            +
            } color_t;color_t37,830
         
     | 
| 
      
 172 
     | 
    
         
            +
            typedef enum e_sync_mode {e_sync_mode39,842
         
     | 
| 
      
 173 
     | 
    
         
            +
                lazy_sync, eager_sync, no_synclazy_sync40,869
         
     | 
| 
      
 174 
     | 
    
         
            +
                lazy_sync, eager_sync, no_synceager_sync40,869
         
     | 
| 
      
 175 
     | 
    
         
            +
                lazy_sync, eager_sync, no_syncno_sync40,869
         
     | 
| 
      
 176 
     | 
    
         
            +
            } sync;sync41,904
         
     | 
| 
      
 177 
     | 
    
         
            +
            typedef struct s_rgba {s_rgba44,927
         
     | 
| 
      
 178 
     | 
    
         
            +
                float red, green, blue, alpha;red45,951
         
     | 
| 
      
 179 
     | 
    
         
            +
                float red, green, blue, alpha;green45,951
         
     | 
| 
      
 180 
     | 
    
         
            +
                float red, green, blue, alpha;blue45,951
         
     | 
| 
      
 181 
     | 
    
         
            +
                float red, green, blue, alpha;alpha45,951
         
     | 
| 
      
 182 
     | 
    
         
            +
            } rgba;rgba46,986
         
     | 
| 
      
 183 
     | 
    
         
            +
                int width, height;    width50,1036
         
     | 
| 
      
 184 
     | 
    
         
            +
                int width, height;    height50,1036
         
     | 
| 
      
 185 
     | 
    
         
            +
                float top, left;    top51,1063
         
     | 
| 
      
 186 
     | 
    
         
            +
                float top, left;    left51,1063
         
     | 
| 
      
 187 
     | 
    
         
            +
                int tname;tname52,1088
         
     | 
| 
      
 188 
     | 
    
         
            +
                float * td_array;td_array53,1103
         
     | 
| 
      
 189 
     | 
    
         
            +
                int yincr, firstpixel;yincr54,1125
         
     | 
| 
      
 190 
     | 
    
         
            +
                int yincr, firstpixel;firstpixel54,1125
         
     | 
| 
      
 191 
     | 
    
         
            +
                int x_offset, y_offset;x_offset55,1152
         
     | 
| 
      
 192 
     | 
    
         
            +
                int x_offset, y_offset;y_offset55,1152
         
     | 
| 
      
 193 
     | 
    
         
            +
                VALUE image;image56,1180
         
     | 
| 
      
 194 
     | 
    
         
            +
            } texture_info;texture_info57,1197
         
     | 
| 
      
 195 
     | 
    
         
            +
            #define IMAGE_BOUNDS(IMAGE_BOUNDS61,1239
         
     | 
| 
      
 196 
     | 
    
         
            +
                int xmin;xmin63,1303
         
     | 
| 
      
 197 
     | 
    
         
            +
                int ymin;ymin64,1317
         
     | 
| 
      
 198 
     | 
    
         
            +
                int xmax;xmax65,1331
         
     | 
| 
      
 199 
     | 
    
         
            +
                int ymax;ymax66,1345
         
     | 
| 
      
 200 
     | 
    
         
            +
            } image_bounds;image_bounds67,1359
         
     | 
| 
      
 201 
     | 
    
         
            +
            typedef struct action_struct {action_struct69,1376
         
     | 
| 
      
 202 
     | 
    
         
            +
                int xmin, ymin, xmax, ymax;xmin70,1407
         
     | 
| 
      
 203 
     | 
    
         
            +
                int xmin, ymin, xmax, ymax;ymin70,1407
         
     | 
| 
      
 204 
     | 
    
         
            +
                int xmin, ymin, xmax, ymax;xmax70,1407
         
     | 
| 
      
 205 
     | 
    
         
            +
                int xmin, ymin, xmax, ymax;ymax70,1407
         
     | 
| 
      
 206 
     | 
    
         
            +
                rgba color;color71,1439
         
     | 
| 
      
 207 
     | 
    
         
            +
                sync sync_mode;sync_mode72,1455
         
     | 
| 
      
 208 
     | 
    
         
            +
                VALUE color_control_proc;color_control_proc75,1504
         
     | 
| 
      
 209 
     | 
    
         
            +
                bool has_color_control_proc;has_color_control_proc76,1534
         
     | 
| 
      
 210 
     | 
    
         
            +
                int color_control_arity;color_control_arity77,1567
         
     | 
| 
      
 211 
     | 
    
         
            +
                texture_info source_tex;source_tex80,1620
         
     | 
| 
      
 212 
     | 
    
         
            +
                bool has_source_texture;has_source_texture81,1649
         
     | 
| 
      
 213 
     | 
    
         
            +
                bool alpha_blend;alpha_blend84,1701
         
     | 
| 
      
 214 
     | 
    
         
            +
                texture_info * tex;tex89,1880
         
     | 
| 
      
 215 
     | 
    
         
            +
                VALUE hash_arg;hash_arg91,1909
         
     | 
| 
      
 216 
     | 
    
         
            +
            } action_struct;action_struct92,1929
         
     | 
| 
      
 217 
     | 
    
         
            +
            
         
     | 
| 
      
 218 
     | 
    
         
            +
            utils.c,4100
         
     | 
| 
      
 219 
     | 
    
         
            +
            static const rgba not_a_color_v = { -1.0, -1.0, -1.0, -1.0 };not_a_color_v36,974
         
     | 
| 
      
 220 
     | 
    
         
            +
            lowercase(char * string) lowercase40,1067
         
     | 
| 
      
 221 
     | 
    
         
            +
            sym2string(VALUE sym) sym2string53,1228
         
     | 
| 
      
 222 
     | 
    
         
            +
            string2sym(char * string) string2sym59,1298
         
     | 
| 
      
 223 
     | 
    
         
            +
            is_a_hash(VALUE try_hash)is_a_hash65,1373
         
     | 
| 
      
 224 
     | 
    
         
            +
            is_an_array(VALUE try_array)is_an_array71,1446
         
     | 
| 
      
 225 
     | 
    
         
            +
            bool is_a_num(VALUE try_num)is_a_num76,1519
         
     | 
| 
      
 226 
     | 
    
         
            +
            get_from_hash(VALUE hash, char * sym) get_from_hash82,1625
         
     | 
| 
      
 227 
     | 
    
         
            +
            set_hash_value(VALUE hash, char * sym, VALUE val)set_hash_value91,1808
         
     | 
| 
      
 228 
     | 
    
         
            +
            delete_from_hash(VALUE hash, char * sym)delete_from_hash101,2016
         
     | 
| 
      
 229 
     | 
    
         
            +
            hash_value_is(VALUE hash, char * sym, VALUE val)hash_value_is111,2295
         
     | 
| 
      
 230 
     | 
    
         
            +
            has_optional_hash_arg(VALUE hash, char * sym) has_optional_hash_arg122,2482
         
     | 
| 
      
 231 
     | 
    
         
            +
            set_array_value(VALUE array, int index, VALUE val)set_array_value134,2710
         
     | 
| 
      
 232 
     | 
    
         
            +
            get_from_array(VALUE array, int index) get_from_array144,2913
         
     | 
| 
      
 233 
     | 
    
         
            +
            init_image_local(VALUE image)init_image_local154,3092
         
     | 
| 
      
 234 
     | 
    
         
            +
            set_image_local(VALUE image, int name, VALUE val)set_image_local173,3553
         
     | 
| 
      
 235 
     | 
    
         
            +
            get_image_local(VALUE image, int name)get_image_local183,3731
         
     | 
| 
      
 236 
     | 
    
         
            +
            convert_image_local_color_to_rgba(VALUE image)convert_image_local_color_to_rgba252,5880
         
     | 
| 
      
 237 
     | 
    
         
            +
            save_rgba_to_image_local_color(VALUE image, rgba color)save_rgba_to_image_local_color266,6319
         
     | 
| 
      
 238 
     | 
    
         
            +
            create_image(VALUE window, int width, int height)create_image283,6877
         
     | 
| 
      
 239 
     | 
    
         
            +
            not_a_color(rgba color1) not_a_color303,7451
         
     | 
| 
      
 240 
     | 
    
         
            +
            is_a_color(rgba color1)is_a_color309,7516
         
     | 
| 
      
 241 
     | 
    
         
            +
            cmp_color(rgba color1, rgba color2) cmp_color315,7583
         
     | 
| 
      
 242 
     | 
    
         
            +
            color_copy(float * source, float * dest) color_copy323,7778
         
     | 
| 
      
 243 
     | 
    
         
            +
            zero_color(float * tex) zero_color330,7908
         
     | 
| 
      
 244 
     | 
    
         
            +
            get_pixel_color_from_chunk(float * chunk, int width, int height, int x, int y)get_pixel_color_from_chunk336,7982
         
     | 
| 
      
 245 
     | 
    
         
            +
            get_pixel_color(texture_info * tex, int x, int y) get_pixel_color357,8429
         
     | 
| 
      
 246 
     | 
    
         
            +
            get_pixel_data(texture_info * tex, int x, int y) get_pixel_data379,9024
         
     | 
| 
      
 247 
     | 
    
         
            +
            set_pixel_color(rgba * pixel_color, texture_info * tex, int x, int y) set_pixel_color388,9204
         
     | 
| 
      
 248 
     | 
    
         
            +
            find_color_from_string(char * try_color) find_color_from_string410,9769
         
     | 
| 
      
 249 
     | 
    
         
            +
            convert_rgba_to_rb_color(rgba * pix)convert_rgba_to_rb_color471,12271
         
     | 
| 
      
 250 
     | 
    
         
            +
            convert_rb_color_to_rgba(VALUE cval)convert_rb_color_to_rgba487,12747
         
     | 
| 
      
 251 
     | 
    
         
            +
            check_mask(VALUE mask) check_mask530,13964
         
     | 
| 
      
 252 
     | 
    
         
            +
            check_image(VALUE image) check_image548,14470
         
     | 
| 
      
 253 
     | 
    
         
            +
            is_gosu_image(VALUE try_image)is_gosu_image555,14634
         
     | 
| 
      
 254 
     | 
    
         
            +
            #define outcode outcode565,14808
         
     | 
| 
      
 255 
     | 
    
         
            +
            const int RIGHT = 8;  //1000RIGHT566,14828
         
     | 
| 
      
 256 
     | 
    
         
            +
            const int TOP = 4;    //0100TOP567,14857
         
     | 
| 
      
 257 
     | 
    
         
            +
            const int LEFT = 2;   //0010LEFT568,14886
         
     | 
| 
      
 258 
     | 
    
         
            +
            const int BOTTOM = 1; //0001BOTTOM569,14915
         
     | 
| 
      
 259 
     | 
    
         
            +
            ComputeOutCode (int x, int y, int xmin, int ymin, int xmax, int ymax)ComputeOutCode574,15083
         
     | 
| 
      
 260 
     | 
    
         
            +
            cohen_sutherland_clip (int * x0, int * y0,int * x1, int * y1, int xmin, int ymin,cohen_sutherland_clip592,15643
         
     | 
| 
      
 261 
     | 
    
         
            +
            constrain_boundaries(int * x0, int * y0, int * x1, int * y1, int width, int height) constrain_boundaries669,18664
         
     | 
| 
      
 262 
     | 
    
         
            +
            bound_by_rect_and_inner(int x, int y, int x0, int y0, int x1, int y1, int inner) bound_by_rect_and_inner692,19249
         
     | 
| 
      
 263 
     | 
    
         
            +
            bound_by_rect(int x, int y, int x0, int y0, int x1, int y1) bound_by_rect701,19577
         
     | 
| 
      
 264 
     | 
    
         
            +
            calc_pixel_offset_for_action(action_struct * cur, texture_info * tex, int x, int y) calc_pixel_offset_for_action708,19783
         
     | 
| 
      
 265 
     | 
    
         
            +
            calc_pixel_offset(texture_info * tex, int x, int y) calc_pixel_offset717,20019
         
     | 
| 
      
 266 
     | 
    
         
            +
            max_quad_size(void)max_quad_size726,20217
         
     | 
| 
      
 267 
     | 
    
         
            +
            check_for_texture_info(VALUE image) check_for_texture_info751,20843
         
     | 
| 
      
 268 
     | 
    
         
            +
            allocate_texture(int width, int height)allocate_texture772,21587
         
     | 
| 
      
 269 
     | 
    
         
            +
            sync_to_gl(int tex_name, int x_offset, int y_offset, int width, int height, void * sub)sync_to_gl787,21894
         
     | 
| 
      
 270 
     | 
    
         
            +
            create_subtexture_and_sync_to_gl(image_bounds * img_bounds, texture_info * tex)create_subtexture_and_sync_to_gl799,22251
         
     | 
| 
      
 271 
     | 
    
         
            +
            get_image_chunk(texture_info * tex, int xmin, int ymin, int xmax, int ymax)get_image_chunk823,23096
         
     | 
| 
      
 272 
     | 
    
         
            +
            get_texture_info(VALUE image, texture_info * tex) get_texture_info852,23802
         
     | 
| 
      
 273 
     | 
    
         
            +
            is_a_point(VALUE try_point)is_a_point897,25165
         
     | 
| 
      
 274 
     | 
    
         
            +
            point_x(VALUE point)point_x907,25380
         
     | 
| 
      
 275 
     | 
    
         
            +
            point_y(VALUE point)point_y913,25461
         
     | 
| 
      
 276 
     | 
    
         
            +
            power(float base, int exp)power920,25598
         
     | 
| 
      
 277 
     | 
    
         
            +
            fact(int n)fact940,25926
         
     | 
| 
      
 278 
     | 
    
         
            +
            comb(int n, int k)comb948,26031
         
     | 
| 
      
 279 
     | 
    
         
            +
            bernstein(int n, int k, float u)bernstein955,26132
         
     | 
| 
      
 280 
     | 
    
         
            +
            
         
     | 
| 
      
 281 
     | 
    
         
            +
            utils.h,201
         
     | 
| 
      
 282 
     | 
    
         
            +
            #define GUARD_UTILS_HGUARD_UTILS_H2,22
         
     | 
| 
      
 283 
     | 
    
         
            +
            #define DRAW_OFFSET DRAW_OFFSET6,102
         
     | 
| 
      
 284 
     | 
    
         
            +
            #define LAZY_BOUNDS LAZY_BOUNDS7,124
         
     | 
| 
      
 285 
     | 
    
         
            +
            #define IMAGE_COLOR IMAGE_COLOR8,146
         
     | 
| 
      
 286 
     | 
    
         
            +
            #define USER_DEFAULTS USER_DEFAULTS9,168
         
     | 
    
        data/src/actions.c
    ADDED
    
    | 
         @@ -0,0 +1,1306 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #include "texplay.h"
         
     | 
| 
      
 2 
     | 
    
         
            +
            #include "utils.h"
         
     | 
| 
      
 3 
     | 
    
         
            +
            #include "actions.h"
         
     | 
| 
      
 4 
     | 
    
         
            +
            #include <assert.h>
         
     | 
| 
      
 5 
     | 
    
         
            +
            #include <math.h>
         
     | 
| 
      
 6 
     | 
    
         
            +
            #ifdef __APPLE__
         
     | 
| 
      
 7 
     | 
    
         
            +
            # include <glut.h>
         
     | 
| 
      
 8 
     | 
    
         
            +
            #else
         
     | 
| 
      
 9 
     | 
    
         
            +
            # include <GL/glut.h>
         
     | 
| 
      
 10 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            /* small helper functions */
         
     | 
| 
      
 14 
     | 
    
         
            +
            static void process_common_hash_args(action_struct * cur, VALUE * hash_arg, sync sync_mode, bool primary);
         
     | 
| 
      
 15 
     | 
    
         
            +
            static void update_bounds(action_struct * cur, int xmin, int ymin, int xmax, int ymax);
         
     | 
| 
      
 16 
     | 
    
         
            +
            static void update_lazy_bounds(action_struct * cur, texture_info * tex);
         
     | 
| 
      
 17 
     | 
    
         
            +
            static void set_local_bounds(action_struct * cur, int xmin, int ymin, int xmax, int ymax, texture_info * tex);
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            static void draw_prologue(action_struct * cur, texture_info * tex,
         
     | 
| 
      
 20 
     | 
    
         
            +
                                      int xmin, int ymin, int xmax, int ymax, VALUE * hash_arg, sync sync_mode,
         
     | 
| 
      
 21 
     | 
    
         
            +
                                      bool primary, action_struct ** payload_ptr);
         
     | 
| 
      
 22 
     | 
    
         
            +
            static void draw_epilogue(action_struct * cur, texture_info * tex, bool primary);
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            static void prepare_fill_texture(action_struct * cur);
         
     | 
| 
      
 25 
     | 
    
         
            +
            static void prepare_color_control(action_struct * cur);
         
     | 
| 
      
 26 
     | 
    
         
            +
            static rgba exec_color_control_proc(action_struct * cur, texture_info * tex, int x, int y);
         
     | 
| 
      
 27 
     | 
    
         
            +
            static void set_pixel_color_with_style(action_struct * payload, texture_info * tex,
         
     | 
| 
      
 28 
     | 
    
         
            +
                                                   int x, int y);
         
     | 
| 
      
 29 
     | 
    
         
            +
            /* end helpers */
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            /** line_do_action, bresenham's algorithm **/
         
     | 
| 
      
 33 
     | 
    
         
            +
            void
         
     | 
| 
      
 34 
     | 
    
         
            +
            line_do_action(int x1, int y1, int x2, int y2, texture_info * tex, VALUE hash_arg,
         
     | 
| 
      
 35 
     | 
    
         
            +
                           sync sync_mode, bool primary, action_struct * payload)
         
     | 
| 
      
 36 
     | 
    
         
            +
            {
         
     | 
| 
      
 37 
     | 
    
         
            +
                int x, y, W, H, F;
         
     | 
| 
      
 38 
     | 
    
         
            +
                int xinc, yinc;
         
     | 
| 
      
 39 
     | 
    
         
            +
                action_struct cur;
         
     | 
| 
      
 40 
     | 
    
         
            +
                int thickness = 1;
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                draw_prologue(&cur, tex, x1, y1,
         
     | 
| 
      
 43 
     | 
    
         
            +
                              x2, y2, &hash_arg, sync_mode, primary, &payload);
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                if(has_optional_hash_arg(hash_arg, "thickness")) 
         
     | 
| 
      
 46 
     | 
    
         
            +
                    thickness = NUM2INT(get_from_hash(hash_arg, "thickness"));
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                /* clip the line */
         
     | 
| 
      
 49 
     | 
    
         
            +
                cohen_sutherland_clip(&x1, &y1, &x2, &y2, 0, 0, tex->width - 1, tex->height - 1);
         
     | 
| 
      
 50 
     | 
    
         
            +
                
         
     | 
| 
      
 51 
     | 
    
         
            +
                W = ABS(x2 - x1);
         
     | 
| 
      
 52 
     | 
    
         
            +
                H = ABS(y2 - y1);
         
     | 
| 
      
 53 
     | 
    
         
            +
                	
         
     | 
| 
      
 54 
     | 
    
         
            +
                if(x1 < x2)
         
     | 
| 
      
 55 
     | 
    
         
            +
                    xinc = 1;
         
     | 
| 
      
 56 
     | 
    
         
            +
                else
         
     | 
| 
      
 57 
     | 
    
         
            +
                    xinc = -1;
         
     | 
| 
      
 58 
     | 
    
         
            +
            		
         
     | 
| 
      
 59 
     | 
    
         
            +
                if(y1 < y2)
         
     | 
| 
      
 60 
     | 
    
         
            +
                    yinc = 1;
         
     | 
| 
      
 61 
     | 
    
         
            +
                else
         
     | 
| 
      
 62 
     | 
    
         
            +
                    yinc = -1;
         
     | 
| 
      
 63 
     | 
    
         
            +
            		
         
     | 
| 
      
 64 
     | 
    
         
            +
                x = x1;
         
     | 
| 
      
 65 
     | 
    
         
            +
                y = y1;
         
     | 
| 
      
 66 
     | 
    
         
            +
            	
         
     | 
| 
      
 67 
     | 
    
         
            +
                if(W >= H) {
         
     | 
| 
      
 68 
     | 
    
         
            +
                    F = 2 * H - W;
         
     | 
| 
      
 69 
     | 
    
         
            +
                    while(x != x2) {
         
     | 
| 
      
 70 
     | 
    
         
            +
                        if(F < 0)
         
     | 
| 
      
 71 
     | 
    
         
            +
                            F += 2 * H;
         
     | 
| 
      
 72 
     | 
    
         
            +
                        else {
         
     | 
| 
      
 73 
     | 
    
         
            +
                            F += 2 * (H - W);
         
     | 
| 
      
 74 
     | 
    
         
            +
                            y += yinc;
         
     | 
| 
      
 75 
     | 
    
         
            +
                        }
         
     | 
| 
      
 76 
     | 
    
         
            +
                        x += xinc;
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                        if(thickness <= 1) {
         
     | 
| 
      
 79 
     | 
    
         
            +
                            set_pixel_color_with_style(payload, tex, x, y);
         
     | 
| 
      
 80 
     | 
    
         
            +
                        }
         
     | 
| 
      
 81 
     | 
    
         
            +
                        else {
         
     | 
| 
      
 82 
     | 
    
         
            +
                            set_hash_value(hash_arg, "fill", Qtrue);
         
     | 
| 
      
 83 
     | 
    
         
            +
                            circle_do_action(x, y, thickness / 2, tex, hash_arg, no_sync, false, payload);
         
     | 
| 
      
 84 
     | 
    
         
            +
                        }
         
     | 
| 
      
 85 
     | 
    
         
            +
                    }
         
     | 
| 
      
 86 
     | 
    
         
            +
                }
         
     | 
| 
      
 87 
     | 
    
         
            +
                else {
         
     | 
| 
      
 88 
     | 
    
         
            +
                    F = 2 * W - H;
         
     | 
| 
      
 89 
     | 
    
         
            +
                    while(y != y2 ) {
         
     | 
| 
      
 90 
     | 
    
         
            +
                        if(F < 0)
         
     | 
| 
      
 91 
     | 
    
         
            +
                            F += 2 * W;
         
     | 
| 
      
 92 
     | 
    
         
            +
                        else {
         
     | 
| 
      
 93 
     | 
    
         
            +
                            F += 2 * (W - H);
         
     | 
| 
      
 94 
     | 
    
         
            +
                            x += xinc;
         
     | 
| 
      
 95 
     | 
    
         
            +
                        }
         
     | 
| 
      
 96 
     | 
    
         
            +
                        y += yinc;
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
                        if(thickness <= 1) {
         
     | 
| 
      
 99 
     | 
    
         
            +
                            set_pixel_color_with_style(payload, tex, x, y);
         
     | 
| 
      
 100 
     | 
    
         
            +
                        }
         
     | 
| 
      
 101 
     | 
    
         
            +
                        else {
         
     | 
| 
      
 102 
     | 
    
         
            +
                            set_hash_value(hash_arg, "fill", Qtrue);
         
     | 
| 
      
 103 
     | 
    
         
            +
                            circle_do_action(x, y, thickness / 2, tex, hash_arg, no_sync, false, payload);
         
     | 
| 
      
 104 
     | 
    
         
            +
                        }
         
     | 
| 
      
 105 
     | 
    
         
            +
                        
         
     | 
| 
      
 106 
     | 
    
         
            +
                    }
         
     | 
| 
      
 107 
     | 
    
         
            +
                }
         
     | 
| 
      
 108 
     | 
    
         
            +
            			
         
     | 
| 
      
 109 
     | 
    
         
            +
                draw_epilogue(&cur, tex, primary);
         
     | 
| 
      
 110 
     | 
    
         
            +
            }
         
     | 
| 
      
 111 
     | 
    
         
            +
            /** end line **/
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
            /** polyline algorithm **/
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
            /* used by both polyline and bezier */
         
     | 
| 
      
 116 
     | 
    
         
            +
            #define SIMPLE_FORMAT 0
         
     | 
| 
      
 117 
     | 
    
         
            +
            #define POINT_FORMAT 1
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
            /* calculate a single point */
         
     | 
| 
      
 120 
     | 
    
         
            +
            static void
         
     | 
| 
      
 121 
     | 
    
         
            +
            polyline_point(VALUE points, int k, int * x, int * y, int format, int draw_offset_x,
         
     | 
| 
      
 122 
     | 
    
         
            +
                           int draw_offset_y)
         
     | 
| 
      
 123 
     | 
    
         
            +
            {
         
     | 
| 
      
 124 
     | 
    
         
            +
                int xy_index;
         
     | 
| 
      
 125 
     | 
    
         
            +
                
         
     | 
| 
      
 126 
     | 
    
         
            +
                switch(format) {
         
     | 
| 
      
 127 
     | 
    
         
            +
                case POINT_FORMAT:
         
     | 
| 
      
 128 
     | 
    
         
            +
                    *x = NUM2INT(point_x(get_from_array(points, k))) + draw_offset_x;
         
     | 
| 
      
 129 
     | 
    
         
            +
                    *y = NUM2INT(point_y(get_from_array(points, k))) + draw_offset_y;
         
     | 
| 
      
 130 
     | 
    
         
            +
                    break;
         
     | 
| 
      
 131 
     | 
    
         
            +
                    
         
     | 
| 
      
 132 
     | 
    
         
            +
                case SIMPLE_FORMAT:
         
     | 
| 
      
 133 
     | 
    
         
            +
                    xy_index = k * 2;
         
     | 
| 
      
 134 
     | 
    
         
            +
                    *x = NUM2INT(get_from_array(points, xy_index)) + draw_offset_x;
         
     | 
| 
      
 135 
     | 
    
         
            +
                    *y = NUM2INT(get_from_array(points, xy_index + 1)) + draw_offset_y;
         
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
      
 137 
     | 
    
         
            +
                    break;
         
     | 
| 
      
 138 
     | 
    
         
            +
                default:
         
     | 
| 
      
 139 
     | 
    
         
            +
                    rb_raise(rb_eArgError, "pixel format must be either POINT_FORMAT or SIMPLE_FORMAT");
         
     | 
| 
      
 140 
     | 
    
         
            +
                }
         
     | 
| 
      
 141 
     | 
    
         
            +
            }
         
     | 
| 
      
 142 
     | 
    
         
            +
                    
         
     | 
| 
      
 143 
     | 
    
         
            +
            void
         
     | 
| 
      
 144 
     | 
    
         
            +
            polyline_do_action(VALUE points, texture_info * tex, VALUE hash_arg,
         
     | 
| 
      
 145 
     | 
    
         
            +
                               sync sync_mode, bool primary, action_struct * payload)
         
     | 
| 
      
 146 
     | 
    
         
            +
            {
         
     | 
| 
      
 147 
     | 
    
         
            +
                action_struct cur;
         
     | 
| 
      
 148 
     | 
    
         
            +
                int x1, y1, x2, y2;
         
     | 
| 
      
 149 
     | 
    
         
            +
                int format;
         
     | 
| 
      
 150 
     | 
    
         
            +
                int num_point_pairs;
         
     | 
| 
      
 151 
     | 
    
         
            +
                int k;
         
     | 
| 
      
 152 
     | 
    
         
            +
                VALUE offset_val;
         
     | 
| 
      
 153 
     | 
    
         
            +
                int draw_offset_x;
         
     | 
| 
      
 154 
     | 
    
         
            +
                int draw_offset_y;
         
     | 
| 
      
 155 
     | 
    
         
            +
                bool closed = false;
         
     | 
| 
      
 156 
     | 
    
         
            +
                
         
     | 
| 
      
 157 
     | 
    
         
            +
                draw_prologue(&cur, tex, XMAX_OOB, YMAX_OOB, XMIN_OOB, YMIN_OOB, &hash_arg, sync_mode, primary, &payload);
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
                /* calculate offset */
         
     | 
| 
      
 160 
     | 
    
         
            +
                offset_val = get_image_local(tex->image, DRAW_OFFSET);
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
      
 162 
     | 
    
         
            +
                draw_offset_x = NUM2INT(get_from_array(offset_val, 0));
         
     | 
| 
      
 163 
     | 
    
         
            +
                draw_offset_y = NUM2INT(get_from_array(offset_val, 1));
         
     | 
| 
      
 164 
     | 
    
         
            +
             
     | 
| 
      
 165 
     | 
    
         
            +
                /* if the polyline is 'closed' make the last point the first */
         
     | 
| 
      
 166 
     | 
    
         
            +
                if(is_a_hash(hash_arg))
         
     | 
| 
      
 167 
     | 
    
         
            +
                    if(RTEST(get_from_hash(hash_arg, "closed")) || RTEST(get_from_hash(hash_arg, "close"))) {
         
     | 
| 
      
 168 
     | 
    
         
            +
                        
         
     | 
| 
      
 169 
     | 
    
         
            +
                        /* so that our additional point is not persistent */
         
     | 
| 
      
 170 
     | 
    
         
            +
                        points = rb_obj_dup(points);
         
     | 
| 
      
 171 
     | 
    
         
            +
                        closed = true;
         
     | 
| 
      
 172 
     | 
    
         
            +
                    }
         
     | 
| 
      
 173 
     | 
    
         
            +
                /* determine format of points */
         
     | 
| 
      
 174 
     | 
    
         
            +
                if(is_a_point(get_from_array(points, 0))) {
         
     | 
| 
      
 175 
     | 
    
         
            +
                    format = POINT_FORMAT;
         
     | 
| 
      
 176 
     | 
    
         
            +
             
     | 
| 
      
 177 
     | 
    
         
            +
                    /* if the polyline is closed to form a polygon then make the last point and first point identical */
         
     | 
| 
      
 178 
     | 
    
         
            +
                    if(closed)
         
     | 
| 
      
 179 
     | 
    
         
            +
                        rb_ary_push(points, get_from_array(points, 0));
         
     | 
| 
      
 180 
     | 
    
         
            +
             
     | 
| 
      
 181 
     | 
    
         
            +
                    num_point_pairs = RARRAY_LEN(points);
         
     | 
| 
      
 182 
     | 
    
         
            +
                }
         
     | 
| 
      
 183 
     | 
    
         
            +
                else {
         
     | 
| 
      
 184 
     | 
    
         
            +
                    format = SIMPLE_FORMAT;
         
     | 
| 
      
 185 
     | 
    
         
            +
             
     | 
| 
      
 186 
     | 
    
         
            +
                    /* ensure there is an 'x' for every 'y'  */
         
     | 
| 
      
 187 
     | 
    
         
            +
                    if(RARRAY_LEN(points) % 2)
         
     | 
| 
      
 188 
     | 
    
         
            +
                        rb_raise(rb_eArgError, "polyline needs an even number of points. got %d\n",
         
     | 
| 
      
 189 
     | 
    
         
            +
                                 (int)RARRAY_LEN(points));
         
     | 
| 
      
 190 
     | 
    
         
            +
             
     | 
| 
      
 191 
     | 
    
         
            +
                    if(closed) {
         
     | 
| 
      
 192 
     | 
    
         
            +
                        rb_ary_push(points, get_from_array(points, 0));
         
     | 
| 
      
 193 
     | 
    
         
            +
                        rb_ary_push(points, get_from_array(points, 1));
         
     | 
| 
      
 194 
     | 
    
         
            +
                    }
         
     | 
| 
      
 195 
     | 
    
         
            +
             
     | 
| 
      
 196 
     | 
    
         
            +
                    num_point_pairs = RARRAY_LEN(points) / 2;
         
     | 
| 
      
 197 
     | 
    
         
            +
                }
         
     | 
| 
      
 198 
     | 
    
         
            +
             
     | 
| 
      
 199 
     | 
    
         
            +
                /* calculate first point */
         
     | 
| 
      
 200 
     | 
    
         
            +
                polyline_point(points, 0, &x1, &y1, format, draw_offset_x, draw_offset_y);
         
     | 
| 
      
 201 
     | 
    
         
            +
                
         
     | 
| 
      
 202 
     | 
    
         
            +
                /* calc the points and draw the polyline */
         
     | 
| 
      
 203 
     | 
    
         
            +
                for(k = 1; k < num_point_pairs; k++) {
         
     | 
| 
      
 204 
     | 
    
         
            +
             
     | 
| 
      
 205 
     | 
    
         
            +
                    polyline_point(points, k, &x2, &y2, format, draw_offset_x, draw_offset_y);
         
     | 
| 
      
 206 
     | 
    
         
            +
                
         
     | 
| 
      
 207 
     | 
    
         
            +
                    line_do_action(x1, y1, x2, y2, tex, hash_arg, no_sync, false, payload);
         
     | 
| 
      
 208 
     | 
    
         
            +
             
     | 
| 
      
 209 
     | 
    
         
            +
                    /* update drawing rectangle */
         
     | 
| 
      
 210 
     | 
    
         
            +
                    update_bounds(payload, x1, y1, x2, y2);
         
     | 
| 
      
 211 
     | 
    
         
            +
                    
         
     | 
| 
      
 212 
     | 
    
         
            +
                    x1 = x2; y1 = y2;
         
     | 
| 
      
 213 
     | 
    
         
            +
                }
         
     | 
| 
      
 214 
     | 
    
         
            +
                
         
     | 
| 
      
 215 
     | 
    
         
            +
                draw_epilogue(&cur, tex, primary);
         
     | 
| 
      
 216 
     | 
    
         
            +
            }
         
     | 
| 
      
 217 
     | 
    
         
            +
            /** end polyline **/
         
     | 
| 
      
 218 
     | 
    
         
            +
             
     | 
| 
      
 219 
     | 
    
         
            +
            /* regular polygon algorithm */
         
     | 
| 
      
 220 
     | 
    
         
            +
            void
         
     | 
| 
      
 221 
     | 
    
         
            +
            ngon_do_action(int x, int y, int r, int num_sides, texture_info * tex, VALUE hash_arg,
         
     | 
| 
      
 222 
     | 
    
         
            +
                           sync sync_mode, bool primary, action_struct * payload)
         
     | 
| 
      
 223 
     | 
    
         
            +
            {
         
     | 
| 
      
 224 
     | 
    
         
            +
                action_struct cur;
         
     | 
| 
      
 225 
     | 
    
         
            +
                int x1, y1, x2, y2, x0, y0;
         
     | 
| 
      
 226 
     | 
    
         
            +
                int n;
         
     | 
| 
      
 227 
     | 
    
         
            +
                int thickness;
         
     | 
| 
      
 228 
     | 
    
         
            +
             
     | 
| 
      
 229 
     | 
    
         
            +
                draw_prologue(&cur, tex, x - r, y - r,
         
     | 
| 
      
 230 
     | 
    
         
            +
                              x + r, y + r, &hash_arg, sync_mode, primary, &payload);
         
     | 
| 
      
 231 
     | 
    
         
            +
             
     | 
| 
      
 232 
     | 
    
         
            +
             
     | 
| 
      
 233 
     | 
    
         
            +
                if(is_a_hash(hash_arg))
         
     | 
| 
      
 234 
     | 
    
         
            +
                    if(RTEST(get_from_hash(hash_arg, "thickness"))) {
         
     | 
| 
      
 235 
     | 
    
         
            +
                        thickness = NUM2INT(get_from_hash(hash_arg, "thickness"));
         
     | 
| 
      
 236 
     | 
    
         
            +
             
     | 
| 
      
 237 
     | 
    
         
            +
                        /* TO DO: find a better way of doing this */
         
     | 
| 
      
 238 
     | 
    
         
            +
                        cur.xmin = x - r - thickness / 2;
         
     | 
| 
      
 239 
     | 
    
         
            +
                        cur.ymin = y - r - thickness / 2;
         
     | 
| 
      
 240 
     | 
    
         
            +
                        cur.xmax = x + r + thickness / 2;
         
     | 
| 
      
 241 
     | 
    
         
            +
                        cur.ymax = y + r + thickness / 2;
         
     | 
| 
      
 242 
     | 
    
         
            +
                    }
         
     | 
| 
      
 243 
     | 
    
         
            +
             
     | 
| 
      
 244 
     | 
    
         
            +
                /* calculate first point */
         
     | 
| 
      
 245 
     | 
    
         
            +
                x0 = x1 = x + r;
         
     | 
| 
      
 246 
     | 
    
         
            +
                y0 = y1 = y;
         
     | 
| 
      
 247 
     | 
    
         
            +
             
     | 
| 
      
 248 
     | 
    
         
            +
                for(n = 0; n < num_sides; n++) {
         
     | 
| 
      
 249 
     | 
    
         
            +
                    x2 = x + r * cos((2 * PI / num_sides) * n);
         
     | 
| 
      
 250 
     | 
    
         
            +
                    y2 = y + r * sin((2 * PI / num_sides) * n);
         
     | 
| 
      
 251 
     | 
    
         
            +
             
     | 
| 
      
 252 
     | 
    
         
            +
                    line_do_action(x1, y1, x2, y2, tex, hash_arg, no_sync, false, payload);
         
     | 
| 
      
 253 
     | 
    
         
            +
             
     | 
| 
      
 254 
     | 
    
         
            +
                    x1 = x2; y1 = y2;
         
     | 
| 
      
 255 
     | 
    
         
            +
                }
         
     | 
| 
      
 256 
     | 
    
         
            +
             
     | 
| 
      
 257 
     | 
    
         
            +
                line_do_action(x0, y0, x1, y1, tex, hash_arg, no_sync, false, payload);
         
     | 
| 
      
 258 
     | 
    
         
            +
             
     | 
| 
      
 259 
     | 
    
         
            +
                draw_epilogue(&cur, tex, primary);
         
     | 
| 
      
 260 
     | 
    
         
            +
            }
         
     | 
| 
      
 261 
     | 
    
         
            +
            /** end of ngon */    
         
     | 
| 
      
 262 
     | 
    
         
            +
             
     | 
| 
      
 263 
     | 
    
         
            +
            /** rectangle algorithm **/
         
     | 
| 
      
 264 
     | 
    
         
            +
            void
         
     | 
| 
      
 265 
     | 
    
         
            +
            rect_do_action(int x1, int y1, int x2, int y2, texture_info * tex, VALUE hash_arg,
         
     | 
| 
      
 266 
     | 
    
         
            +
                           sync sync_mode, bool primary, action_struct * payload)
         
     | 
| 
      
 267 
     | 
    
         
            +
            {
         
     | 
| 
      
 268 
     | 
    
         
            +
                action_struct cur;
         
     | 
| 
      
 269 
     | 
    
         
            +
                bool fill = false;
         
     | 
| 
      
 270 
     | 
    
         
            +
                int thickness = 1;
         
     | 
| 
      
 271 
     | 
    
         
            +
             
     | 
| 
      
 272 
     | 
    
         
            +
                draw_prologue(&cur, tex, x1, y1,
         
     | 
| 
      
 273 
     | 
    
         
            +
                              x2, y2, &hash_arg, sync_mode, primary, &payload);
         
     | 
| 
      
 274 
     | 
    
         
            +
             
     | 
| 
      
 275 
     | 
    
         
            +
                
         
     | 
| 
      
 276 
     | 
    
         
            +
                if(is_a_hash(hash_arg)) {
         
     | 
| 
      
 277 
     | 
    
         
            +
             
     | 
| 
      
 278 
     | 
    
         
            +
                    /* make our private copy of the hash so we can mess with it */
         
     | 
| 
      
 279 
     | 
    
         
            +
                    hash_arg = rb_obj_dup(hash_arg);
         
     | 
| 
      
 280 
     | 
    
         
            +
             
     | 
| 
      
 281 
     | 
    
         
            +
                    if(RTEST(get_from_hash(hash_arg, "fill")) || RTEST(get_from_hash(hash_arg, "filled"))) {
         
     | 
| 
      
 282 
     | 
    
         
            +
                        fill = true;
         
     | 
| 
      
 283 
     | 
    
         
            +
             
     | 
| 
      
 284 
     | 
    
         
            +
                        /* since we're filling the rect, line thickness is irrelevant */
         
     | 
| 
      
 285 
     | 
    
         
            +
                        delete_from_hash(hash_arg, "thickness");
         
     | 
| 
      
 286 
     | 
    
         
            +
                    }
         
     | 
| 
      
 287 
     | 
    
         
            +
                    else if(RTEST(get_from_hash(hash_arg, "thickness"))) {
         
     | 
| 
      
 288 
     | 
    
         
            +
                        thickness = NUM2INT(get_from_hash(hash_arg, "thickness"));
         
     | 
| 
      
 289 
     | 
    
         
            +
                        /* TO DO: find a better way of doing this */
         
     | 
| 
      
 290 
     | 
    
         
            +
             
     | 
| 
      
 291 
     | 
    
         
            +
                        if(thickness > 1) {
         
     | 
| 
      
 292 
     | 
    
         
            +
                            cur.xmin = x1 - thickness / 2;
         
     | 
| 
      
 293 
     | 
    
         
            +
                            cur.ymin = y1 - thickness / 2;
         
     | 
| 
      
 294 
     | 
    
         
            +
                            cur.xmax = x2 + thickness / 2 + 1;
         
     | 
| 
      
 295 
     | 
    
         
            +
                            cur.ymax = y2 + thickness / 2 + 1;
         
     | 
| 
      
 296 
     | 
    
         
            +
                        }
         
     | 
| 
      
 297 
     | 
    
         
            +
                    }
         
     | 
| 
      
 298 
     | 
    
         
            +
                }
         
     | 
| 
      
 299 
     | 
    
         
            +
                if(!fill) {
         
     | 
| 
      
 300 
     | 
    
         
            +
                    line_do_action(x1, y1, x2, y1, tex, hash_arg, no_sync, false, payload);
         
     | 
| 
      
 301 
     | 
    
         
            +
                    line_do_action(x1, y1, x1, y2, tex, hash_arg, no_sync, false, payload);
         
     | 
| 
      
 302 
     | 
    
         
            +
                    line_do_action(x1, y2, x2, y2, tex, hash_arg, no_sync, false, payload);
         
     | 
| 
      
 303 
     | 
    
         
            +
                    line_do_action(x2, y1, x2, y2, tex, hash_arg, no_sync, false, payload);
         
     | 
| 
      
 304 
     | 
    
         
            +
                }
         
     | 
| 
      
 305 
     | 
    
         
            +
                else {
         
     | 
| 
      
 306 
     | 
    
         
            +
                    int y;
         
     | 
| 
      
 307 
     | 
    
         
            +
                    if(y1 > y2) SWAP(y1, y2);
         
     | 
| 
      
 308 
     | 
    
         
            +
             
     | 
| 
      
 309 
     | 
    
         
            +
                    for(y = y1; y < y2; y++)
         
     | 
| 
      
 310 
     | 
    
         
            +
                        line_do_action(x1, y, x2, y, tex, hash_arg, no_sync, false, payload);
         
     | 
| 
      
 311 
     | 
    
         
            +
                }
         
     | 
| 
      
 312 
     | 
    
         
            +
             
     | 
| 
      
 313 
     | 
    
         
            +
                draw_epilogue(&cur, tex, primary);
         
     | 
| 
      
 314 
     | 
    
         
            +
            }
         
     | 
| 
      
 315 
     | 
    
         
            +
             
     | 
| 
      
 316 
     | 
    
         
            +
             
     | 
| 
      
 317 
     | 
    
         
            +
            /** midpoint circle algorithm **/
         
     | 
| 
      
 318 
     | 
    
         
            +
            void
         
     | 
| 
      
 319 
     | 
    
         
            +
            circle_do_action(int x1, int y1, int r, texture_info * tex, VALUE hash_arg,
         
     | 
| 
      
 320 
     | 
    
         
            +
                             sync sync_mode, bool primary, action_struct * payload)
         
     | 
| 
      
 321 
     | 
    
         
            +
            {
         
     | 
| 
      
 322 
     | 
    
         
            +
             
     | 
| 
      
 323 
     | 
    
         
            +
                int x, y;
         
     | 
| 
      
 324 
     | 
    
         
            +
                float p;
         
     | 
| 
      
 325 
     | 
    
         
            +
                action_struct cur;
         
     | 
| 
      
 326 
     | 
    
         
            +
                bool fill = false;
         
     | 
| 
      
 327 
     | 
    
         
            +
             
     | 
| 
      
 328 
     | 
    
         
            +
                draw_prologue(&cur, tex, x1 - r, y1 - r, x1 + r, y1 + r, &hash_arg,
         
     | 
| 
      
 329 
     | 
    
         
            +
                              sync_mode, primary, &payload);
         
     | 
| 
      
 330 
     | 
    
         
            +
             
     | 
| 
      
 331 
     | 
    
         
            +
             
     | 
| 
      
 332 
     | 
    
         
            +
                if(is_a_hash(hash_arg)) {
         
     | 
| 
      
 333 
     | 
    
         
            +
             
     | 
| 
      
 334 
     | 
    
         
            +
                    /* make our private copy of the hash so we can mess with it */
         
     | 
| 
      
 335 
     | 
    
         
            +
                    hash_arg = rb_obj_dup(hash_arg);
         
     | 
| 
      
 336 
     | 
    
         
            +
             
     | 
| 
      
 337 
     | 
    
         
            +
                    if(RTEST(get_from_hash(hash_arg, "fill")) || RTEST(get_from_hash(hash_arg, "filled"))) {
         
     | 
| 
      
 338 
     | 
    
         
            +
                        fill = true;
         
     | 
| 
      
 339 
     | 
    
         
            +
             
     | 
| 
      
 340 
     | 
    
         
            +
                        /* to prevent infinite recursion set line thickness to 1 :D
         
     | 
| 
      
 341 
     | 
    
         
            +
                           NB: a filled circle uses lines and a thick line uses filled circles :D */
         
     | 
| 
      
 342 
     | 
    
         
            +
                        delete_from_hash(hash_arg, "thickness");
         
     | 
| 
      
 343 
     | 
    
         
            +
                    }
         
     | 
| 
      
 344 
     | 
    
         
            +
                }
         
     | 
| 
      
 345 
     | 
    
         
            +
                
         
     | 
| 
      
 346 
     | 
    
         
            +
                x = 0 ; y = r;
         
     | 
| 
      
 347 
     | 
    
         
            +
                p = 5 / 4 - r;
         
     | 
| 
      
 348 
     | 
    
         
            +
                if(!fill) {
         
     | 
| 
      
 349 
     | 
    
         
            +
                    while (x <= y) {
         
     | 
| 
      
 350 
     | 
    
         
            +
                        set_pixel_color_with_style(payload, tex, x1 + x, y1 + y);
         
     | 
| 
      
 351 
     | 
    
         
            +
                        set_pixel_color_with_style(payload, tex, x1 + x, y1 - y);
         
     | 
| 
      
 352 
     | 
    
         
            +
                        set_pixel_color_with_style(payload, tex, x1 - x, y1 + y);
         
     | 
| 
      
 353 
     | 
    
         
            +
                        set_pixel_color_with_style(payload, tex, x1 - x, y1 - y);
         
     | 
| 
      
 354 
     | 
    
         
            +
                        set_pixel_color_with_style(payload, tex, x1 + y, y1 + x);
         
     | 
| 
      
 355 
     | 
    
         
            +
                        set_pixel_color_with_style(payload, tex, x1 + y, y1 - x);
         
     | 
| 
      
 356 
     | 
    
         
            +
                        set_pixel_color_with_style(payload, tex, x1 - y, y1 + x);
         
     | 
| 
      
 357 
     | 
    
         
            +
                        set_pixel_color_with_style(payload, tex, x1 - y, y1 - x);
         
     | 
| 
      
 358 
     | 
    
         
            +
             
     | 
| 
      
 359 
     | 
    
         
            +
                        if (p < 0) {
         
     | 
| 
      
 360 
     | 
    
         
            +
                            p += 2 * x + 3;
         
     | 
| 
      
 361 
     | 
    
         
            +
                        }
         
     | 
| 
      
 362 
     | 
    
         
            +
                        else {
         
     | 
| 
      
 363 
     | 
    
         
            +
                            y--;
         
     | 
| 
      
 364 
     | 
    
         
            +
                            p += 2 * (x - y) + 5;
         
     | 
| 
      
 365 
     | 
    
         
            +
                        }
         
     | 
| 
      
 366 
     | 
    
         
            +
                        x++;
         
     | 
| 
      
 367 
     | 
    
         
            +
                    }
         
     | 
| 
      
 368 
     | 
    
         
            +
                }
         
     | 
| 
      
 369 
     | 
    
         
            +
                else {
         
     | 
| 
      
 370 
     | 
    
         
            +
                    while (x <= y) {
         
     | 
| 
      
 371 
     | 
    
         
            +
                        line_do_action(x1 - x, y1 + y, x1 + x, y1 + y, tex, hash_arg, no_sync, false, payload);
         
     | 
| 
      
 372 
     | 
    
         
            +
                        line_do_action(x1 - x, y1 - y, x1 + x, y1 - y, tex, hash_arg, no_sync, false, payload);
         
     | 
| 
      
 373 
     | 
    
         
            +
                        line_do_action(x1 - y, y1 + x, x1 + y, y1 + x, tex, hash_arg, no_sync, false, payload);
         
     | 
| 
      
 374 
     | 
    
         
            +
                        line_do_action(x1 - y, y1 - x, x1 + y, y1 - x, tex, hash_arg, no_sync, false, payload);
         
     | 
| 
      
 375 
     | 
    
         
            +
             
     | 
| 
      
 376 
     | 
    
         
            +
                        if (p < 0) {
         
     | 
| 
      
 377 
     | 
    
         
            +
                            p += 2 * x + 3;
         
     | 
| 
      
 378 
     | 
    
         
            +
                        }
         
     | 
| 
      
 379 
     | 
    
         
            +
                        else {
         
     | 
| 
      
 380 
     | 
    
         
            +
                            y--;
         
     | 
| 
      
 381 
     | 
    
         
            +
                            p += 2 * (x - y) + 5;
         
     | 
| 
      
 382 
     | 
    
         
            +
                        }
         
     | 
| 
      
 383 
     | 
    
         
            +
                        x++;
         
     | 
| 
      
 384 
     | 
    
         
            +
                    }
         
     | 
| 
      
 385 
     | 
    
         
            +
                }
         
     | 
| 
      
 386 
     | 
    
         
            +
             
     | 
| 
      
 387 
     | 
    
         
            +
                draw_epilogue(&cur, tex, primary);
         
     | 
| 
      
 388 
     | 
    
         
            +
            }
         
     | 
| 
      
 389 
     | 
    
         
            +
            /** end circle **/
         
     | 
| 
      
 390 
     | 
    
         
            +
             
     | 
| 
      
 391 
     | 
    
         
            +
            /** set pixel  algorithm **/
         
     | 
| 
      
 392 
     | 
    
         
            +
            void
         
     | 
| 
      
 393 
     | 
    
         
            +
            pixel_do_action(int x1, int y1, texture_info * tex, VALUE hash_arg,
         
     | 
| 
      
 394 
     | 
    
         
            +
                            sync sync_mode, bool primary, action_struct * payload)
         
     | 
| 
      
 395 
     | 
    
         
            +
            {
         
     | 
| 
      
 396 
     | 
    
         
            +
                action_struct cur;
         
     | 
| 
      
 397 
     | 
    
         
            +
             
     | 
| 
      
 398 
     | 
    
         
            +
                draw_prologue(&cur, tex, x1, y1, x1, y1, &hash_arg, sync_mode, primary, &payload);
         
     | 
| 
      
 399 
     | 
    
         
            +
             
     | 
| 
      
 400 
     | 
    
         
            +
                set_pixel_color_with_style(payload, tex, x1, y1);
         
     | 
| 
      
 401 
     | 
    
         
            +
             
     | 
| 
      
 402 
     | 
    
         
            +
                draw_epilogue(&cur, tex, primary);
         
     | 
| 
      
 403 
     | 
    
         
            +
            }
         
     | 
| 
      
 404 
     | 
    
         
            +
            /** end set pixel **/
         
     | 
| 
      
 405 
     | 
    
         
            +
             
     | 
| 
      
 406 
     | 
    
         
            +
            /*** non recursive FLOOD FILL, inspired by John R. Shaw ***/
         
     | 
| 
      
 407 
     | 
    
         
            +
            typedef struct { int x1, x2, y, dy; } LINESEGMENT;
         
     | 
| 
      
 408 
     | 
    
         
            +
             
     | 
| 
      
 409 
     | 
    
         
            +
            #define MAXDEPTH 10000
         
     | 
| 
      
 410 
     | 
    
         
            +
             
     | 
| 
      
 411 
     | 
    
         
            +
            #define PUSH(XL, XR, Y, DY)                                             \
         
     | 
| 
      
 412 
     | 
    
         
            +
                if( sp < stack+MAXDEPTH && Y+(DY) >= nMinX && Y+(DY) <= nMaxY )     \
         
     | 
| 
      
 413 
     | 
    
         
            +
                    { sp->x1 = XL; sp->x2 = XR; sp->y = Y; sp->dy = DY; ++sp; }
         
     | 
| 
      
 414 
     | 
    
         
            +
             
     | 
| 
      
 415 
     | 
    
         
            +
            #define POP(XL, XR, Y, DY)                                              \
         
     | 
| 
      
 416 
     | 
    
         
            +
                { --sp; XL = sp->x1; XR = sp->x2; Y = sp->y+(DY = sp->dy); }
         
     | 
| 
      
 417 
     | 
    
         
            +
             
     | 
| 
      
 418 
     | 
    
         
            +
            void
         
     | 
| 
      
 419 
     | 
    
         
            +
            flood_fill_do_action(int x, int y, texture_info * tex, VALUE hash_arg,
         
     | 
| 
      
 420 
     | 
    
         
            +
                                 sync sync_mode, bool primary, action_struct * payload)
         
     | 
| 
      
 421 
     | 
    
         
            +
            {
         
     | 
| 
      
 422 
     | 
    
         
            +
                int left, x1, x2, dy;
         
     | 
| 
      
 423 
     | 
    
         
            +
                rgba old_color;
         
     | 
| 
      
 424 
     | 
    
         
            +
                LINESEGMENT stack[MAXDEPTH], *sp = stack;
         
     | 
| 
      
 425 
     | 
    
         
            +
             
     | 
| 
      
 426 
     | 
    
         
            +
                action_struct cur;
         
     | 
| 
      
 427 
     | 
    
         
            +
             
     | 
| 
      
 428 
     | 
    
         
            +
                int nMinX, nMinY, nMaxX, nMaxY;
         
     | 
| 
      
 429 
     | 
    
         
            +
                
         
     | 
| 
      
 430 
     | 
    
         
            +
                /* NOTE: 1024 is just a place-holder to indicate maximum possible width/height.
         
     | 
| 
      
 431 
     | 
    
         
            +
                   Values will be constrained to realistic dimensions by constrain_boundaries() function */
         
     | 
| 
      
 432 
     | 
    
         
            +
                draw_prologue(&cur, tex, 0, 0, 1024, 1024, &hash_arg, sync_mode, primary, &payload);
         
     | 
| 
      
 433 
     | 
    
         
            +
             
     | 
| 
      
 434 
     | 
    
         
            +
                /* fill hates alpha_blend so let's turn it off */
         
     | 
| 
      
 435 
     | 
    
         
            +
                payload->pen.alpha_blend = false;
         
     | 
| 
      
 436 
     | 
    
         
            +
             
     | 
| 
      
 437 
     | 
    
         
            +
                nMinX = cur.xmin; nMinY = cur.ymin;
         
     | 
| 
      
 438 
     | 
    
         
            +
                nMaxX = cur.xmax; nMaxY = cur.ymax;
         
     | 
| 
      
 439 
     | 
    
         
            +
             
     | 
| 
      
 440 
     | 
    
         
            +
                old_color = get_pixel_color(tex, x, y);
         
     | 
| 
      
 441 
     | 
    
         
            +
                if( cmp_color(old_color, cur.color) )
         
     | 
| 
      
 442 
     | 
    
         
            +
                    return;
         
     | 
| 
      
 443 
     | 
    
         
            +
             
     | 
| 
      
 444 
     | 
    
         
            +
                if( x < nMinX || x > nMaxX || y < nMinX || y > nMaxY )
         
     | 
| 
      
 445 
     | 
    
         
            +
                    return;
         
     | 
| 
      
 446 
     | 
    
         
            +
             
     | 
| 
      
 447 
     | 
    
         
            +
                PUSH(x, x, y, 1);        /* needed in some cases */
         
     | 
| 
      
 448 
     | 
    
         
            +
                PUSH(x, x, y + 1, -1);    /* seed segment (popped 1st) */
         
     | 
| 
      
 449 
     | 
    
         
            +
             
     | 
| 
      
 450 
     | 
    
         
            +
                while( sp > stack ) {
         
     | 
| 
      
 451 
     | 
    
         
            +
                    POP(x1, x2, y, dy);
         
     | 
| 
      
 452 
     | 
    
         
            +
             
     | 
| 
      
 453 
     | 
    
         
            +
                    for( x = x1; x >= nMinX && cmp_color(get_pixel_color(tex, x, y), old_color); --x ) {
         
     | 
| 
      
 454 
     | 
    
         
            +
                        set_pixel_color_with_style(payload, tex, x, y);
         
     | 
| 
      
 455 
     | 
    
         
            +
                    }
         
     | 
| 
      
 456 
     | 
    
         
            +
             
     | 
| 
      
 457 
     | 
    
         
            +
                    if( x >= x1 )
         
     | 
| 
      
 458 
     | 
    
         
            +
                        goto SKIP;
         
     | 
| 
      
 459 
     | 
    
         
            +
             
     | 
| 
      
 460 
     | 
    
         
            +
                    left = x + 1;
         
     | 
| 
      
 461 
     | 
    
         
            +
                    if( left < x1 )
         
     | 
| 
      
 462 
     | 
    
         
            +
                        PUSH(y, left, x1 - 1, -dy);    /* leak on left? */
         
     | 
| 
      
 463 
     | 
    
         
            +
             
     | 
| 
      
 464 
     | 
    
         
            +
                    x = x1 + 1;
         
     | 
| 
      
 465 
     | 
    
         
            +
             
     | 
| 
      
 466 
     | 
    
         
            +
                    do {
         
     | 
| 
      
 467 
     | 
    
         
            +
                        for( ; x <= nMaxX && cmp_color(get_pixel_color(tex, x, y), old_color); ++x ){
         
     | 
| 
      
 468 
     | 
    
         
            +
                            set_pixel_color_with_style(payload, tex, x, y);
         
     | 
| 
      
 469 
     | 
    
         
            +
                        }
         
     | 
| 
      
 470 
     | 
    
         
            +
             
     | 
| 
      
 471 
     | 
    
         
            +
                        PUSH(left, x - 1, y, dy);
         
     | 
| 
      
 472 
     | 
    
         
            +
             
     | 
| 
      
 473 
     | 
    
         
            +
                        if( x > x2 + 1 )
         
     | 
| 
      
 474 
     | 
    
         
            +
                            PUSH(x2 + 1, x - 1, y, -dy);    /* leak on right? */
         
     | 
| 
      
 475 
     | 
    
         
            +
             
     | 
| 
      
 476 
     | 
    
         
            +
                    SKIP:        for( ++x; x <= x2 && !cmp_color(get_pixel_color(tex, x, y), old_color); ++x ) {;}
         
     | 
| 
      
 477 
     | 
    
         
            +
             
     | 
| 
      
 478 
     | 
    
         
            +
                        left = x;
         
     | 
| 
      
 479 
     | 
    
         
            +
                    } while( x <= x2 );
         
     | 
| 
      
 480 
     | 
    
         
            +
                }
         
     | 
| 
      
 481 
     | 
    
         
            +
             
     | 
| 
      
 482 
     | 
    
         
            +
                draw_epilogue(&cur, tex, primary);
         
     | 
| 
      
 483 
     | 
    
         
            +
            }
         
     | 
| 
      
 484 
     | 
    
         
            +
            /*** END FLOOD FILL ***/
         
     | 
| 
      
 485 
     | 
    
         
            +
             
     | 
| 
      
 486 
     | 
    
         
            +
            /** glow fill algorithm, from the gosu forums **/ 
         
     | 
| 
      
 487 
     | 
    
         
            +
            static void
         
     | 
| 
      
 488 
     | 
    
         
            +
            glow_floodFill( int x, int y, rgba * seed_color, action_struct * cur, texture_info * tex, texture_info * tex2 )
         
     | 
| 
      
 489 
     | 
    
         
            +
            {
         
     | 
| 
      
 490 
     | 
    
         
            +
                /* used to flood in both horizontal directions from the given point to form a line. */
         
     | 
| 
      
 491 
     | 
    
         
            +
                int fillL, fillR;     
         
     | 
| 
      
 492 
     | 
    
         
            +
                int i;
         
     | 
| 
      
 493 
     | 
    
         
            +
             
     | 
| 
      
 494 
     | 
    
         
            +
                /* initialize the flood directions */
         
     | 
| 
      
 495 
     | 
    
         
            +
                fillL = fillR = x;
         
     | 
| 
      
 496 
     | 
    
         
            +
             
     | 
| 
      
 497 
     | 
    
         
            +
                /* flood left until a new color is hit - or the edge of the image */
         
     | 
| 
      
 498 
     | 
    
         
            +
                do {
         
     | 
| 
      
 499 
     | 
    
         
            +
                    /* for texture filling */
         
     | 
| 
      
 500 
     | 
    
         
            +
                    if(tex2)
         
     | 
| 
      
 501 
     | 
    
         
            +
                        cur->color = get_pixel_color(tex2, fillL % tex2->width, y % tex2->height);
         
     | 
| 
      
 502 
     | 
    
         
            +
                    
         
     | 
| 
      
 503 
     | 
    
         
            +
                    /* TWO VERSIONS of below */
         
     | 
| 
      
 504 
     | 
    
         
            +
             
     | 
| 
      
 505 
     | 
    
         
            +
                    /* SLOW BUT MODERN VERSION */
         
     | 
| 
      
 506 
     | 
    
         
            +
                    /*        set_pixel_color_with_style(cur, tex, fillL, y); */
         
     | 
| 
      
 507 
     | 
    
         
            +
             
     | 
| 
      
 508 
     | 
    
         
            +
                    /* FAST but old version */
         
     | 
| 
      
 509 
     | 
    
         
            +
                    set_pixel_color(&cur->color, tex, fillL, y);
         
     | 
| 
      
 510 
     | 
    
         
            +
             
     | 
| 
      
 511 
     | 
    
         
            +
                    fillL--;
         
     | 
| 
      
 512 
     | 
    
         
            +
                } while( (fillL >= 0 ) && (cmp_color(get_pixel_color(tex, fillL, y), *seed_color)) );
         
     | 
| 
      
 513 
     | 
    
         
            +
             
     | 
| 
      
 514 
     | 
    
         
            +
                /* flood right until a new color is hit - or the edge of the image */
         
     | 
| 
      
 515 
     | 
    
         
            +
                do {
         
     | 
| 
      
 516 
     | 
    
         
            +
                    //        for texture filling
         
     | 
| 
      
 517 
     | 
    
         
            +
                    if(tex2)
         
     | 
| 
      
 518 
     | 
    
         
            +
                        cur->color = get_pixel_color(tex2, fillR % tex2->width, y % tex2->height);
         
     | 
| 
      
 519 
     | 
    
         
            +
                    
         
     | 
| 
      
 520 
     | 
    
         
            +
                    /*        set_pixel_color_with_style(cur, tex, fillR, y); */
         
     | 
| 
      
 521 
     | 
    
         
            +
                     
         
     | 
| 
      
 522 
     | 
    
         
            +
                    set_pixel_color(&cur->color, tex, fillR, y);
         
     | 
| 
      
 523 
     | 
    
         
            +
             
     | 
| 
      
 524 
     | 
    
         
            +
                    fillR++;
         
     | 
| 
      
 525 
     | 
    
         
            +
                } while( (fillR < cur->xmax - 1) && (cmp_color(get_pixel_color(tex, fillR, y), *seed_color)) );
         
     | 
| 
      
 526 
     | 
    
         
            +
             
     | 
| 
      
 527 
     | 
    
         
            +
                /* recurse to the line above and the line below at each point */
         
     | 
| 
      
 528 
     | 
    
         
            +
                for( i = fillL + 1; i < fillR; i++ ) {
         
     | 
| 
      
 529 
     | 
    
         
            +
                    /* Flood above */
         
     | 
| 
      
 530 
     | 
    
         
            +
                    if( ( y > 0 ) && ( cmp_color(get_pixel_color(tex, i, y - 1), *seed_color)  ) ) {
         
     | 
| 
      
 531 
     | 
    
         
            +
                        
         
     | 
| 
      
 532 
     | 
    
         
            +
                        glow_floodFill( i, y-1, seed_color, cur, tex, tex2 );
         
     | 
| 
      
 533 
     | 
    
         
            +
                    }
         
     | 
| 
      
 534 
     | 
    
         
            +
                    /* flood below */
         
     | 
| 
      
 535 
     | 
    
         
            +
                    if( (y < cur->ymax - 1) && (cmp_color(get_pixel_color(tex, i, y + 1), *seed_color) )) {
         
     | 
| 
      
 536 
     | 
    
         
            +
                        glow_floodFill( i, y+1, seed_color, cur, tex, tex2 );
         
     | 
| 
      
 537 
     | 
    
         
            +
                    }
         
     | 
| 
      
 538 
     | 
    
         
            +
                }
         
     | 
| 
      
 539 
     | 
    
         
            +
            }
         
     | 
| 
      
 540 
     | 
    
         
            +
             
     | 
| 
      
 541 
     | 
    
         
            +
            void
         
     | 
| 
      
 542 
     | 
    
         
            +
            glow_fill_do_action(int x, int y, texture_info * tex, VALUE hash_arg,
         
     | 
| 
      
 543 
     | 
    
         
            +
                                sync sync_mode, bool primary, action_struct * payload)
         
     | 
| 
      
 544 
     | 
    
         
            +
            {
         
     | 
| 
      
 545 
     | 
    
         
            +
                action_struct cur;
         
     | 
| 
      
 546 
     | 
    
         
            +
                rgba seed_color;
         
     | 
| 
      
 547 
     | 
    
         
            +
                texture_info fill_image;
         
     | 
| 
      
 548 
     | 
    
         
            +
                texture_info * fill_image_ptr = NULL;
         
     | 
| 
      
 549 
     | 
    
         
            +
                
         
     | 
| 
      
 550 
     | 
    
         
            +
                if(!bound_by_rect(x, y, 0, 0, tex->width, tex->height)) return;
         
     | 
| 
      
 551 
     | 
    
         
            +
             
     | 
| 
      
 552 
     | 
    
         
            +
                draw_prologue(&cur, tex, 0, 0, 1024, 1024, &hash_arg, sync_mode, primary, &payload);
         
     | 
| 
      
 553 
     | 
    
         
            +
             
     | 
| 
      
 554 
     | 
    
         
            +
                /* fill hates alpha_blend so let's turn it off */
         
     | 
| 
      
 555 
     | 
    
         
            +
                payload->pen.alpha_blend = false;
         
     | 
| 
      
 556 
     | 
    
         
            +
             
     | 
| 
      
 557 
     | 
    
         
            +
                if(is_a_hash(hash_arg)) {
         
     | 
| 
      
 558 
     | 
    
         
            +
                    VALUE try_image = get_from_hash(hash_arg, "texture");
         
     | 
| 
      
 559 
     | 
    
         
            +
                    if(is_gosu_image(try_image)) {
         
     | 
| 
      
 560 
     | 
    
         
            +
                        get_texture_info(try_image, &fill_image);
         
     | 
| 
      
 561 
     | 
    
         
            +
                        fill_image_ptr = &fill_image;
         
     | 
| 
      
 562 
     | 
    
         
            +
                    }
         
     | 
| 
      
 563 
     | 
    
         
            +
                }
         
     | 
| 
      
 564 
     | 
    
         
            +
             
     | 
| 
      
 565 
     | 
    
         
            +
                seed_color = get_pixel_color(tex, x, y);
         
     | 
| 
      
 566 
     | 
    
         
            +
             
     | 
| 
      
 567 
     | 
    
         
            +
                /* last argument is pointer to texture fill data (if it exists) or NULL (if it doesn't) */
         
     | 
| 
      
 568 
     | 
    
         
            +
                glow_floodFill( x, y, &seed_color, &cur, tex, fill_image_ptr );
         
     | 
| 
      
 569 
     | 
    
         
            +
             
     | 
| 
      
 570 
     | 
    
         
            +
                draw_epilogue(&cur, tex, primary);
         
     | 
| 
      
 571 
     | 
    
         
            +
            }
         
     | 
| 
      
 572 
     | 
    
         
            +
            /** end of glow fill **/
         
     | 
| 
      
 573 
     | 
    
         
            +
             
     | 
| 
      
 574 
     | 
    
         
            +
            /** scanfill algorithm **/
         
     | 
| 
      
 575 
     | 
    
         
            +
            /* the stack */
         
     | 
| 
      
 576 
     | 
    
         
            +
            #define stackSize 16777218
         
     | 
| 
      
 577 
     | 
    
         
            +
            int stack[stackSize];
         
     | 
| 
      
 578 
     | 
    
         
            +
            int stackPointer;
         
     | 
| 
      
 579 
     | 
    
         
            +
             
     | 
| 
      
 580 
     | 
    
         
            +
            static bool
         
     | 
| 
      
 581 
     | 
    
         
            +
            pop(int * x, int * y, int h) 
         
     | 
| 
      
 582 
     | 
    
         
            +
            { 
         
     | 
| 
      
 583 
     | 
    
         
            +
                if(stackPointer > 0) 
         
     | 
| 
      
 584 
     | 
    
         
            +
                    { 
         
     | 
| 
      
 585 
     | 
    
         
            +
                        int p = stack[stackPointer]; 
         
     | 
| 
      
 586 
     | 
    
         
            +
                        *x = p / h; 
         
     | 
| 
      
 587 
     | 
    
         
            +
                        *y = p % h; 
         
     | 
| 
      
 588 
     | 
    
         
            +
                        stackPointer--; 
         
     | 
| 
      
 589 
     | 
    
         
            +
                        return true; 
         
     | 
| 
      
 590 
     | 
    
         
            +
                    }     
         
     | 
| 
      
 591 
     | 
    
         
            +
                else 
         
     | 
| 
      
 592 
     | 
    
         
            +
                    { 
         
     | 
| 
      
 593 
     | 
    
         
            +
                        return false;
         
     | 
| 
      
 594 
     | 
    
         
            +
                    }    
         
     | 
| 
      
 595 
     | 
    
         
            +
            }    
         
     | 
| 
      
 596 
     | 
    
         
            +
             
     | 
| 
      
 597 
     | 
    
         
            +
            static bool
         
     | 
| 
      
 598 
     | 
    
         
            +
            push(int x, int y, int h) 
         
     | 
| 
      
 599 
     | 
    
         
            +
            { 
         
     | 
| 
      
 600 
     | 
    
         
            +
                if(stackPointer < stackSize - 1) 
         
     | 
| 
      
 601 
     | 
    
         
            +
                    { 
         
     | 
| 
      
 602 
     | 
    
         
            +
                        stackPointer++; 
         
     | 
| 
      
 603 
     | 
    
         
            +
                        stack[stackPointer] = h * x + y; 
         
     | 
| 
      
 604 
     | 
    
         
            +
                        return true;
         
     | 
| 
      
 605 
     | 
    
         
            +
                    }     
         
     | 
| 
      
 606 
     | 
    
         
            +
                else 
         
     | 
| 
      
 607 
     | 
    
         
            +
                    { 
         
     | 
| 
      
 608 
     | 
    
         
            +
                        return false;
         
     | 
| 
      
 609 
     | 
    
         
            +
                    }    
         
     | 
| 
      
 610 
     | 
    
         
            +
            }     
         
     | 
| 
      
 611 
     | 
    
         
            +
             
     | 
| 
      
 612 
     | 
    
         
            +
            static void
         
     | 
| 
      
 613 
     | 
    
         
            +
            emptyStack() 
         
     | 
| 
      
 614 
     | 
    
         
            +
            { 
         
     | 
| 
      
 615 
     | 
    
         
            +
                int x, y; 
         
     | 
| 
      
 616 
     | 
    
         
            +
                while(pop(&x, &y, 0)); 
         
     | 
| 
      
 617 
     | 
    
         
            +
            }
         
     | 
| 
      
 618 
     | 
    
         
            +
             
     | 
| 
      
 619 
     | 
    
         
            +
            void
         
     | 
| 
      
 620 
     | 
    
         
            +
            scan_fill_do_action(int x, int y, texture_info * tex, VALUE hash_arg,
         
     | 
| 
      
 621 
     | 
    
         
            +
                                sync sync_mode, bool primary, action_struct * payload)
         
     | 
| 
      
 622 
     | 
    
         
            +
            {
         
     | 
| 
      
 623 
     | 
    
         
            +
                action_struct cur;
         
     | 
| 
      
 624 
     | 
    
         
            +
                rgba old_color;
         
     | 
| 
      
 625 
     | 
    
         
            +
                int y1;
         
     | 
| 
      
 626 
     | 
    
         
            +
                bool spanLeft, spanRight;
         
     | 
| 
      
 627 
     | 
    
         
            +
             
     | 
| 
      
 628 
     | 
    
         
            +
                if(!bound_by_rect(x, y, 0, 0, tex->width - 1, tex->height - 1)) return;
         
     | 
| 
      
 629 
     | 
    
         
            +
             
     | 
| 
      
 630 
     | 
    
         
            +
                /* NB: using XMAX_OOB etc since we dont know the drawing area yet; drawing area will be set by
         
     | 
| 
      
 631 
     | 
    
         
            +
                   update_bounds() function in main loop */
         
     | 
| 
      
 632 
     | 
    
         
            +
                draw_prologue(&cur, tex, XMAX_OOB, YMAX_OOB, XMIN_OOB, YMIN_OOB, &hash_arg, sync_mode, primary, &payload);
         
     | 
| 
      
 633 
     | 
    
         
            +
             
     | 
| 
      
 634 
     | 
    
         
            +
                /* fill hates alpha_blend so let's turn it off */
         
     | 
| 
      
 635 
     | 
    
         
            +
                payload->pen.alpha_blend = false;
         
     | 
| 
      
 636 
     | 
    
         
            +
                
         
     | 
| 
      
 637 
     | 
    
         
            +
                old_color = get_pixel_color(tex, x, y);
         
     | 
| 
      
 638 
     | 
    
         
            +
             
     | 
| 
      
 639 
     | 
    
         
            +
                if(cmp_color(old_color, cur.color)) return;
         
     | 
| 
      
 640 
     | 
    
         
            +
                
         
     | 
| 
      
 641 
     | 
    
         
            +
                emptyStack();
         
     | 
| 
      
 642 
     | 
    
         
            +
                
         
     | 
| 
      
 643 
     | 
    
         
            +
                if(!push(x, y, tex->width - 1)) return;
         
     | 
| 
      
 644 
     | 
    
         
            +
                
         
     | 
| 
      
 645 
     | 
    
         
            +
                while(pop(&x, &y, tex->width - 1))
         
     | 
| 
      
 646 
     | 
    
         
            +
                    {    
         
     | 
| 
      
 647 
     | 
    
         
            +
                        y1 = y;
         
     | 
| 
      
 648 
     | 
    
         
            +
                        while(y1 >= 0 && cmp_color(old_color, get_pixel_color(tex, x, y1))) y1--;
         
     | 
| 
      
 649 
     | 
    
         
            +
                        y1++;
         
     | 
| 
      
 650 
     | 
    
         
            +
                        spanLeft = spanRight = false;
         
     | 
| 
      
 651 
     | 
    
         
            +
                        while(y1 < tex->height && cmp_color(old_color, get_pixel_color(tex, x, y1)) )
         
     | 
| 
      
 652 
     | 
    
         
            +
                            {
         
     | 
| 
      
 653 
     | 
    
         
            +
                                set_pixel_color_with_style(payload, tex, x, y1);
         
     | 
| 
      
 654 
     | 
    
         
            +
             
     | 
| 
      
 655 
     | 
    
         
            +
                                /* update the drawing rectangle */
         
     | 
| 
      
 656 
     | 
    
         
            +
                                update_bounds(payload, x, y1, x, y1);
         
     | 
| 
      
 657 
     | 
    
         
            +
             
     | 
| 
      
 658 
     | 
    
         
            +
                                if(!spanLeft && x > 1 && cmp_color(old_color, get_pixel_color(tex, x - 1, y1))) 
         
     | 
| 
      
 659 
     | 
    
         
            +
                                    {
         
     | 
| 
      
 660 
     | 
    
         
            +
                                        if(!push(x - 1, y1, tex->width - 1)) return;
         
     | 
| 
      
 661 
     | 
    
         
            +
                                        spanLeft = true;
         
     | 
| 
      
 662 
     | 
    
         
            +
                                    }
         
     | 
| 
      
 663 
     | 
    
         
            +
             
     | 
| 
      
 664 
     | 
    
         
            +
                                else if(spanLeft && !cmp_color(old_color, get_pixel_color(tex, x - 1, y1)))
         
     | 
| 
      
 665 
     | 
    
         
            +
                                    {
         
     | 
| 
      
 666 
     | 
    
         
            +
                                        spanLeft = false;
         
     | 
| 
      
 667 
     | 
    
         
            +
                                    }
         
     | 
| 
      
 668 
     | 
    
         
            +
             
     | 
| 
      
 669 
     | 
    
         
            +
                                if(!spanRight && x < tex->width - 1 && cmp_color(old_color,
         
     | 
| 
      
 670 
     | 
    
         
            +
                                                                                 get_pixel_color(tex, x + 1, y1))) 
         
     | 
| 
      
 671 
     | 
    
         
            +
                                    {
         
     | 
| 
      
 672 
     | 
    
         
            +
                                        if(!push(x + 1, y1, tex->width - 1)) return;
         
     | 
| 
      
 673 
     | 
    
         
            +
                                        spanRight = true;
         
     | 
| 
      
 674 
     | 
    
         
            +
                                    }
         
     | 
| 
      
 675 
     | 
    
         
            +
             
     | 
| 
      
 676 
     | 
    
         
            +
                                else if(spanRight && x < tex->width - 1 && !cmp_color(old_color,get_pixel_color(tex, x + 1, y1)))
         
     | 
| 
      
 677 
     | 
    
         
            +
                                    {
         
     | 
| 
      
 678 
     | 
    
         
            +
                                        spanRight = false;
         
     | 
| 
      
 679 
     | 
    
         
            +
                                    } 
         
     | 
| 
      
 680 
     | 
    
         
            +
                                y1++;
         
     | 
| 
      
 681 
     | 
    
         
            +
                            }
         
     | 
| 
      
 682 
     | 
    
         
            +
                    }
         
     | 
| 
      
 683 
     | 
    
         
            +
                draw_epilogue(&cur, tex, primary);
         
     | 
| 
      
 684 
     | 
    
         
            +
            }
         
     | 
| 
      
 685 
     | 
    
         
            +
            /** end of scanfill **/
         
     | 
| 
      
 686 
     | 
    
         
            +
             
     | 
| 
      
 687 
     | 
    
         
            +
            /** bezier curve algorithm **/
         
     | 
| 
      
 688 
     | 
    
         
            +
            static void
         
     | 
| 
      
 689 
     | 
    
         
            +
            bezier_point(VALUE points, float u, float * x, float * y, int n, int format,
         
     | 
| 
      
 690 
     | 
    
         
            +
                         int draw_offset_x, int draw_offset_y)
         
     | 
| 
      
 691 
     | 
    
         
            +
            {
         
     | 
| 
      
 692 
     | 
    
         
            +
                int k;
         
     | 
| 
      
 693 
     | 
    
         
            +
                int xy_index;
         
     | 
| 
      
 694 
     | 
    
         
            +
                double sumx = 0, sumy = 0;
         
     | 
| 
      
 695 
     | 
    
         
            +
             
         
     | 
| 
      
 696 
     | 
    
         
            +
             
     | 
| 
      
 697 
     | 
    
         
            +
                for(k = 0; k < n; k++) {
         
     | 
| 
      
 698 
     | 
    
         
            +
                    switch(format) {
         
     | 
| 
      
 699 
     | 
    
         
            +
                    case POINT_FORMAT:
         
     | 
| 
      
 700 
     | 
    
         
            +
                        
         
     | 
| 
      
 701 
     | 
    
         
            +
                        sumx += NUM2DBL(point_x(get_from_array(points, k))) * bernstein(n - 1, k, u);
         
     | 
| 
      
 702 
     | 
    
         
            +
                        sumy += NUM2DBL(point_y(get_from_array(points, k))) * bernstein(n - 1, k, u);
         
     | 
| 
      
 703 
     | 
    
         
            +
                        break;
         
     | 
| 
      
 704 
     | 
    
         
            +
                    case SIMPLE_FORMAT:
         
     | 
| 
      
 705 
     | 
    
         
            +
                         
         
     | 
| 
      
 706 
     | 
    
         
            +
                        xy_index = k * 2;
         
     | 
| 
      
 707 
     | 
    
         
            +
                        sumx +=  NUM2DBL(get_from_array(points, xy_index)) * bernstein(n - 1, k, u);
         
     | 
| 
      
 708 
     | 
    
         
            +
                        sumy +=  NUM2DBL(get_from_array(points, xy_index + 1)) * bernstein(n - 1, k, u);
         
     | 
| 
      
 709 
     | 
    
         
            +
                        break;
         
     | 
| 
      
 710 
     | 
    
         
            +
                    default:
         
     | 
| 
      
 711 
     | 
    
         
            +
                        rb_raise(rb_eArgError, "pixel format must be either POINT_FORMAT or SIMPLE_FORMAT");
         
     | 
| 
      
 712 
     | 
    
         
            +
                    }
         
     | 
| 
      
 713 
     | 
    
         
            +
                }
         
     | 
| 
      
 714 
     | 
    
         
            +
             
     | 
| 
      
 715 
     | 
    
         
            +
                *x = sumx + draw_offset_x;
         
     | 
| 
      
 716 
     | 
    
         
            +
                *y = sumy + draw_offset_y;
         
     | 
| 
      
 717 
     | 
    
         
            +
            }
         
     | 
| 
      
 718 
     | 
    
         
            +
             
     | 
| 
      
 719 
     | 
    
         
            +
            void
         
     | 
| 
      
 720 
     | 
    
         
            +
            bezier_do_action(VALUE points, texture_info * tex, VALUE hash_arg, sync sync_mode,
         
     | 
| 
      
 721 
     | 
    
         
            +
                             bool primary, action_struct * payload)
         
     | 
| 
      
 722 
     | 
    
         
            +
            {
         
     | 
| 
      
 723 
     | 
    
         
            +
                float u = 0.0;
         
     | 
| 
      
 724 
     | 
    
         
            +
                action_struct cur;
         
     | 
| 
      
 725 
     | 
    
         
            +
                float x1, y1, x2, y2;
         
     | 
| 
      
 726 
     | 
    
         
            +
                int first_x, first_y;
         
     | 
| 
      
 727 
     | 
    
         
            +
                int format;
         
     | 
| 
      
 728 
     | 
    
         
            +
                int num_point_pairs;
         
     | 
| 
      
 729 
     | 
    
         
            +
                bool closed = false;
         
     | 
| 
      
 730 
     | 
    
         
            +
                VALUE offset_val;
         
     | 
| 
      
 731 
     | 
    
         
            +
                int draw_offset_x, draw_offset_y;
         
     | 
| 
      
 732 
     | 
    
         
            +
             
     | 
| 
      
 733 
     | 
    
         
            +
                /* defaults to 200 (1 / 0.005) samples per curve */
         
     | 
| 
      
 734 
     | 
    
         
            +
                float step_size = 0.005;
         
     | 
| 
      
 735 
     | 
    
         
            +
                
         
     | 
| 
      
 736 
     | 
    
         
            +
                draw_prologue(&cur, tex, XMAX_OOB, YMAX_OOB, XMIN_OOB, YMIN_OOB, &hash_arg, sync_mode, primary, &payload);
         
     | 
| 
      
 737 
     | 
    
         
            +
             
     | 
| 
      
 738 
     | 
    
         
            +
                /* calculate offset */
         
     | 
| 
      
 739 
     | 
    
         
            +
                offset_val = get_image_local(tex->image, DRAW_OFFSET);
         
     | 
| 
      
 740 
     | 
    
         
            +
             
     | 
| 
      
 741 
     | 
    
         
            +
                draw_offset_x = NUM2INT(get_from_array(offset_val, 0));
         
     | 
| 
      
 742 
     | 
    
         
            +
                draw_offset_y = NUM2INT(get_from_array(offset_val, 1));
         
     | 
| 
      
 743 
     | 
    
         
            +
             
     | 
| 
      
 744 
     | 
    
         
            +
                if(is_a_hash(hash_arg)) {
         
     | 
| 
      
 745 
     | 
    
         
            +
             
     | 
| 
      
 746 
     | 
    
         
            +
                    /* if the polyline is 'closed' make the last point the first */
         
     | 
| 
      
 747 
     | 
    
         
            +
                    if(RTEST(get_from_hash(hash_arg, "closed")) || RTEST(get_from_hash(hash_arg, "close"))) {
         
     | 
| 
      
 748 
     | 
    
         
            +
             
     | 
| 
      
 749 
     | 
    
         
            +
                        /* so that our additional point is not persistent */
         
     | 
| 
      
 750 
     | 
    
         
            +
                        points = rb_obj_dup(points);
         
     | 
| 
      
 751 
     | 
    
         
            +
                        closed = true;
         
     | 
| 
      
 752 
     | 
    
         
            +
                    }
         
     | 
| 
      
 753 
     | 
    
         
            +
                    
         
     | 
| 
      
 754 
     | 
    
         
            +
                    /* number of points to sample */
         
     | 
| 
      
 755 
     | 
    
         
            +
                    if(RTEST(get_from_hash(hash_arg, "sample_size"))) {
         
     | 
| 
      
 756 
     | 
    
         
            +
                        VALUE c = get_from_hash(hash_arg, "sample_size");
         
     | 
| 
      
 757 
     | 
    
         
            +
                        Check_Type(c, T_FIXNUM);
         
     | 
| 
      
 758 
     | 
    
         
            +
                        step_size = 1.0 / (float)FIX2INT(c);
         
     | 
| 
      
 759 
     | 
    
         
            +
                    }
         
     | 
| 
      
 760 
     | 
    
         
            +
                }
         
     | 
| 
      
 761 
     | 
    
         
            +
             
     | 
| 
      
 762 
     | 
    
         
            +
                if(is_a_point(get_from_array(points, 0))) {
         
     | 
| 
      
 763 
     | 
    
         
            +
                    format = POINT_FORMAT;
         
     | 
| 
      
 764 
     | 
    
         
            +
             
     | 
| 
      
 765 
     | 
    
         
            +
                    if(closed)
         
     | 
| 
      
 766 
     | 
    
         
            +
                        rb_ary_push(points, get_from_array(points, 0));
         
     | 
| 
      
 767 
     | 
    
         
            +
                    
         
     | 
| 
      
 768 
     | 
    
         
            +
                    num_point_pairs = RARRAY_LEN(points);
         
     | 
| 
      
 769 
     | 
    
         
            +
                }
         
     | 
| 
      
 770 
     | 
    
         
            +
                else {
         
     | 
| 
      
 771 
     | 
    
         
            +
                    format = SIMPLE_FORMAT;
         
     | 
| 
      
 772 
     | 
    
         
            +
             
     | 
| 
      
 773 
     | 
    
         
            +
                    /* ensure points are given in pairs */
         
     | 
| 
      
 774 
     | 
    
         
            +
                    if(RARRAY_LEN(points) % 2)
         
     | 
| 
      
 775 
     | 
    
         
            +
                        rb_raise(rb_eArgError, "bezier needs an even number of points. got %d\n", (int)RARRAY_LEN(points));
         
     | 
| 
      
 776 
     | 
    
         
            +
             
     | 
| 
      
 777 
     | 
    
         
            +
                    if(closed) {
         
     | 
| 
      
 778 
     | 
    
         
            +
                        rb_ary_push(points, get_from_array(points, 0));
         
     | 
| 
      
 779 
     | 
    
         
            +
                        rb_ary_push(points, get_from_array(points, 1));
         
     | 
| 
      
 780 
     | 
    
         
            +
                    }
         
     | 
| 
      
 781 
     | 
    
         
            +
                    
         
     | 
| 
      
 782 
     | 
    
         
            +
                    num_point_pairs = RARRAY_LEN(points) / 2;
         
     | 
| 
      
 783 
     | 
    
         
            +
                }
         
     | 
| 
      
 784 
     | 
    
         
            +
             
     | 
| 
      
 785 
     | 
    
         
            +
                if(num_point_pairs > 13)
         
     | 
| 
      
 786 
     | 
    
         
            +
                    rb_raise(rb_eArgError, "too many points for bezier curve. 13 points is current maximum. got %d\n",
         
     | 
| 
      
 787 
     | 
    
         
            +
                             num_point_pairs);
         
     | 
| 
      
 788 
     | 
    
         
            +
             
     | 
| 
      
 789 
     | 
    
         
            +
                /* get the first point */
         
     | 
| 
      
 790 
     | 
    
         
            +
                bezier_point(points, 0, &x1, &y1, num_point_pairs, format, draw_offset_x, draw_offset_y);
         
     | 
| 
      
 791 
     | 
    
         
            +
             
     | 
| 
      
 792 
     | 
    
         
            +
                /* save it so we can link up with last point properly if the curve is 'closed' */
         
     | 
| 
      
 793 
     | 
    
         
            +
                first_x = x1;
         
     | 
| 
      
 794 
     | 
    
         
            +
                first_y = y1;
         
     | 
| 
      
 795 
     | 
    
         
            +
             
     | 
| 
      
 796 
     | 
    
         
            +
                while(u <= 1) {
         
     | 
| 
      
 797 
     | 
    
         
            +
                    bezier_point(points, u, &x2, &y2, num_point_pairs, format, draw_offset_x, draw_offset_y);
         
     | 
| 
      
 798 
     | 
    
         
            +
             
         
     | 
| 
      
 799 
     | 
    
         
            +
                    line_do_action(x1, y1, x2, y2, tex, hash_arg, no_sync, false, payload);
         
     | 
| 
      
 800 
     | 
    
         
            +
             
     | 
| 
      
 801 
     | 
    
         
            +
                    /* update drawing rectangle */
         
     | 
| 
      
 802 
     | 
    
         
            +
                    update_bounds(payload, x1, y1, x2, y2);
         
     | 
| 
      
 803 
     | 
    
         
            +
             
     | 
| 
      
 804 
     | 
    
         
            +
                    x1 = x2;
         
     | 
| 
      
 805 
     | 
    
         
            +
                    y1 = y2;
         
     | 
| 
      
 806 
     | 
    
         
            +
             
     | 
| 
      
 807 
     | 
    
         
            +
                    u += step_size;
         
     | 
| 
      
 808 
     | 
    
         
            +
                }
         
     | 
| 
      
 809 
     | 
    
         
            +
             
     | 
| 
      
 810 
     | 
    
         
            +
                /* sometimes beziers dont close properly, so we'll ensure it's closed */
         
     | 
| 
      
 811 
     | 
    
         
            +
                if(closed)
         
     | 
| 
      
 812 
     | 
    
         
            +
                    line_do_action(x2, y2, first_x, first_y, tex, hash_arg, no_sync, false, payload);
         
     | 
| 
      
 813 
     | 
    
         
            +
             
     | 
| 
      
 814 
     | 
    
         
            +
                draw_epilogue(&cur, tex, primary);
         
     | 
| 
      
 815 
     | 
    
         
            +
            }
         
     | 
| 
      
 816 
     | 
    
         
            +
            /** end of bezier **/
         
     | 
| 
      
 817 
     | 
    
         
            +
             
     | 
| 
      
 818 
     | 
    
         
            +
            /** each_pixel  **/
         
     | 
| 
      
 819 
     | 
    
         
            +
            static void
         
     | 
| 
      
 820 
     | 
    
         
            +
            set_color_array(VALUE ary, rgba * color)
         
     | 
| 
      
 821 
     | 
    
         
            +
            {
         
     | 
| 
      
 822 
     | 
    
         
            +
                set_array_value(ary, 0, rb_float_new(color->red));
         
     | 
| 
      
 823 
     | 
    
         
            +
                set_array_value(ary, 1, rb_float_new(color->green));
         
     | 
| 
      
 824 
     | 
    
         
            +
                set_array_value(ary, 2, rb_float_new(color->blue));
         
     | 
| 
      
 825 
     | 
    
         
            +
                set_array_value(ary, 3, rb_float_new(color->alpha));
         
     | 
| 
      
 826 
     | 
    
         
            +
            }
         
     | 
| 
      
 827 
     | 
    
         
            +
                
         
     | 
| 
      
 828 
     | 
    
         
            +
            void
         
     | 
| 
      
 829 
     | 
    
         
            +
            each_pixel_do_action(int x1, int y1, int x2, int y2, VALUE proc, texture_info * tex, VALUE hash_arg,
         
     | 
| 
      
 830 
     | 
    
         
            +
                                 sync sync_mode, bool primary, action_struct * payload)
         
     | 
| 
      
 831 
     | 
    
         
            +
            {
         
     | 
| 
      
 832 
     | 
    
         
            +
                action_struct cur;
         
     | 
| 
      
 833 
     | 
    
         
            +
                int x, y, arity;
         
     | 
| 
      
 834 
     | 
    
         
            +
                VALUE rb_pix = rb_ary_new2(4);
         
     | 
| 
      
 835 
     | 
    
         
            +
                
         
     | 
| 
      
 836 
     | 
    
         
            +
                draw_prologue(&cur, tex, x1, y1, x2, y2, &hash_arg, sync_mode, primary, &payload);
         
     | 
| 
      
 837 
     | 
    
         
            +
             
     | 
| 
      
 838 
     | 
    
         
            +
                arity = FIX2INT(rb_funcall(proc, rb_intern("arity"), 0));
         
     | 
| 
      
 839 
     | 
    
         
            +
             
     | 
| 
      
 840 
     | 
    
         
            +
                for(y = y1; y < y2 + 1; y++)
         
     | 
| 
      
 841 
     | 
    
         
            +
                    for(x = x1; x < x2 + 1; x++) {
         
     | 
| 
      
 842 
     | 
    
         
            +
                        rgba pix = get_pixel_color(tex, x, y);
         
     | 
| 
      
 843 
     | 
    
         
            +
             
     | 
| 
      
 844 
     | 
    
         
            +
                        set_color_array(rb_pix, &pix);
         
     | 
| 
      
 845 
     | 
    
         
            +
                        
         
     | 
| 
      
 846 
     | 
    
         
            +
                        /* invoke the block */
         
     | 
| 
      
 847 
     | 
    
         
            +
                        switch(arity) {
         
     | 
| 
      
 848 
     | 
    
         
            +
                        case 1:
         
     | 
| 
      
 849 
     | 
    
         
            +
                            rb_funcall(proc, rb_intern("call"), 1, rb_pix);
         
     | 
| 
      
 850 
     | 
    
         
            +
                            break;
         
     | 
| 
      
 851 
     | 
    
         
            +
                        case 3:
         
     | 
| 
      
 852 
     | 
    
         
            +
                            rb_funcall(proc, rb_intern("call"), 3, rb_pix, INT2FIX(x), INT2FIX(y));
         
     | 
| 
      
 853 
     | 
    
         
            +
                            break;
         
     | 
| 
      
 854 
     | 
    
         
            +
                        default:
         
     | 
| 
      
 855 
     | 
    
         
            +
                            rb_raise(rb_eArgError, "permissible arities for each are 1 & 3. Got %d\n",
         
     | 
| 
      
 856 
     | 
    
         
            +
                                     arity);
         
     | 
| 
      
 857 
     | 
    
         
            +
             
     | 
| 
      
 858 
     | 
    
         
            +
                        }
         
     | 
| 
      
 859 
     | 
    
         
            +
             
     | 
| 
      
 860 
     | 
    
         
            +
                        pix = convert_rb_color_to_rgba(rb_pix);
         
     | 
| 
      
 861 
     | 
    
         
            +
             
     | 
| 
      
 862 
     | 
    
         
            +
                        set_pixel_color(&pix, tex, x, y);
         
     | 
| 
      
 863 
     | 
    
         
            +
                    }
         
     | 
| 
      
 864 
     | 
    
         
            +
             
     | 
| 
      
 865 
     | 
    
         
            +
                draw_epilogue(&cur, tex, primary);
         
     | 
| 
      
 866 
     | 
    
         
            +
            }
         
     | 
| 
      
 867 
     | 
    
         
            +
            /** end each_pixel iterator **/
         
     | 
| 
      
 868 
     | 
    
         
            +
             
     | 
| 
      
 869 
     | 
    
         
            +
            /** splice algorithm **/
         
     | 
| 
      
 870 
     | 
    
         
            +
            void
         
     | 
| 
      
 871 
     | 
    
         
            +
            splice_do_action(int x0, int y0, int cx1, int cy1, int cx2, int cy2, texture_info * splice_tex,
         
     | 
| 
      
 872 
     | 
    
         
            +
                             texture_info * tex, VALUE hash_arg, sync sync_mode,
         
     | 
| 
      
 873 
     | 
    
         
            +
                             bool primary, action_struct * payload)
         
     | 
| 
      
 874 
     | 
    
         
            +
            {
         
     | 
| 
      
 875 
     | 
    
         
            +
                action_struct cur;
         
     | 
| 
      
 876 
     | 
    
         
            +
                int xbound;
         
     | 
| 
      
 877 
     | 
    
         
            +
                int ybound;
         
     | 
| 
      
 878 
     | 
    
         
            +
                rgba chromakey;
         
     | 
| 
      
 879 
     | 
    
         
            +
                int x, y;
         
     | 
| 
      
 880 
     | 
    
         
            +
                float * image_buf = NULL;
         
     | 
| 
      
 881 
     | 
    
         
            +
                bool inverse_chroma = false;
         
     | 
| 
      
 882 
     | 
    
         
            +
                bool has_chroma = false;
         
     | 
| 
      
 883 
     | 
    
         
            +
                bool same_image = false;
         
     | 
| 
      
 884 
     | 
    
         
            +
             
     | 
| 
      
 885 
     | 
    
         
            +
                constrain_boundaries(&cx1, &cy1, &cx2, &cy2, splice_tex->width, splice_tex->height);
         
     | 
| 
      
 886 
     | 
    
         
            +
                xbound = cx2 - cx1 + 1;
         
     | 
| 
      
 887 
     | 
    
         
            +
                ybound = cy2 - cy1 + 1;
         
     | 
| 
      
 888 
     | 
    
         
            +
             
     | 
| 
      
 889 
     | 
    
         
            +
                draw_prologue(&cur, tex, x0, y0,
         
     | 
| 
      
 890 
     | 
    
         
            +
                              x0 + xbound, y0 + ybound, &hash_arg, sync_mode, primary, &payload);
         
     | 
| 
      
 891 
     | 
    
         
            +
             
     | 
| 
      
 892 
     | 
    
         
            +
             
     | 
| 
      
 893 
     | 
    
         
            +
                if(has_optional_hash_arg(hash_arg, "chroma_key")) {
         
     | 
| 
      
 894 
     | 
    
         
            +
                    VALUE c = get_from_hash(hash_arg, "chroma_key");
         
     | 
| 
      
 895 
     | 
    
         
            +
                    chromakey = convert_rb_color_to_rgba(c);
         
     | 
| 
      
 896 
     | 
    
         
            +
                    has_chroma = true;
         
     | 
| 
      
 897 
     | 
    
         
            +
                }
         
     | 
| 
      
 898 
     | 
    
         
            +
                else if(has_optional_hash_arg(hash_arg, "chroma_key_not")) {
         
     | 
| 
      
 899 
     | 
    
         
            +
                    chromakey = convert_rb_color_to_rgba(get_from_hash(hash_arg, "chroma_key_not"));
         
     | 
| 
      
 900 
     | 
    
         
            +
                    inverse_chroma = true;
         
     | 
| 
      
 901 
     | 
    
         
            +
                    has_chroma = true;
         
     | 
| 
      
 902 
     | 
    
         
            +
                }
         
     | 
| 
      
 903 
     | 
    
         
            +
             
     | 
| 
      
 904 
     | 
    
         
            +
                if(splice_tex->image == tex->image)
         
     | 
| 
      
 905 
     | 
    
         
            +
                    same_image = true;
         
     | 
| 
      
 906 
     | 
    
         
            +
             
     | 
| 
      
 907 
     | 
    
         
            +
                /* NB: we do not use this in the general case since it's almost 1.5 times as slow.
         
     | 
| 
      
 908 
     | 
    
         
            +
                   It is necessary for splicing from/to the same region of pixels though.
         
     | 
| 
      
 909 
     | 
    
         
            +
                */
         
     | 
| 
      
 910 
     | 
    
         
            +
                if(same_image) 
         
     | 
| 
      
 911 
     | 
    
         
            +
                    image_buf = get_image_chunk(splice_tex, cx1, cy1, cx2, cy2);
         
     | 
| 
      
 912 
     | 
    
         
            +
                
         
     | 
| 
      
 913 
     | 
    
         
            +
                for(y = 0; y < ybound; y++)
         
     | 
| 
      
 914 
     | 
    
         
            +
                    for(x = 0; x < xbound; x++) {
         
     | 
| 
      
 915 
     | 
    
         
            +
                        
         
     | 
| 
      
 916 
     | 
    
         
            +
                        if(!same_image)
         
     | 
| 
      
 917 
     | 
    
         
            +
                            payload->color = get_pixel_color(splice_tex, cx1 + x, cy1 + y);
         
     | 
| 
      
 918 
     | 
    
         
            +
                        else 
         
     | 
| 
      
 919 
     | 
    
         
            +
                            payload->color = get_pixel_color_from_chunk(image_buf, xbound, ybound, x, y);
         
     | 
| 
      
 920 
     | 
    
         
            +
                            
         
     | 
| 
      
 921 
     | 
    
         
            +
                        if(has_chroma) {
         
     | 
| 
      
 922 
     | 
    
         
            +
                            bool cmp = cmp_color(payload->color, chromakey);
         
     | 
| 
      
 923 
     | 
    
         
            +
                            if(!cmp && !inverse_chroma)
         
     | 
| 
      
 924 
     | 
    
         
            +
                                set_pixel_color_with_style(payload, tex, x0 + x, y0 + y);
         
     | 
| 
      
 925 
     | 
    
         
            +
                            else if(cmp && inverse_chroma)
         
     | 
| 
      
 926 
     | 
    
         
            +
                                set_pixel_color_with_style(payload, tex, x0 + x, y0 + y);
         
     | 
| 
      
 927 
     | 
    
         
            +
                        }
         
     | 
| 
      
 928 
     | 
    
         
            +
                        else
         
     | 
| 
      
 929 
     | 
    
         
            +
                            set_pixel_color_with_style(payload, tex, x0 + x, y0 + y);
         
     | 
| 
      
 930 
     | 
    
         
            +
                    }
         
     | 
| 
      
 931 
     | 
    
         
            +
             
     | 
| 
      
 932 
     | 
    
         
            +
                if(same_image)
         
     | 
| 
      
 933 
     | 
    
         
            +
                    free(image_buf);
         
     | 
| 
      
 934 
     | 
    
         
            +
             
     | 
| 
      
 935 
     | 
    
         
            +
                draw_epilogue(&cur, tex, primary);
         
     | 
| 
      
 936 
     | 
    
         
            +
            }
         
     | 
| 
      
 937 
     | 
    
         
            +
            /** end splice **/
         
     | 
| 
      
 938 
     | 
    
         
            +
             
     | 
| 
      
 939 
     | 
    
         
            +
            static void
         
     | 
| 
      
 940 
     | 
    
         
            +
            initialize_action_struct(action_struct * cur, VALUE hash_arg, sync sync_mode)
         
     | 
| 
      
 941 
     | 
    
         
            +
            {
         
     | 
| 
      
 942 
     | 
    
         
            +
                /* initialize action-struct to default values */
         
     | 
| 
      
 943 
     | 
    
         
            +
                cur->sync_mode = sync_mode;
         
     | 
| 
      
 944 
     | 
    
         
            +
                cur->hash_arg = hash_arg;
         
     | 
| 
      
 945 
     | 
    
         
            +
             
     | 
| 
      
 946 
     | 
    
         
            +
                cur->color = convert_image_local_color_to_rgba(cur->tex->image);
         
     | 
| 
      
 947 
     | 
    
         
            +
                cur->pen.has_color_control_proc = false;
         
     | 
| 
      
 948 
     | 
    
         
            +
                cur->pen.has_color_control_transform = false;
         
     | 
| 
      
 949 
     | 
    
         
            +
                cur->pen.has_source_texture = false;
         
     | 
| 
      
 950 
     | 
    
         
            +
                cur->pen.alpha_blend = false;
         
     | 
| 
      
 951 
     | 
    
         
            +
             
     | 
| 
      
 952 
     | 
    
         
            +
                /* set static color control transformations to defaults */
         
     | 
| 
      
 953 
     | 
    
         
            +
                cur->pen.color_mult.red = 1.0;
         
     | 
| 
      
 954 
     | 
    
         
            +
                cur->pen.color_mult.green = 1.0;
         
     | 
| 
      
 955 
     | 
    
         
            +
                cur->pen.color_mult.blue = 1.0;
         
     | 
| 
      
 956 
     | 
    
         
            +
                cur->pen.color_mult.alpha = 1.0;
         
     | 
| 
      
 957 
     | 
    
         
            +
             
     | 
| 
      
 958 
     | 
    
         
            +
                cur->pen.color_add.red = 0.0;
         
     | 
| 
      
 959 
     | 
    
         
            +
                cur->pen.color_add.green = 0.0;
         
     | 
| 
      
 960 
     | 
    
         
            +
                cur->pen.color_add.blue = 0.0;
         
     | 
| 
      
 961 
     | 
    
         
            +
                cur->pen.color_add.alpha = 0.0;
         
     | 
| 
      
 962 
     | 
    
         
            +
            }
         
     | 
| 
      
 963 
     | 
    
         
            +
                
         
     | 
| 
      
 964 
     | 
    
         
            +
            /* TODO: fix this function below, it's too ugly and bulky and weird **/
         
     | 
| 
      
 965 
     | 
    
         
            +
            static void
         
     | 
| 
      
 966 
     | 
    
         
            +
            process_common_hash_args(action_struct * cur, VALUE * hash_arg, sync sync_mode, bool primary)
         
     | 
| 
      
 967 
     | 
    
         
            +
            {
         
     | 
| 
      
 968 
     | 
    
         
            +
                
         
     | 
| 
      
 969 
     | 
    
         
            +
                VALUE user_defaults;  
         
     | 
| 
      
 970 
     | 
    
         
            +
                VALUE hash_blend;
         
     | 
| 
      
 971 
     | 
    
         
            +
             
     | 
| 
      
 972 
     | 
    
         
            +
             
     | 
| 
      
 973 
     | 
    
         
            +
                /* if a hash doesn't exist then create one */
         
     | 
| 
      
 974 
     | 
    
         
            +
                if(!is_a_hash(*hash_arg)) 
         
     | 
| 
      
 975 
     | 
    
         
            +
                    *hash_arg = rb_hash_new();
         
     | 
| 
      
 976 
     | 
    
         
            +
             
     | 
| 
      
 977 
     | 
    
         
            +
                /* init the action to default values */
         
     | 
| 
      
 978 
     | 
    
         
            +
                initialize_action_struct(cur, *hash_arg, sync_mode);
         
     | 
| 
      
 979 
     | 
    
         
            +
             
     | 
| 
      
 980 
     | 
    
         
            +
                /* get the user default options & merge with given options */
         
     | 
| 
      
 981 
     | 
    
         
            +
                user_defaults = get_image_local(cur->tex->image, USER_DEFAULTS);
         
     | 
| 
      
 982 
     | 
    
         
            +
                hash_blend = rb_funcall(user_defaults, rb_intern("merge"), 1, *hash_arg);
         
     | 
| 
      
 983 
     | 
    
         
            +
                rb_funcall(*hash_arg, rb_intern("merge!"), 1, hash_blend);
         
     | 
| 
      
 984 
     | 
    
         
            +
             
     | 
| 
      
 985 
     | 
    
         
            +
                if(has_optional_hash_arg(*hash_arg, "color")) {
         
     | 
| 
      
 986 
     | 
    
         
            +
                    VALUE c = get_from_hash(*hash_arg, "color");
         
     | 
| 
      
 987 
     | 
    
         
            +
                    cur->color = convert_rb_color_to_rgba(c);
         
     | 
| 
      
 988 
     | 
    
         
            +
                    if(c == string2sym("random")) {
         
     | 
| 
      
 989 
     | 
    
         
            +
                        set_hash_value(*hash_arg, "color", convert_rgba_to_rb_color(&cur->color));
         
     | 
| 
      
 990 
     | 
    
         
            +
                    }
         
     | 
| 
      
 991 
     | 
    
         
            +
                }
         
     | 
| 
      
 992 
     | 
    
         
            +
             
     | 
| 
      
 993 
     | 
    
         
            +
                /* shadows */
         
     | 
| 
      
 994 
     | 
    
         
            +
                if(RTEST(get_from_hash(*hash_arg, "shadow"))) {
         
     | 
| 
      
 995 
     | 
    
         
            +
                    cur->pen.color_mult.red = 0.66;
         
     | 
| 
      
 996 
     | 
    
         
            +
                    cur->pen.color_mult.green = 0.66;
         
     | 
| 
      
 997 
     | 
    
         
            +
                    cur->pen.color_mult.blue = 0.66;
         
     | 
| 
      
 998 
     | 
    
         
            +
                    cur->pen.color_mult.alpha = 1;
         
     | 
| 
      
 999 
     | 
    
         
            +
             
     | 
| 
      
 1000 
     | 
    
         
            +
                    cur->pen.has_color_control_transform = true;
         
     | 
| 
      
 1001 
     | 
    
         
            +
                }
         
     | 
| 
      
 1002 
     | 
    
         
            +
                
         
     | 
| 
      
 1003 
     | 
    
         
            +
                /* sync mode */
         
     | 
| 
      
 1004 
     | 
    
         
            +
                if(has_optional_hash_arg(*hash_arg, "sync_mode")) {
         
     | 
| 
      
 1005 
     | 
    
         
            +
                    VALUE user_sync_mode = get_from_hash(*hash_arg, "sync_mode");
         
     | 
| 
      
 1006 
     | 
    
         
            +
             
     | 
| 
      
 1007 
     | 
    
         
            +
                    Check_Type(user_sync_mode, T_SYMBOL);
         
     | 
| 
      
 1008 
     | 
    
         
            +
                    
         
     | 
| 
      
 1009 
     | 
    
         
            +
                    if(user_sync_mode == string2sym("lazy_sync"))
         
     | 
| 
      
 1010 
     | 
    
         
            +
                        cur->sync_mode = lazy_sync;
         
     | 
| 
      
 1011 
     | 
    
         
            +
                    else if(user_sync_mode == string2sym("eager_sync"))
         
     | 
| 
      
 1012 
     | 
    
         
            +
                        cur->sync_mode = eager_sync;
         
     | 
| 
      
 1013 
     | 
    
         
            +
                    else if(user_sync_mode == string2sym("no_sync"))
         
     | 
| 
      
 1014 
     | 
    
         
            +
                        cur->sync_mode = no_sync;
         
     | 
| 
      
 1015 
     | 
    
         
            +
                    else
         
     | 
| 
      
 1016 
     | 
    
         
            +
                        rb_raise(rb_eArgError, "unrecognized sync mode: %s\n. Allowable modes are "
         
     | 
| 
      
 1017 
     | 
    
         
            +
                                 ":lazy_sync, :eager_sync, :no_sync.",
         
     | 
| 
      
 1018 
     | 
    
         
            +
                                 sym2string(user_sync_mode));
         
     | 
| 
      
 1019 
     | 
    
         
            +
             
     | 
| 
      
 1020 
     | 
    
         
            +
                    delete_from_hash(*hash_arg, "sync_mode");
         
     | 
| 
      
 1021 
     | 
    
         
            +
                    
         
     | 
| 
      
 1022 
     | 
    
         
            +
                }
         
     | 
| 
      
 1023 
     | 
    
         
            +
             
     | 
| 
      
 1024 
     | 
    
         
            +
                /* process the color_control block or transform (if there is one) */
         
     | 
| 
      
 1025 
     | 
    
         
            +
                prepare_color_control(cur);
         
     | 
| 
      
 1026 
     | 
    
         
            +
             
     | 
| 
      
 1027 
     | 
    
         
            +
                /* process the filling texture (if there is one) */
         
     | 
| 
      
 1028 
     | 
    
         
            +
                prepare_fill_texture(cur);
         
     | 
| 
      
 1029 
     | 
    
         
            +
             
     | 
| 
      
 1030 
     | 
    
         
            +
                /* does the user want to blend alpha values ? */
         
     | 
| 
      
 1031 
     | 
    
         
            +
                if(get_from_hash(*hash_arg, "alpha_blend") == Qtrue)
         
     | 
| 
      
 1032 
     | 
    
         
            +
                    cur->pen.alpha_blend = true;
         
     | 
| 
      
 1033 
     | 
    
         
            +
             
     | 
| 
      
 1034 
     | 
    
         
            +
            }
         
     | 
| 
      
 1035 
     | 
    
         
            +
             
     | 
| 
      
 1036 
     | 
    
         
            +
            static void
         
     | 
| 
      
 1037 
     | 
    
         
            +
            update_lazy_bounds(action_struct * cur, texture_info * tex)
         
     | 
| 
      
 1038 
     | 
    
         
            +
            {
         
     | 
| 
      
 1039 
     | 
    
         
            +
                
         
     | 
| 
      
 1040 
     | 
    
         
            +
                /* only update global bounds if we're doing a lazy_sync */
         
     | 
| 
      
 1041 
     | 
    
         
            +
                if(cur->sync_mode == lazy_sync) {
         
     | 
| 
      
 1042 
     | 
    
         
            +
                    int xmin, ymin, xmax, ymax;
         
     | 
| 
      
 1043 
     | 
    
         
            +
                    VALUE lazy_bounds;
         
     | 
| 
      
 1044 
     | 
    
         
            +
             
     | 
| 
      
 1045 
     | 
    
         
            +
                    lazy_bounds = get_image_local(tex->image, LAZY_BOUNDS);
         
     | 
| 
      
 1046 
     | 
    
         
            +
             
     | 
| 
      
 1047 
     | 
    
         
            +
                    xmin = INT2FIX(MIN(cur->xmin, FIX2INT(get_from_array(lazy_bounds, 0))));
         
     | 
| 
      
 1048 
     | 
    
         
            +
                    ymin = INT2FIX(MIN(cur->ymin, FIX2INT(get_from_array(lazy_bounds, 1))));
         
     | 
| 
      
 1049 
     | 
    
         
            +
                    xmax = INT2FIX(MAX(cur->xmax, FIX2INT(get_from_array(lazy_bounds, 2))));
         
     | 
| 
      
 1050 
     | 
    
         
            +
                    ymax = INT2FIX(MAX(cur->ymax, FIX2INT(get_from_array(lazy_bounds, 3))));
         
     | 
| 
      
 1051 
     | 
    
         
            +
             
     | 
| 
      
 1052 
     | 
    
         
            +
                    set_array_value(lazy_bounds, 0, xmin);
         
     | 
| 
      
 1053 
     | 
    
         
            +
                    set_array_value(lazy_bounds, 1, ymin);
         
     | 
| 
      
 1054 
     | 
    
         
            +
                    set_array_value(lazy_bounds, 2, xmax);
         
     | 
| 
      
 1055 
     | 
    
         
            +
                    set_array_value(lazy_bounds, 3, ymax);
         
     | 
| 
      
 1056 
     | 
    
         
            +
                }
         
     | 
| 
      
 1057 
     | 
    
         
            +
            }
         
     | 
| 
      
 1058 
     | 
    
         
            +
             
     | 
| 
      
 1059 
     | 
    
         
            +
            static void
         
     | 
| 
      
 1060 
     | 
    
         
            +
            update_bounds(action_struct * cur, int xmin, int ymin, int xmax, int ymax)
         
     | 
| 
      
 1061 
     | 
    
         
            +
            {
         
     | 
| 
      
 1062 
     | 
    
         
            +
                if(xmin > xmax) SWAP(xmin, xmax);
         
     | 
| 
      
 1063 
     | 
    
         
            +
                if(ymin > ymax) SWAP(ymin, ymax);
         
     | 
| 
      
 1064 
     | 
    
         
            +
                
         
     | 
| 
      
 1065 
     | 
    
         
            +
                cur->xmin = MIN(cur->xmin, xmin);
         
     | 
| 
      
 1066 
     | 
    
         
            +
                cur->ymin = MIN(cur->ymin, ymin);
         
     | 
| 
      
 1067 
     | 
    
         
            +
                cur->xmax = MAX(cur->xmax, xmax);
         
     | 
| 
      
 1068 
     | 
    
         
            +
                cur->ymax = MAX(cur->ymax, ymax);
         
     | 
| 
      
 1069 
     | 
    
         
            +
            }
         
     | 
| 
      
 1070 
     | 
    
         
            +
             
     | 
| 
      
 1071 
     | 
    
         
            +
            static void
         
     | 
| 
      
 1072 
     | 
    
         
            +
            set_local_bounds(action_struct * cur, int xmin, int ymin, int xmax, int ymax, texture_info * tex)
         
     | 
| 
      
 1073 
     | 
    
         
            +
            {
         
     | 
| 
      
 1074 
     | 
    
         
            +
                if(cur->sync_mode == no_sync)
         
     | 
| 
      
 1075 
     | 
    
         
            +
                    return;
         
     | 
| 
      
 1076 
     | 
    
         
            +
             
     | 
| 
      
 1077 
     | 
    
         
            +
                /* local bounds used by both eager_sync and lazy_sync: */
         
     | 
| 
      
 1078 
     | 
    
         
            +
                
         
     | 
| 
      
 1079 
     | 
    
         
            +
                /* eager sync: to demarcate precise area to sync to opengl */
         
     | 
| 
      
 1080 
     | 
    
         
            +
                /* lazy sync: to update global bounds */
         
     | 
| 
      
 1081 
     | 
    
         
            +
                cur->xmin = xmin;
         
     | 
| 
      
 1082 
     | 
    
         
            +
                cur->ymin = ymin;
         
     | 
| 
      
 1083 
     | 
    
         
            +
                cur->xmax = xmax;
         
     | 
| 
      
 1084 
     | 
    
         
            +
                cur->ymax = ymax;
         
     | 
| 
      
 1085 
     | 
    
         
            +
            }
         
     | 
| 
      
 1086 
     | 
    
         
            +
             
     | 
| 
      
 1087 
     | 
    
         
            +
            static void
         
     | 
| 
      
 1088 
     | 
    
         
            +
            draw_prologue(action_struct * cur, texture_info * tex, int xmin, int ymin, int xmax, int ymax,
         
     | 
| 
      
 1089 
     | 
    
         
            +
                          VALUE * hash_arg, sync sync_mode, bool primary, action_struct ** payload_ptr)
         
     | 
| 
      
 1090 
     | 
    
         
            +
            {
         
     | 
| 
      
 1091 
     | 
    
         
            +
                if(!primary) return;
         
     | 
| 
      
 1092 
     | 
    
         
            +
             
     | 
| 
      
 1093 
     | 
    
         
            +
                /* set the payload pointer */
         
     | 
| 
      
 1094 
     | 
    
         
            +
                *payload_ptr = cur;
         
     | 
| 
      
 1095 
     | 
    
         
            +
                
         
     | 
| 
      
 1096 
     | 
    
         
            +
                /* not too happy about having this here, look at texplay.h for why */
         
     | 
| 
      
 1097 
     | 
    
         
            +
                cur->tex = tex;
         
     | 
| 
      
 1098 
     | 
    
         
            +
                
         
     | 
| 
      
 1099 
     | 
    
         
            +
                process_common_hash_args(cur, hash_arg, sync_mode, primary);
         
     | 
| 
      
 1100 
     | 
    
         
            +
                
         
     | 
| 
      
 1101 
     | 
    
         
            +
                set_local_bounds(cur, xmin, ymin, xmax, ymax, tex);
         
     | 
| 
      
 1102 
     | 
    
         
            +
            }
         
     | 
| 
      
 1103 
     | 
    
         
            +
             
     | 
| 
      
 1104 
     | 
    
         
            +
            void
         
     | 
| 
      
 1105 
     | 
    
         
            +
            draw_epilogue(action_struct * cur, texture_info * tex, bool primary)
         
     | 
| 
      
 1106 
     | 
    
         
            +
            {
         
     | 
| 
      
 1107 
     | 
    
         
            +
                /* only primary actions get sync'd */
         
     | 
| 
      
 1108 
     | 
    
         
            +
                if(!primary) return;
         
     | 
| 
      
 1109 
     | 
    
         
            +
                
         
     | 
| 
      
 1110 
     | 
    
         
            +
                switch(cur->sync_mode) {
         
     | 
| 
      
 1111 
     | 
    
         
            +
             
     | 
| 
      
 1112 
     | 
    
         
            +
                    /* do not sync */
         
     | 
| 
      
 1113 
     | 
    
         
            +
                case no_sync:
         
     | 
| 
      
 1114 
     | 
    
         
            +
                    return;
         
     | 
| 
      
 1115 
     | 
    
         
            +
                    break;
         
     | 
| 
      
 1116 
     | 
    
         
            +
             
     | 
| 
      
 1117 
     | 
    
         
            +
                    /* sync immediately */
         
     | 
| 
      
 1118 
     | 
    
         
            +
                case eager_sync:
         
     | 
| 
      
 1119 
     | 
    
         
            +
                    create_subtexture_and_sync_to_gl(IMAGE_BOUNDS(cur), tex);
         
     | 
| 
      
 1120 
     | 
    
         
            +
                    break;
         
     | 
| 
      
 1121 
     | 
    
         
            +
             
     | 
| 
      
 1122 
     | 
    
         
            +
                    /* sync later (at end of paint block?) */
         
     | 
| 
      
 1123 
     | 
    
         
            +
                case lazy_sync:
         
     | 
| 
      
 1124 
     | 
    
         
            +
                    update_lazy_bounds(cur, tex);
         
     | 
| 
      
 1125 
     | 
    
         
            +
                    break;
         
     | 
| 
      
 1126 
     | 
    
         
            +
                    
         
     | 
| 
      
 1127 
     | 
    
         
            +
                default:
         
     | 
| 
      
 1128 
     | 
    
         
            +
                    rb_raise(rb_eRuntimeError,
         
     | 
| 
      
 1129 
     | 
    
         
            +
                             "sync_mode may only be: lazy_sync, eager_sync, no_sync. got %d\n", cur->sync_mode);
         
     | 
| 
      
 1130 
     | 
    
         
            +
                }
         
     | 
| 
      
 1131 
     | 
    
         
            +
            }
         
     | 
| 
      
 1132 
     | 
    
         
            +
             
     | 
| 
      
 1133 
     | 
    
         
            +
            /* set action color to return value of color_control proc */
         
     | 
| 
      
 1134 
     | 
    
         
            +
            static void
         
     | 
| 
      
 1135 
     | 
    
         
            +
            prepare_color_control(action_struct * cur)
         
     | 
| 
      
 1136 
     | 
    
         
            +
            {
         
     | 
| 
      
 1137 
     | 
    
         
            +
             
     | 
| 
      
 1138 
     | 
    
         
            +
                if(is_a_hash(cur->hash_arg)) {
         
     | 
| 
      
 1139 
     | 
    
         
            +
                    VALUE try_val = get_from_hash(cur->hash_arg, "color_control");
         
     | 
| 
      
 1140 
     | 
    
         
            +
                    
         
     | 
| 
      
 1141 
     | 
    
         
            +
                    if(rb_respond_to(try_val, rb_intern("call"))) {
         
     | 
| 
      
 1142 
     | 
    
         
            +
                        cur->pen.color_control_proc = try_val;
         
     | 
| 
      
 1143 
     | 
    
         
            +
                        cur->pen.color_control_arity = FIX2INT(rb_funcall(try_val, rb_intern("arity"), 0));
         
     | 
| 
      
 1144 
     | 
    
         
            +
                        cur->pen.has_color_control_proc = true;
         
     | 
| 
      
 1145 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1146 
     | 
    
         
            +
                    else if(is_a_hash(try_val)) {
         
     | 
| 
      
 1147 
     | 
    
         
            +
                        VALUE try_add = get_from_hash(try_val, "add");
         
     | 
| 
      
 1148 
     | 
    
         
            +
                        VALUE try_mult = get_from_hash(try_val, "mult");
         
     | 
| 
      
 1149 
     | 
    
         
            +
             
     | 
| 
      
 1150 
     | 
    
         
            +
                        if(is_an_array(try_add)) {
         
     | 
| 
      
 1151 
     | 
    
         
            +
                            if(RARRAY_LEN(try_add) < 4)
         
     | 
| 
      
 1152 
     | 
    
         
            +
                                rb_raise(rb_eArgError, ":color_control transform :add needs 4 parameters");
         
     | 
| 
      
 1153 
     | 
    
         
            +
                            
         
     | 
| 
      
 1154 
     | 
    
         
            +
                            cur->pen.color_add.red = NUM2DBL(get_from_array(try_add, 0));
         
     | 
| 
      
 1155 
     | 
    
         
            +
                            cur->pen.color_add.green = NUM2DBL(get_from_array(try_add, 1));
         
     | 
| 
      
 1156 
     | 
    
         
            +
                            cur->pen.color_add.blue = NUM2DBL(get_from_array(try_add, 2));
         
     | 
| 
      
 1157 
     | 
    
         
            +
                            cur->pen.color_add.alpha = NUM2DBL(get_from_array(try_add, 3));
         
     | 
| 
      
 1158 
     | 
    
         
            +
             
     | 
| 
      
 1159 
     | 
    
         
            +
                            cur->pen.has_color_control_transform = true;
         
     | 
| 
      
 1160 
     | 
    
         
            +
                        }
         
     | 
| 
      
 1161 
     | 
    
         
            +
                        if(is_an_array(try_mult)) {
         
     | 
| 
      
 1162 
     | 
    
         
            +
                            if(RARRAY_LEN(try_mult) < 4)
         
     | 
| 
      
 1163 
     | 
    
         
            +
                                rb_raise(rb_eArgError, ":color_control transform :mult needs 4 parameters");
         
     | 
| 
      
 1164 
     | 
    
         
            +
             
     | 
| 
      
 1165 
     | 
    
         
            +
                            cur->pen.color_mult.red = NUM2DBL(get_from_array(try_mult, 0));
         
     | 
| 
      
 1166 
     | 
    
         
            +
                            cur->pen.color_mult.green = NUM2DBL(get_from_array(try_mult, 1));
         
     | 
| 
      
 1167 
     | 
    
         
            +
                            cur->pen.color_mult.blue = NUM2DBL(get_from_array(try_mult, 2));
         
     | 
| 
      
 1168 
     | 
    
         
            +
                            cur->pen.color_mult.alpha = NUM2DBL(get_from_array(try_mult, 3));
         
     | 
| 
      
 1169 
     | 
    
         
            +
             
     | 
| 
      
 1170 
     | 
    
         
            +
                            cur->pen.has_color_control_transform = true;
         
     | 
| 
      
 1171 
     | 
    
         
            +
                        }
         
     | 
| 
      
 1172 
     | 
    
         
            +
                            
         
     | 
| 
      
 1173 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1174 
     | 
    
         
            +
                }
         
     | 
| 
      
 1175 
     | 
    
         
            +
            }
         
     | 
| 
      
 1176 
     | 
    
         
            +
             
     | 
| 
      
 1177 
     | 
    
         
            +
            static rgba 
         
     | 
| 
      
 1178 
     | 
    
         
            +
            exec_color_control_proc(action_struct * cur, texture_info * tex, int x, int y)
         
     | 
| 
      
 1179 
     | 
    
         
            +
            {
         
     | 
| 
      
 1180 
     | 
    
         
            +
                int arity = cur->pen.color_control_arity;
         
     | 
| 
      
 1181 
     | 
    
         
            +
                VALUE proc = cur->pen.color_control_proc;
         
     | 
| 
      
 1182 
     | 
    
         
            +
                rgba old_color = get_pixel_color(tex, x, y);
         
     | 
| 
      
 1183 
     | 
    
         
            +
                rgba current_color = cur->color;
         
     | 
| 
      
 1184 
     | 
    
         
            +
                rgba new_color;
         
     | 
| 
      
 1185 
     | 
    
         
            +
             
     | 
| 
      
 1186 
     | 
    
         
            +
                if(!cur->pen.has_color_control_proc)
         
     | 
| 
      
 1187 
     | 
    
         
            +
                    rb_raise(rb_eRuntimeError, "needs a proc");
         
     | 
| 
      
 1188 
     | 
    
         
            +
             
     | 
| 
      
 1189 
     | 
    
         
            +
                switch(arity) {
         
     | 
| 
      
 1190 
     | 
    
         
            +
                case 1:
         
     | 
| 
      
 1191 
     | 
    
         
            +
                    new_color = convert_rb_color_to_rgba(rb_funcall(proc, rb_intern("call"), arity,
         
     | 
| 
      
 1192 
     | 
    
         
            +
                                                                    convert_rgba_to_rb_color(&old_color)));
         
     | 
| 
      
 1193 
     | 
    
         
            +
                    break;
         
     | 
| 
      
 1194 
     | 
    
         
            +
                        
         
     | 
| 
      
 1195 
     | 
    
         
            +
                case 2:
         
     | 
| 
      
 1196 
     | 
    
         
            +
                    new_color = convert_rb_color_to_rgba(rb_funcall(proc, rb_intern("call"), arity,
         
     | 
| 
      
 1197 
     | 
    
         
            +
                                                                    convert_rgba_to_rb_color(&old_color),
         
     | 
| 
      
 1198 
     | 
    
         
            +
                                                                    convert_rgba_to_rb_color(¤t_color)));
         
     | 
| 
      
 1199 
     | 
    
         
            +
                    break;
         
     | 
| 
      
 1200 
     | 
    
         
            +
                        
         
     | 
| 
      
 1201 
     | 
    
         
            +
                case 3:
         
     | 
| 
      
 1202 
     | 
    
         
            +
                    new_color = convert_rb_color_to_rgba(rb_funcall(proc, rb_intern("call"), arity,
         
     | 
| 
      
 1203 
     | 
    
         
            +
                                                                    convert_rgba_to_rb_color(&old_color),
         
     | 
| 
      
 1204 
     | 
    
         
            +
                                                                    INT2FIX(x), INT2FIX(y)));
         
     | 
| 
      
 1205 
     | 
    
         
            +
                    break;
         
     | 
| 
      
 1206 
     | 
    
         
            +
                case 4:
         
     | 
| 
      
 1207 
     | 
    
         
            +
                    new_color = convert_rb_color_to_rgba(rb_funcall(proc, rb_intern("call"), arity,
         
     | 
| 
      
 1208 
     | 
    
         
            +
                                                                    convert_rgba_to_rb_color(&old_color),
         
     | 
| 
      
 1209 
     | 
    
         
            +
                                                                    convert_rgba_to_rb_color(¤t_color),
         
     | 
| 
      
 1210 
     | 
    
         
            +
                                                                    INT2FIX(x), INT2FIX(y)));
         
     | 
| 
      
 1211 
     | 
    
         
            +
                    break;
         
     | 
| 
      
 1212 
     | 
    
         
            +
                default:
         
     | 
| 
      
 1213 
     | 
    
         
            +
                    rb_raise(rb_eArgError, "permissible arities for color_control proc are 1, 2, 3  and 4. Got %d\n",
         
     | 
| 
      
 1214 
     | 
    
         
            +
                             arity);
         
     | 
| 
      
 1215 
     | 
    
         
            +
                }
         
     | 
| 
      
 1216 
     | 
    
         
            +
                    
         
     | 
| 
      
 1217 
     | 
    
         
            +
                /* update the action color */
         
     | 
| 
      
 1218 
     | 
    
         
            +
                return new_color;
         
     | 
| 
      
 1219 
     | 
    
         
            +
            }
         
     | 
| 
      
 1220 
     | 
    
         
            +
             
     | 
| 
      
 1221 
     | 
    
         
            +
            static void
         
     | 
| 
      
 1222 
     | 
    
         
            +
            prepare_fill_texture(action_struct * payload)
         
     | 
| 
      
 1223 
     | 
    
         
            +
            {
         
     | 
| 
      
 1224 
     | 
    
         
            +
                if(is_a_hash(payload->hash_arg)) {
         
     | 
| 
      
 1225 
     | 
    
         
            +
                    VALUE try_image = get_from_hash(payload->hash_arg, "texture");
         
     | 
| 
      
 1226 
     | 
    
         
            +
                    if(is_gosu_image(try_image)) {
         
     | 
| 
      
 1227 
     | 
    
         
            +
             
     | 
| 
      
 1228 
     | 
    
         
            +
                        get_texture_info(try_image, &payload->pen.source_tex);
         
     | 
| 
      
 1229 
     | 
    
         
            +
                        payload->pen.has_source_texture = true;
         
     | 
| 
      
 1230 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1231 
     | 
    
         
            +
                }
         
     | 
| 
      
 1232 
     | 
    
         
            +
            }
         
     | 
| 
      
 1233 
     | 
    
         
            +
             
     | 
| 
      
 1234 
     | 
    
         
            +
            static void
         
     | 
| 
      
 1235 
     | 
    
         
            +
            apply_color_control_transform(action_struct * payload, texture_info * tex, int x, int y)
         
     | 
| 
      
 1236 
     | 
    
         
            +
            {
         
     | 
| 
      
 1237 
     | 
    
         
            +
                payload->color = get_pixel_color(tex, x, y);
         
     | 
| 
      
 1238 
     | 
    
         
            +
                    
         
     | 
| 
      
 1239 
     | 
    
         
            +
                payload->color.red += payload->pen.color_add.red; 
         
     | 
| 
      
 1240 
     | 
    
         
            +
                payload->color.green += payload->pen.color_add.green; 
         
     | 
| 
      
 1241 
     | 
    
         
            +
                payload->color.blue += payload->pen.color_add.blue; 
         
     | 
| 
      
 1242 
     | 
    
         
            +
                payload->color.alpha += payload->pen.color_add.alpha;
         
     | 
| 
      
 1243 
     | 
    
         
            +
             
     | 
| 
      
 1244 
     | 
    
         
            +
                payload->color.red *= payload->pen.color_mult.red; 
         
     | 
| 
      
 1245 
     | 
    
         
            +
                payload->color.green *= payload->pen.color_mult.green; 
         
     | 
| 
      
 1246 
     | 
    
         
            +
                payload->color.blue *= payload->pen.color_mult.blue; 
         
     | 
| 
      
 1247 
     | 
    
         
            +
                payload->color.alpha *= payload->pen.color_mult.alpha;
         
     | 
| 
      
 1248 
     | 
    
         
            +
            }
         
     | 
| 
      
 1249 
     | 
    
         
            +
             
     | 
| 
      
 1250 
     | 
    
         
            +
            static void
         
     | 
| 
      
 1251 
     | 
    
         
            +
            set_pixel_color_with_style(action_struct * payload, texture_info * tex, int x, int y)
         
     | 
| 
      
 1252 
     | 
    
         
            +
            {
         
     | 
| 
      
 1253 
     | 
    
         
            +
             
     | 
| 
      
 1254 
     | 
    
         
            +
                rgba blended_pixel;
         
     | 
| 
      
 1255 
     | 
    
         
            +
             
     | 
| 
      
 1256 
     | 
    
         
            +
                /* for color_control transform */
         
     | 
| 
      
 1257 
     | 
    
         
            +
                if(payload->pen.has_color_control_transform)
         
     | 
| 
      
 1258 
     | 
    
         
            +
                    apply_color_control_transform(payload, tex, x, y);
         
     | 
| 
      
 1259 
     | 
    
         
            +
                
         
     | 
| 
      
 1260 
     | 
    
         
            +
                /*    for texture fill  */
         
     | 
| 
      
 1261 
     | 
    
         
            +
                if(payload->pen.has_source_texture)
         
     | 
| 
      
 1262 
     | 
    
         
            +
                    payload->color = get_pixel_color(&payload->pen.source_tex,
         
     | 
| 
      
 1263 
     | 
    
         
            +
                                                     x % payload->pen.source_tex.width,
         
     | 
| 
      
 1264 
     | 
    
         
            +
                                                     y % payload->pen.source_tex.height);
         
     | 
| 
      
 1265 
     | 
    
         
            +
             
     | 
| 
      
 1266 
     | 
    
         
            +
                /* for color_control block */
         
     | 
| 
      
 1267 
     | 
    
         
            +
                if(payload->pen.has_color_control_proc)
         
     | 
| 
      
 1268 
     | 
    
         
            +
                    payload->color = exec_color_control_proc(payload, tex, x,  y);
         
     | 
| 
      
 1269 
     | 
    
         
            +
                
         
     | 
| 
      
 1270 
     | 
    
         
            +
             
     | 
| 
      
 1271 
     | 
    
         
            +
                /*  TO DO: do bitwise pixel combinations here */
         
     | 
| 
      
 1272 
     | 
    
         
            +
                
         
     | 
| 
      
 1273 
     | 
    
         
            +
                /* if i do not use blended_pixel and instead use payload->color in the
         
     | 
| 
      
 1274 
     | 
    
         
            +
                   code below i get an interesting blurring effect in images (with alpha_blend => true)
         
     | 
| 
      
 1275 
     | 
    
         
            +
                */
         
     | 
| 
      
 1276 
     | 
    
         
            +
                blended_pixel = payload->color;
         
     | 
| 
      
 1277 
     | 
    
         
            +
                
         
     | 
| 
      
 1278 
     | 
    
         
            +
                
         
     | 
| 
      
 1279 
     | 
    
         
            +
                /*  alpha blending
         
     | 
| 
      
 1280 
     | 
    
         
            +
                    TO DO: refactor into its own helper function
         
     | 
| 
      
 1281 
     | 
    
         
            +
                    & rewrite using sse2 */
         
     | 
| 
      
 1282 
     | 
    
         
            +
                if(payload->pen.alpha_blend) {
         
     | 
| 
      
 1283 
     | 
    
         
            +
                    rgba dest_pixel = get_pixel_color(tex, x, y);
         
     | 
| 
      
 1284 
     | 
    
         
            +
                        
         
     | 
| 
      
 1285 
     | 
    
         
            +
                    /* alpha blending is nothing more than a weighted average of src and dest pixels
         
     | 
| 
      
 1286 
     | 
    
         
            +
                       based on source alpha value */
         
     | 
| 
      
 1287 
     | 
    
         
            +
                    /* NB: destination alpha value is ignored */
         
     | 
| 
      
 1288 
     | 
    
         
            +
                    if(is_a_color(payload->color) && is_a_color(dest_pixel)) {
         
     | 
| 
      
 1289 
     | 
    
         
            +
             
     | 
| 
      
 1290 
     | 
    
         
            +
                        /** TO DO: rewrite this using sse2 instructions **/
         
     | 
| 
      
 1291 
     | 
    
         
            +
                        blended_pixel.red = payload->color.alpha * payload->color.red + (1 - payload->color.alpha)
         
     | 
| 
      
 1292 
     | 
    
         
            +
                            * dest_pixel.red;
         
     | 
| 
      
 1293 
     | 
    
         
            +
             
     | 
| 
      
 1294 
     | 
    
         
            +
                        blended_pixel.green = payload->color.alpha * payload->color.green + (1 - payload->color.alpha)
         
     | 
| 
      
 1295 
     | 
    
         
            +
                            * dest_pixel.green;
         
     | 
| 
      
 1296 
     | 
    
         
            +
             
     | 
| 
      
 1297 
     | 
    
         
            +
                        blended_pixel.blue = payload->color.alpha * payload->color.blue + (1 - payload->color.alpha)
         
     | 
| 
      
 1298 
     | 
    
         
            +
                            * dest_pixel.blue;
         
     | 
| 
      
 1299 
     | 
    
         
            +
             
     | 
| 
      
 1300 
     | 
    
         
            +
                        blended_pixel.alpha = payload->color.alpha;
         
     | 
| 
      
 1301 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1302 
     | 
    
         
            +
                }
         
     | 
| 
      
 1303 
     | 
    
         
            +
             
     | 
| 
      
 1304 
     | 
    
         
            +
                set_pixel_color(&blended_pixel, tex, x, y);
         
     | 
| 
      
 1305 
     | 
    
         
            +
            }
         
     | 
| 
      
 1306 
     | 
    
         
            +
             
     |