Line data Source code
1 : /* Copyright (C) 2000-2012 by George Williams */
2 : /*
3 : * Redistribution and use in source and binary forms, with or without
4 : * modification, are permitted provided that the following conditions are met:
5 :
6 : * Redistributions of source code must retain the above copyright notice, this
7 : * list of conditions and the following disclaimer.
8 :
9 : * Redistributions in binary form must reproduce the above copyright notice,
10 : * this list of conditions and the following disclaimer in the documentation
11 : * and/or other materials provided with the distribution.
12 :
13 : * The name of the author may not be used to endorse or promote products
14 : * derived from this software without specific prior written permission.
15 :
16 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 : * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 : * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 : * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 : * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 : * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 : * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 : * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 : * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 : */
27 : #include "cvundoes.h"
28 : #include "fontforgeui.h"
29 : #include "nonlineartrans.h"
30 :
31 : #include <math.h>
32 :
33 0 : void CVMouseDownTransform(CharView *cv) {
34 0 : CVPreserveTState(cv);
35 0 : }
36 :
37 0 : void CVMouseMoveTransform(CharView *cv) {
38 : real transform[6];
39 :
40 0 : CVRestoreTOriginalState(cv);
41 0 : if ( cv->info.x != cv->p.cx || cv->info.y != cv->p.cy ) {
42 0 : transform[0] = transform[3] = 1;
43 0 : transform[1] = transform[2] = 0;
44 0 : switch ( cv->active_tool ) {
45 : case cvt_rotate: {
46 0 : real angle = atan2(cv->info.y-cv->p.cy,cv->info.x-cv->p.cx);
47 0 : transform[0] = transform[3] = cos(angle);
48 0 : transform[2] = -(transform[1] = sin(angle));
49 0 : } break;
50 : case cvt_flip: {
51 : real dx,dy;
52 0 : if (( dx = cv->info.x-cv->p.cx)<0 ) dx=-dx;
53 0 : if (( dy = cv->info.y-cv->p.cy)<0 ) dy=-dy;
54 0 : if ( dy>2*dx )
55 0 : transform[0] = -1;
56 0 : else if ( dx>2*dy )
57 0 : transform[3] = -1;
58 0 : else if ( (cv->info.x-cv->p.cx)*(cv->info.y-cv->p.cy)>0 ) {
59 0 : transform[0] = transform[3] = 0;
60 0 : transform[1] = transform[2] = -1;
61 : } else {
62 0 : transform[0] = transform[3] = 0;
63 0 : transform[1] = transform[2] = 1;
64 : }
65 0 : } break;
66 : case cvt_scale: {
67 0 : transform[0] = 1.0+(cv->info.x-cv->p.cx)/(400*cv->scale);
68 0 : transform[3] = 1.0+(cv->info.y-cv->p.cy)/(400*cv->scale);
69 0 : } break;
70 : case cvt_skew: {
71 0 : real angle = atan2(cv->info.y-cv->p.cy,cv->info.x-cv->p.cx);
72 0 : transform[2] = sin(angle);
73 0 : } break;
74 : case cvt_3d_rotate: {
75 0 : real angle = atan2(cv->info.y-cv->p.cy,cv->info.x-cv->p.cx);
76 : /* Allow one pixel per degree */
77 0 : real zangle = sqrt( (cv->info.x-cv->p.cx)*(cv->info.x-cv->p.cx) +
78 0 : (cv->info.y-cv->p.cy)*(cv->info.y-cv->p.cy) ) * cv->scale *
79 : 3.1415926535897932/180;
80 0 : real s = sin(angle), c = cos(angle);
81 0 : real cz = cos(zangle);
82 0 : transform[0] = c*c + s*s*cz;
83 0 : transform[3] = s*s + c*c*cz;
84 0 : transform[2] = transform[1] = c*s * (cz-1);
85 0 : } break;
86 : /* Perspective takes three points: origin, start point, cur point */
87 : /* first rotate so that orig/start are the x axis */
88 : /* then define perspective so that: */
89 : /* y' = y */
90 : /* x' = cur.x + (cur.y - y)/cur.y * (x - cur.x) */
91 : /* then rotate back */
92 : case cvt_perspective: {
93 0 : real angle = atan2(cv->p.cy,cv->p.cx);
94 0 : real s = sin(angle), c = cos(angle);
95 0 : transform[0] = transform[3] = c;
96 0 : transform[2] = -(transform[1] = -s);
97 0 : transform[4] = transform[5] = 0;
98 0 : CVTransFunc(cv,transform,false);
99 0 : CVYPerspective((CharViewBase *) cv,
100 0 : c*cv->info.x + s*cv->info.y,
101 0 : -s*cv->info.x + c*cv->info.y);
102 0 : transform[2] = -(transform[1] = s);
103 0 : } break;
104 : default:
105 0 : break;
106 : }
107 : /* Make the pressed point be the center of the transformation */
108 0 : if ( cv->active_tool!=cvt_perspective ) {
109 0 : transform[4] = -cv->p.cx*transform[0] -
110 0 : cv->p.cy*transform[2] +
111 0 : cv->p.cx;
112 0 : transform[5] = -cv->p.cy*transform[3] -
113 0 : cv->p.cx*transform[1] +
114 0 : cv->p.cy;
115 : }
116 0 : CVSetCharChanged(cv,true);
117 0 : CVTransFunc(cv,transform,false);
118 : }
119 0 : SCUpdateAll(cv->b.sc);
120 0 : CVGridHandlePossibleFitChar(cv);
121 0 : }
122 :
123 0 : void CVMouseUpTransform(CharView *cv) {
124 0 : if ( cv->info.x == cv->p.cx && cv->info.y == cv->p.cy )
125 : {
126 : /* Nothing happened */
127 0 : cv->needsrasterize = cv->recentchange = false;
128 0 : CVRemoveTopUndo(&cv->b);
129 0 : SCUpdateAll(cv->b.sc);
130 0 : CVGridHandlePossibleFitChar(cv);
131 : }
132 : else
133 : {
134 0 : CVUndoCleanup(cv);
135 : }
136 0 : }
|