1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 #include "preferences.h"
32 /** Calculate the width (in cm) of the gap between grid lines in dynamic
36 calculate_dynamic_grid(DDisplay
*ddisp
, real
*width_x
, real
*width_y
)
38 real zoom
= ddisplay_untransform_length(ddisp
, 1.0);
39 /* Twiddle zoom to make change-over appropriate */
41 return pow(10, ceil(log10(zoom
)));
45 grid_draw_horizontal_lines(DDisplay
*ddisp
, Rectangle
*update
, real length
)
50 guint major_lines
= ddisp
->diagram
->data
->grid
.major_lines
;
51 DiaRenderer
*renderer
= ddisp
->renderer
;
52 DiaInteractiveRendererInterface
*irenderer
;
55 irenderer
= DIA_GET_INTERACTIVE_RENDERER_INTERFACE (renderer
);
57 pos
= ceil( update
->top
/ length
) * length
;
58 ddisplay_transform_coords(ddisp
, update
->left
, pos
, &x
, &y
);
59 ddisplay_transform_coords(ddisp
, update
->right
, update
->bottom
, &width
, &height
);
62 major_count
= pos
/length
;
63 major_count
%= major_lines
;
69 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_SOLID
);
71 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_DOTTED
);
72 major_count
= (major_count
+1)%major_lines
;
74 irenderer
->draw_pixel_line(renderer
, x
, y
, width
, y
,
75 &ddisp
->diagram
->data
->grid
.colour
);
77 ddisplay_transform_coords(ddisp
, update
->left
, pos
, &x
, &y
);
82 grid_draw_vertical_lines(DDisplay
*ddisp
, Rectangle
*update
, real length
)
87 guint major_lines
= ddisp
->diagram
->data
->grid
.major_lines
;
88 DiaRenderer
*renderer
= ddisp
->renderer
;
89 DiaInteractiveRendererInterface
*irenderer
;
92 irenderer
= DIA_GET_INTERACTIVE_RENDERER_INTERFACE (renderer
);
94 pos
= ceil( update
->left
/ length
) * length
;
95 ddisplay_transform_coords(ddisp
, update
->right
, update
->bottom
, &width
, &height
);
98 major_count
= pos
/length
;
99 major_count
%= major_lines
;
103 ddisplay_transform_coords(ddisp
, pos
, update
->top
, &x
, &y
);
105 if (major_count
== 0)
106 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_SOLID
);
108 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_DOTTED
);
109 major_count
= (major_count
+1)%major_lines
;
111 irenderer
->draw_pixel_line(renderer
, x
, y
, x
, height
,
112 &ddisp
->diagram
->data
->grid
.colour
);
118 grid_draw(DDisplay
*ddisp
, Rectangle
*update
)
120 Grid
*grid
= &ddisp
->grid
;
121 DiaRenderer
*renderer
= ddisp
->renderer
;
125 int width
= dia_renderer_get_width_pixels(ddisp
->renderer
);
126 int height
= dia_renderer_get_height_pixels(ddisp
->renderer
);
127 /* distance between visible grid lines */
128 real width_x
= ddisp
->diagram
->data
->grid
.width_x
;
129 real width_y
= ddisp
->diagram
->data
->grid
.width_y
;
130 if (ddisp
->diagram
->data
->grid
.dynamic
) {
131 width_x
= width_y
= calculate_dynamic_grid(ddisp
, &width_x
, &width_y
);
133 width_x
= ddisp
->diagram
->data
->grid
.width_x
*
134 ddisp
->diagram
->data
->grid
.visible_x
;
135 width_y
= ddisp
->diagram
->data
->grid
.width_y
*
136 ddisp
->diagram
->data
->grid
.visible_y
;
139 DIA_RENDERER_GET_CLASS(renderer
)->set_linewidth(renderer
, 0.0);
140 DIA_RENDERER_GET_CLASS(renderer
)->set_dashlength(renderer
,
141 ddisplay_untransform_length(ddisp
, 31));
143 if (ddisplay_transform_length(ddisp
, width_y
) >= 2.0 &&
144 ddisplay_transform_length(ddisp
, width_x
) >= 2.0) {
145 /* Vertical lines: */
146 grid_draw_vertical_lines(ddisp
, update
, width_x
);
147 /* Horizontal lines: */
148 grid_draw_horizontal_lines(ddisp
, update
, width_y
);
154 pagebreak_draw(DDisplay
*ddisp
, Rectangle
*update
)
156 DiaRenderer
*renderer
= ddisp
->renderer
;
157 DiaInteractiveRendererInterface
*irenderer
;
159 int width
= dia_renderer_get_width_pixels(ddisp
->renderer
);
160 int height
= dia_renderer_get_height_pixels(ddisp
->renderer
);
162 irenderer
= DIA_GET_INTERACTIVE_RENDERER_INTERFACE (renderer
);
163 if (prefs
.pagebreak
.visible
) {
164 Diagram
*dia
= ddisp
->diagram
;
165 real origx
= 0, origy
= 0, pos
;
166 real pwidth
= dia
->data
->paper
.width
;
167 real pheight
= dia
->data
->paper
.height
;
170 DIA_RENDERER_GET_CLASS(renderer
)->set_linewidth(renderer
, 0.0);
171 DIA_RENDERER_GET_CLASS(renderer
)->set_dashlength(renderer
,
172 ddisplay_untransform_length(ddisp
, 31));
173 if (prefs
.pagebreak
.solid
)
174 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_SOLID
);
176 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_DOTTED
);
178 if (dia
->data
->paper
.fitto
) {
179 origx
= dia
->data
->extents
.left
;
180 origy
= dia
->data
->extents
.top
;
183 /* vertical lines ... */
184 pos
= origx
+ ceil((update
->left
- origx
) / pwidth
) * pwidth
;
185 while (pos
<= update
->right
) {
186 ddisplay_transform_coords(ddisp
, pos
,0,&x
,&y
);
187 irenderer
->draw_pixel_line(renderer
,
189 &dia
->data
->pagebreak_color
);
192 /* Horizontal lines: */
193 pos
= origy
+ ceil((update
->top
- origy
) / pheight
) * pheight
;
194 while (pos
<= update
->bottom
) {
195 ddisplay_transform_coords(ddisp
, 0,pos
,&x
,&y
);
196 irenderer
->draw_pixel_line(renderer
,
198 &dia
->data
->pagebreak_color
);
205 snap_to_grid(DDisplay
*ddisp
, coord
*x
, coord
*y
)
207 if (ddisp
->grid
.snap
) {
208 real width_x
= ddisp
->diagram
->data
->grid
.width_x
;
209 real width_y
= ddisp
->diagram
->data
->grid
.width_y
;
210 if (prefs
.grid
.dynamic
) {
211 calculate_dynamic_grid(ddisp
, &width_x
, &width_y
);
213 *x
= ROUND((*x
) / width_x
) * width_x
;
214 *y
= ROUND((*y
) / width_y
) * width_y
;