1 /* base class for drawing operations
2 *
3 * 27/9/10
4 * - from im_draw_circle()
5 * 17/11/10
6 * - oops, scanline clipping was off by 1
7 */
8
9 /*
10
11 This file is part of VIPS.
12
13 VIPS is free software; you can redistribute it and/or modify
14 it under the terms of the GNU Lesser General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU Lesser General Public License for more details.
22
23 You should have received a copy of the GNU Lesser General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 02110-1301 USA
27
28 */
29
30 /*
31
32 These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
33
34 */
35
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif /*HAVE_CONFIG_H*/
39 #include <vips/intl.h>
40
41 #include <string.h>
42
43 #include <vips/vips.h>
44 #include <vips/internal.h>
45
46 #include "pdraw.h"
47
48 /**
49 * SECTION: draw
50 * @short_description: drawing operations: flood, paste, line, circle
51 * @stability: Stable
52 * @include: vips/vips.h
53 *
54 * These operations directly modify the image. They do not thread, on 32-bit
55 * machines they will be limited to 2GB images, and a little care needs to be
56 * taken if you use them as part of an image pipeline.
57 * They are mostly supposed to be useful for paintbox-style programs.
58 *
59 * libvips operations are all functional: they take zero or more existing input
60 * images and generate zero or more new output images. Images are
61 * never altered, you always create new images. This means libvips can cache
62 * and thread very agressively.
63 *
64 * The downside is that creating entirely fresh images each time can be very
65 * slow. libvips has a range of tricks to avoid these problems, but there are
66 * still times when you really have to be able to modify an image. An example
67 * might be drawing a curved line from a set of straight line segments: if you
68 * need to draw 1,000 straight lines, a 1,000 operation-deep pipeline is going
69 * to be a slow way to do it. This is where the draw operations come in.
70 *
71 * To use these operations, use vips_copy() to make a copy of the image you
72 * want to modify to ensure that no one else is using it, then call a
73 * series of draw operations.
74 * Once you are done drawing, return to normal use of vips operations. Any time
75 * you want to start drawing again, you'll need to copy again.
76 */
77
78 /**
79 * VipsCombineMode:
80 * @VIPS_COMBINE_MODE_SET: set pixels to the new value
81 * @VIPS_COMBINE_MODE_ADD: add pixels
82 *
83 * See vips_draw_image() and so on.
84 *
85 * Operations like vips_draw_image() need to be told how to combine images
86 * from two sources.
87 *
88 * See also: vips_join().
89 */
90
91 G_DEFINE_ABSTRACT_TYPE( VipsDraw, vips_draw, VIPS_TYPE_OPERATION );
92
93 static int
vips_draw_build(VipsObject * object)94 vips_draw_build( VipsObject *object )
95 {
96 VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
97 VipsDraw *draw = VIPS_DRAW( object );
98
99 #ifdef DEBUG
100 printf( "vips_draw_build: " );
101 vips_object_print_name( object );
102 printf( "\n" );
103 #endif /*DEBUG*/
104
105 if( VIPS_OBJECT_CLASS( vips_draw_parent_class )->build( object ) )
106 return( -1 );
107
108 if( vips_check_coding_known( class->nickname, draw->image ) ||
109 vips_image_inplace( draw->image ) )
110 return( -1 );
111
112 draw->lsize = VIPS_IMAGE_SIZEOF_LINE( draw->image );
113 draw->psize = VIPS_IMAGE_SIZEOF_PEL( draw->image );
114 draw->noclip = FALSE;
115
116 return( 0 );
117 }
118
119 static void
vips_draw_class_init(VipsDrawClass * class)120 vips_draw_class_init( VipsDrawClass *class )
121 {
122 GObjectClass *gobject_class = G_OBJECT_CLASS( class );
123 VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class );
124
125 gobject_class->set_property = vips_object_set_property;
126 gobject_class->get_property = vips_object_get_property;
127
128 vobject_class->nickname = "draw";
129 vobject_class->description = _( "draw operations" );
130 vobject_class->build = vips_draw_build;
131
132 VIPS_ARG_IMAGE( class, "image", 1,
133 _( "Image" ),
134 _( "Image to draw on" ),
135 VIPS_ARGUMENT_REQUIRED_INPUT | VIPS_ARGUMENT_MODIFY,
136 G_STRUCT_OFFSET( VipsDraw, image ) );
137
138 }
139
140 static void
vips_draw_init(VipsDraw * draw)141 vips_draw_init( VipsDraw *draw )
142 {
143 }
144
145 void
vips_draw_operation_init(void)146 vips_draw_operation_init( void )
147 {
148 extern GType vips_draw_rect_get_type( void );
149 extern GType vips_draw_image_get_type( void );
150 extern GType vips_draw_mask_get_type( void );
151 extern GType vips_draw_line_get_type( void );
152 extern GType vips_draw_circle_get_type( void );
153 extern GType vips_draw_flood_get_type( void );
154 extern GType vips_draw_smudge_get_type( void );
155
156 vips_draw_rect_get_type();
157 vips_draw_image_get_type();
158 vips_draw_mask_get_type();
159 vips_draw_line_get_type();
160 vips_draw_circle_get_type();
161 vips_draw_flood_get_type();
162 vips_draw_smudge_get_type();
163 }
164
165