1 /*$
2  Copyright (C) 2013-2020 Azel.
3 
4  This file is part of AzPainter.
5 
6  AzPainter is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  AzPainter is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 $*/
19 
20 /*****************************************
21  * DrawData
22  *
23  * キャンバス関連
24  *****************************************/
25 
26 #include "mDef.h"
27 #include "mWidgetDef.h"
28 
29 #include "defMacros.h"
30 #include "defConfig.h"
31 
32 #include "defDraw.h"
33 #include "draw_main.h"
34 #include "draw_calc.h"
35 
36 #include "MainWinCanvas.h"
37 #include "Docks_external.h"
38 
39 
40 
41 /** キャンバスの描画を低品質に */
42 
drawCanvas_lowQuality()43 void drawCanvas_lowQuality()
44 {
45 	APP_DRAW->bCanvasLowQuality = 1;
46 }
47 
48 /** キャンバスの描画品質を元に戻す */
49 
drawCanvas_normalQuality()50 void drawCanvas_normalQuality()
51 {
52 	APP_DRAW->bCanvasLowQuality = 0;
53 }
54 
55 /** スクロールリセット (値のみ)
56  *
57  * イメージ原点位置をセットして、スクロール位置を (0,0) にする。
58  *
59  * @param origin イメージ原点位置。NULL で現在のキャンバス中央。 */
60 
drawCanvas_setScrollReset(DrawData * p,mDoublePoint * origin)61 void drawCanvas_setScrollReset(DrawData *p,mDoublePoint *origin)
62 {
63 	if(origin)
64 	{
65 		p->imgoriginX = origin->x;
66 		p->imgoriginY = origin->y;
67 	}
68 	else
69 		drawCalc_getImagePos_atCanvasCenter(p, &p->imgoriginX, &p->imgoriginY);
70 
71 	p->ptScroll.x = p->ptScroll.y = 0;
72 }
73 
74 /** スクロールリセット (更新も行う) */
75 
drawCanvas_setScrollReset_update(DrawData * p,mDoublePoint * origin)76 void drawCanvas_setScrollReset_update(DrawData *p,mDoublePoint *origin)
77 {
78 	drawCanvas_setScrollReset(p, origin);
79 	drawCanvas_setZoomAndAngle(p, 0, 0, 0, FALSE);
80 }
81 
82 /** スクロール位置をデフォルトに (画像の中央を原点位置とする) */
83 
drawCanvas_setScrollDefault(DrawData * p)84 void drawCanvas_setScrollDefault(DrawData *p)
85 {
86 	p->imgoriginX = p->imgw * 0.5;
87 	p->imgoriginY = p->imgh * 0.5;
88 	p->ptScroll.x = p->ptScroll.y = 0;
89 }
90 
91 /** 表示倍率を一段階上げ下げ */
92 
drawCanvas_zoomStep(DrawData * p,mBool zoomup)93 void drawCanvas_zoomStep(DrawData *p,mBool zoomup)
94 {
95 	drawCanvas_setZoomAndAngle(p,
96 		drawCalc_getZoom_step(p, zoomup), 0, 1, TRUE);
97 }
98 
99 /** 一段階左右に回転 */
100 
drawCanvas_rotateStep(DrawData * p,mBool left)101 void drawCanvas_rotateStep(DrawData *p,mBool left)
102 {
103 	int step;
104 
105 	step = APP_CONF->canvasAngleStep;
106 	if(left) step = -step;
107 
108 	drawCanvas_setZoomAndAngle(p, 0, p->canvas_angle + step * 100, 2, TRUE);
109 }
110 
111 /** キャンバスをウィンドウに合わせる
112  *
113  * イメージ全体がキャンバス内に収まるように倍率セット。 */
114 
drawCanvas_fitWindow(DrawData * p)115 void drawCanvas_fitWindow(DrawData *p)
116 {
117 	drawCanvas_setScrollDefault(p);
118 
119 	drawCanvas_setZoomAndAngle(p,
120 		drawCalc_getZoom_fitWindow(p), 0, 3, FALSE);
121 }
122 
123 /** キャンバス左右反転表示切り替え */
124 
drawCanvas_mirror(DrawData * p)125 void drawCanvas_mirror(DrawData *p)
126 {
127 	mDoublePoint pt;
128 
129 	drawCalc_getImagePos_atCanvasCenter(p, &pt.x, &pt.y);
130 
131 	p->canvas_mirror ^= 1;
132 
133 	drawCanvas_setScrollReset(p, &pt);
134 
135 	drawCanvas_setZoomAndAngle(p, 0, -(p->canvas_angle), 2, FALSE);
136 }
137 
138 /** キャンバスの領域サイズ変更時 */
139 
drawCanvas_setAreaSize(DrawData * p,int w,int h)140 void drawCanvas_setAreaSize(DrawData *p,int w,int h)
141 {
142 	p->szCanvas.w = w;
143 	p->szCanvas.h = h;
144 
145 	//メインウィンドウ、スクロール情報変更
146 
147 	MainWinCanvas_setScrollInfo();
148 }
149 
150 /** キャンバス表示倍率と回転角度をセット
151  *
152  * 値を変更せずに更新のみを行う場合にも使う。
153  * [!] キャンバスのスクロールバー範囲が変更される。
154  *
155  * @param flags [0bit] 倍率変更 [1bit] 角度変更 [2bit]キャンバス更新しない
156  * @param reset_scroll スクロールを現在のキャンバス中央位置にリセット */
157 
drawCanvas_setZoomAndAngle(DrawData * p,int zoom,int angle,int flags,mBool reset_scroll)158 void drawCanvas_setZoomAndAngle(DrawData *p,int zoom,int angle,int flags,mBool reset_scroll)
159 {
160 	//スクロールリセット
161 	//[!] すでにスクロール位置が (0,0) ならそのまま
162 
163 	if(reset_scroll && (p->ptScroll.x || p->ptScroll.y))
164 		drawCanvas_setScrollReset(p, NULL);
165 
166 	//倍率
167 
168 	if(flags & 1)
169 	{
170 		if(zoom < CANVAS_ZOOM_MIN)
171 			zoom = CANVAS_ZOOM_MIN;
172 		else if(zoom > CANVAS_ZOOM_MAX)
173 			zoom = CANVAS_ZOOM_MAX;
174 
175 		p->canvas_zoom = zoom;
176 	}
177 
178 	//角度
179 
180 	if(flags & 2)
181 	{
182 		if(angle < -18000)
183 			angle += 36000;
184 		else if(angle > 18000)
185 			angle -= 36000;
186 
187 		p->canvas_angle = angle;
188 	}
189 
190 	//CanvasViewParam セット
191 
192 	drawCalc_setCanvasViewParam(p);
193 
194 	//メインウィンドウのスクロール
195 
196 	MainWinCanvas_setScrollInfo();
197 
198 	//ほか、関連するウィジェット
199 
200 	DockCanvasCtrl_setPos();
201 
202 	//更新
203 
204 	if(!(flags & DRAW_SETZOOMANDANGLE_F_NO_UPDATE))
205 		drawUpdate_canvasArea();
206 }
207