]> Shamusworld >> Repos - ttedit/blob - src/charwindow.cpp
Minor changes: Supply a reasonable default epsilon to vector::zero() and
[ttedit] / src / charwindow.cpp
1 //
2 // TTEDIT.CPP - The TrueType Editor
3 // by James L. Hammons
4 // (C) 2004 Underground Software
5 //
6 // JLH = James L. Hammons <jlhamm@acm.org>
7 //
8 // Who  When        What
9 // ---  ----------  -------------------------------------------------------------
10 // JLH  08/28/2008  Created this file
11 // JLH  03/19/2009  Converted from wxWidgets to Qt
12 // JLH  03/21/2009  Fixed main screen points rendering
13 //
14
15 // FIXED:
16 //
17 // - Render of main window points [DONE]
18 //
19 // STILL TO BE DONE:
20 //
21 // - Fix "window disappears when tool win comes up" problem
22 //
23
24 #include "charwindow.h"
25 #include "debug.h"
26
27 CharWindow::CharWindow(QWidget * parent/*= NULL*/): QWidget(parent, Qt::Tool), path(NULL)
28 {
29         setWindowTitle("Character: Unknown");
30 }
31
32 void CharWindow::MakePathFromPoints(GlyphPoints * gp)
33 {
34         if (gp == NULL)
35                 return;
36
37         if (path != NULL)
38                 delete path;
39
40         path = new QPainterPath();
41 //      path->setFillRule(Qt::OddEvenFill);
42         path->setFillRule(Qt::WindingFill);
43
44         // Draw curve formed by points
45
46         for(int poly=0; poly<gp->GetNumPolys(); poly++)
47         {
48                 if (gp->GetNumPoints(poly) > 2)
49                 {
50                         // Initial move...
51                         // If last point is on curve then move to it, otherwise move to first point...
52
53 //NOTE: This is basically doing the below for i=-1.
54 //      Find some way to integrate this crap.
55 /*
56 Could do in pairs: get i and i+1, connect them depending on whether the pair
57 is a line or a curve.
58 4 cases: on to on (line),
59          on to off (begin curve),
60          off to on (end curve),
61          off to off (begin curve)
62 */
63 #if 1
64                         for(int i=0; i<gp->GetNumPoints(poly); i++)
65                         {
66                                 if (i == 0)
67                                 {
68                                         IPoint pt = (gp->GetOnCurve(poly, 0)
69                                                 ? gp->GetPoint(poly, 0) : (gp->GetPrevOnCurve(poly, 0)
70                                                         ? gp->GetPrevPoint(poly, 0) : gp->GetMidpointToPrev(poly, 0)));
71                                         path->moveTo(pt.x, pt.y);
72                                 }
73
74                                 if (gp->GetOnCurve(poly, i) && gp->GetNextOnCurve(poly, i))
75                                 {
76                                         // Handle lines...
77                                         path->lineTo(gp->GetNextX(poly, i), gp->GetNextY(poly, i));
78                                 }
79                                 else
80                                 {
81                                         // Skip point if it's on curve (start of curve--it's already
82                                         // been plotted so we don't care about it...
83                                         if (gp->GetOnCurve(poly, i))
84                                                 i++;
85
86                                         // We may have moved past the end; if not, handle curve
87                                         if (i < gp->GetNumPoints(poly))
88                                         {
89                                                 // Handle curves...
90                                                 IPoint pt = (gp->GetNextOnCurve(poly, i)
91                                                         ? gp->GetNextPoint(poly, i) : gp->GetMidpointToNext(poly, i));
92
93                                                 path->quadTo(gp->GetX(poly, i), gp->GetY(poly, i), pt.x, pt.y);
94                                         }
95                                 }
96                         }
97 #else
98                         IPoint pt;
99
100                         if (gp->GetPrevOnCurve(poly, 0))
101                                 pt = gp->GetPrevPoint(poly, 0);
102                         else
103                                 pt = (gp->GetOnCurve(poly, 0)
104                                         ? gp->GetPoint(poly, 0) : gp->GetMidpointToPrev(poly, 0));
105
106                         path->moveTo(pt.x, pt.y);
107
108                         for(int i=0; i<gp->GetNumPoints(poly); i++)
109                         {
110                                 if (gp->GetOnCurve(poly, i))
111                                         path->lineTo(gp->GetX(poly, i), gp->GetY(poly, i));
112                                 else
113                                 {
114                                         pt = (gp->GetNextOnCurve(poly, i)
115                                                 ? gp->GetNextPoint(poly, i) : gp->GetMidpointToNext(poly, i));
116
117                                         path->quadTo(gp->GetX(poly, i), gp->GetY(poly, i), pt.x, pt.y);
118
119                                         // If following point is on curve, move past it
120                                         if (gp->GetNextOnCurve(poly, i))
121                                                 i++;
122                                 }
123                         }
124 #endif
125
126                         path->closeSubpath();
127                 }
128         }
129 }
130
131 QSize CharWindow::minimumSizeHint() const
132 {
133         return QSize(50, 50);
134 }
135
136 QSize CharWindow::sizeHint() const
137 {
138         return QSize(200, 200);
139 }
140
141 void CharWindow::paintEvent(QPaintEvent * /*event*/)
142 {
143         if (path == NULL)
144                 return;
145
146         QPainter p(this);
147
148         p.setPen(QPen(Qt::black, 1.0, Qt::SolidLine));
149 //      p.setBrush(QColor(122, 163, 39));
150         p.setBrush(Qt::black);
151
152 /*
153 1.0 -> 3.0, height = 400
154 r.h / ps.h = 2/400 <-- do it the other way!
155
156 height works, width does not
157
158 2-step process:
159 compare aspect ratios
160
161 ps.w - ((r.h / ps.h) * ps.w)
162
163 0.5 -> where in the 400? -> 100
164 0.5/r.h(2.0) = 0.25 * ps.h(400) = 100
165 conv.fac. -> (ps.h / r.h)
166 */
167         QRectF rect = path->boundingRect();
168         QSize paintSize = size();
169
170         p.translate(0, paintSize.height());
171         float extraX = 0.0f, extraY = 0.0f;
172         float xConvFac = (float)paintSize.width() / rect.width();
173         float yConvFac = (float)paintSize.height() / rect.height();
174
175         if (xConvFac > yConvFac)
176         {
177                 // height is limiting factor
178                 p.scale(yConvFac, -yConvFac);
179                 extraX = (((float)paintSize.width() / yConvFac) - rect.width()) / 2.0f;
180         }
181         else
182         {
183                 // width is limiting factor
184                 p.scale(xConvFac, -xConvFac);
185 //extraY = (rect.width() / (float)paintSize.width()) * (float)paintSize.height();
186 //extraY = (extraY - rect.height()) / 2.0f;
187                 extraY = (((float)paintSize.height() / xConvFac) - rect.height()) / 2.0f;
188         }
189
190         p.translate(-rect.x() + extraX, -rect.y() + extraY);
191
192         p.drawPath(*path);
193 }