Initial import
[flexagon-toolkit.git] / src / diagram / gimp_diagram.py
1 #!/usr/bin/env python
2 #
3 # A diagram class to draw in Gimp
4 #
5 # Copyright (C) 2018  Antonio Ospite <ao2@ao2.it>
6 #
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
20 import warnings
21 from gimpfu import *
22
23 from .diagram import Diagram
24
25
26 class GimpDiagram(Diagram):
27     def __init__(self, width, height, image, layer, **kwargs):
28         super(GimpDiagram, self).__init__(width, height, **kwargs)
29
30         self.image = image
31         self.drawable = layer
32
33     def color_to_rgba(self, color):
34         color = super(GimpDiagram, self).color_to_rgba(color)
35         if color[3] != 1.0:
36             warnings.warn("Warning, trasparent colors are not supported", stacklevel=4)
37
38         return color
39
40     def clear(self):
41         pass
42
43     def _polygon_path(self, verts):
44         path = pdb.gimp_vectors_new(self.image, "")
45
46         v0 = verts[0]
47         strokeid = pdb.gimp_vectors_bezier_stroke_new_moveto(path,
48                                                              v0[0], v0[1])
49         for v in verts[1:]:
50             pdb.gimp_vectors_bezier_stroke_lineto(path, strokeid, v[0], v[1])
51
52         pdb.gimp_vectors_stroke_close(path, strokeid)
53
54         return path
55
56     def _fill_path(self, path, fill_color):
57         if fill_color:
58             orig_foreground = pdb.gimp_context_get_foreground()
59             orig_selection = pdb.gimp_selection_save(self.image)
60
61             color = self.color_to_rgba(fill_color)
62             pdb.gimp_context_set_foreground(color)
63
64             pdb.gimp_image_select_item(self.image, CHANNEL_OP_REPLACE, path)
65
66             pdb.gimp_edit_fill(self.drawable, FOREGROUND_FILL)
67
68             pdb.gimp_selection_load(orig_selection)
69             pdb.gimp_image_remove_channel(self.image, orig_selection)
70             pdb.gimp_context_set_foreground(orig_foreground)
71
72     def _stroke_path(self, path, stroke_color):
73         if stroke_color:
74             orig_paint_method = pdb.gimp_context_get_paint_method()
75             orig_foreground = pdb.gimp_context_get_foreground()
76             orig_brush = pdb.gimp_context_get_brush()
77
78             pdb.gimp_context_set_paint_method('gimp-paintbrush')
79
80             color = self.color_to_rgba(stroke_color)
81             pdb.gimp_context_set_foreground(color)
82             pdb.gimp_context_set_brush("1. Pixel")
83             pdb.gimp_context_set_brush_size(self.stroke_width)
84
85             pdb.gimp_edit_stroke_vectors(self.drawable, path)
86
87             pdb.gimp_context_set_brush(orig_brush)
88             pdb.gimp_context_set_foreground(orig_foreground)
89             pdb.gimp_context_set_paint_method(orig_paint_method)
90
91     def draw_star_by_verts(self, cx, cy, verts, stroke_color=(0, 0, 0)):
92         path = pdb.gimp_vectors_new(self.image, "")
93
94         for v in verts:
95             strokeid = pdb.gimp_vectors_bezier_stroke_new_moveto(path, cx, cy)
96             pdb.gimp_vectors_bezier_stroke_lineto(path, strokeid, v[0], v[1])
97
98         pdb.gimp_image_insert_vectors(self.image, path, None, -1)
99         pdb.gimp_image_set_active_vectors(self.image, path)
100
101         self._stroke_path(path, stroke_color)
102
103         pdb.gimp_image_remove_vectors(self.image, path)
104
105     def draw_polygon_by_verts(self, verts,
106                               stroke_color=(0, 0, 0),
107                               fill_color=None):
108         path = self._polygon_path(verts)
109
110         pdb.gimp_image_insert_vectors(self.image, path, None, -1)
111         pdb.gimp_image_set_active_vectors(self.image, path)
112
113         self._fill_path(path, fill_color)
114         self._stroke_path(path, stroke_color)
115
116         pdb.gimp_image_remove_vectors(self.image, path)
117
118     def copy_polygon(self, src_drawable, verts, dest_drawable, matrix):
119         # flatten the verts list to be accepted by gimp_image_select_polygon()
120         segs = [coord for v in verts for coord in v]
121         pdb.gimp_image_select_polygon(self.image, CHANNEL_OP_REPLACE, len(segs), segs)
122
123         pdb.gimp_edit_copy(src_drawable)
124         floating_layer = pdb.gimp_edit_paste(dest_drawable, FALSE)
125
126         pdb.gimp_item_transform_matrix(floating_layer,
127                                        matrix[0], matrix[1], matrix[2],
128                                        matrix[3], matrix[4], matrix[5],
129                                        matrix[6], matrix[7], matrix[8])
130
131         pdb.gimp_floating_sel_anchor(floating_layer)
132
133     def draw_centered_text(self, cx, cy, text, theta, color,
134                            align_baseline=False,
135                            bb_stroke_color=None,
136                            bb_fill_color=None):
137         font_name = "Georgia"
138
139         width, height, ascent, descent = pdb.gimp_text_get_extents_fontname(text,
140                                                                             self.font_size,
141                                                                             PIXELS,
142                                                                             font_name)
143
144         tx = cx - width / 2.0
145         ty = cy - height / 2.0
146
147         floating_selection = pdb.gimp_text_fontname(self.image, self.drawable,
148                                                     tx, ty, text, 0, True,
149                                                     self.font_size,
150                                                     PIXELS,
151                                                     font_name)
152
153         text_color = self.color_to_rgba(color)
154         pdb.gimp_text_layer_set_color(floating_selection, text_color)
155
156         pdb.gimp_item_transform_rotate(floating_selection, theta, FALSE, cx, cy)
157         pdb.gimp_floating_sel_anchor(floating_selection)
158
159         if align_baseline:
160             warnings.warn("The align_baseline option has not been implemented yet.")
161
162         if bb_stroke_color or bb_fill_color:
163             warnings.warn("Drawing the bounding box has not been implemented yet.")