]> Shamusworld >> Repos - ttedit/blob - src/charwindow.cpp
Added preview window to file loading dialog. :-)
[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
28 CharWindow::CharWindow(QWidget * parent/*= NULL*/): QWidget(parent, Qt::Window), path(NULL)
29 {
30         setWindowTitle("Character: Unknown");
31 }
32
33
34 QPainterPath * CharWindow::MakePathFromPoints(GlyphPoints * gp)
35 {
36         if (gp == NULL)
37                 return NULL;
38
39         if (path != NULL)
40                 delete path;
41
42         path = new QPainterPath();
43 //      path->setFillRule(Qt::OddEvenFill);
44         path->setFillRule(Qt::WindingFill);
45
46         // Draw curve formed by points
47
48         for(int poly=0; poly<gp->GetNumPolys(); poly++)
49         {
50                 if (gp->GetNumPoints(poly) < 3)
51                         continue;
52
53                 // Initial move: If our start point is on curve, then go to it.
54                 // Otherwise, check previous point. If it's on curve, go to it
55                 // otherwise go the midpoint between start point and previous (since
56                 // it's between two curve control points).
57                 IPoint pt = (gp->GetOnCurve(poly, 0)
58                         ? gp->GetPoint(poly, 0) : (gp->GetPrevOnCurve(poly, 0)
59                                 ? gp->GetPrevPoint(poly, 0) : gp->GetMidpointToPrev(poly, 0)));
60                 path->moveTo(pt.x, pt.y);
61
62                 for(int i=0; i<gp->GetNumPoints(poly); i++)
63                 {
64                         // If this point and then next are both on curve, we have a line...
65                         if (gp->GetOnCurve(poly, i) && gp->GetNextOnCurve(poly, i))
66                                 path->lineTo(gp->GetNextX(poly, i), gp->GetNextY(poly, i));
67                         else
68                         {
69                                 // Skip point if it's on curve (start of curve--it's already
70                                 // been plotted so we don't need to handle it...)
71                                 if (gp->GetOnCurve(poly, i))
72                                         continue;
73
74                                 // We are now guaranteed that we are sitting on a curve control
75                                 // point (off curve). Figure the extent of the curve: If the
76                                 // following is a curve control point, then use the midpoint to
77                                 // it otherwise go to the next point since it's on curve.
78                                 IPoint pt = (gp->GetNextOnCurve(poly, i)
79                                         ? gp->GetNextPoint(poly, i) : gp->GetMidpointToNext(poly, i));
80
81                                 path->quadTo(gp->GetX(poly, i), gp->GetY(poly, i), pt.x, pt.y);
82                         }
83                 }
84
85                 path->closeSubpath();
86         }
87
88         return path;
89 }
90
91
92 void CharWindow::RenderPathInImage(QPainterPath * path, QImage * img)
93 {
94         if ((path == NULL) || (img == NULL))
95                 return;
96
97         QPainter p(img);
98
99         p.setPen(QPen(Qt::black, 1.0, Qt::SolidLine));
100         p.setBrush(Qt::black);
101
102         QRectF rect = path->boundingRect();
103         QSize paintSize = img->size();
104
105 #if 0
106         // For some reason, this code cuts off two pixels when rendering the path.
107         // Not sure why, but we compensate for that here.
108         paintSize.rwidth() -= 2;
109         paintSize.rheight() -= 2;
110 #endif
111
112         p.translate(0, paintSize.height());
113         float extraX = 0.0f, extraY = 0.0f;
114         float xConvFac = (float)paintSize.width() / rect.width();
115         float yConvFac = (float)paintSize.height() / rect.height();
116
117         if (xConvFac > yConvFac)
118         {
119                 // height is limiting factor (smaller than width)
120                 p.scale(yConvFac, -yConvFac);
121                 extraX = (((float)paintSize.width() / yConvFac) - rect.width()) / 2.0f;
122         }
123         else
124         {
125                 // width is limiting factor (smaller than height)
126                 p.scale(xConvFac, -xConvFac);
127                 extraY = (((float)paintSize.height() / xConvFac) - rect.height()) / 2.0f;
128         }
129
130         p.translate(-rect.x() + extraX, -rect.y() + extraY);
131         p.drawPath(*path);
132 }
133
134
135 QSize CharWindow::minimumSizeHint() const
136 {
137         return QSize(50, 50);
138 }
139
140
141 QSize CharWindow::sizeHint() const
142 {
143         return QSize(200, 200);
144 }
145
146
147 void CharWindow::paintEvent(QPaintEvent * /*event*/)
148 {
149         if (path == NULL)
150                 return;
151
152         QPainter p(this);
153
154 //      p.setBrush(QColor(0, 163, 200));        // Nice, aqua color...
155         p.setPen(QPen(Qt::black, 1.0, Qt::SolidLine));
156         p.setBrush(Qt::black);
157
158         QRectF rect = path->boundingRect();
159         QSize paintSize = size();
160
161         // For some reason, this code cuts off two pixels when rendering the path.
162         // Not sure why, but we compensate for that here.
163         paintSize.rwidth() -= 2;
164         paintSize.rheight() -= 2;
165
166         p.translate(0, paintSize.height());
167         float extraX = 0.0f, extraY = 0.0f;
168         float xConvFac = (float)paintSize.width() / rect.width();
169         float yConvFac = (float)paintSize.height() / rect.height();
170
171         if (xConvFac > yConvFac)
172         {
173                 // height is limiting factor (smaller than width)
174                 p.scale(yConvFac, -yConvFac);
175                 extraX = (((float)paintSize.width() / yConvFac) - rect.width()) / 2.0f;
176         }
177         else
178         {
179                 // width is limiting factor (smaller than height)
180                 p.scale(xConvFac, -xConvFac);
181                 extraY = (((float)paintSize.height() / xConvFac) - rect.height()) / 2.0f;
182         }
183
184         p.translate(-rect.x() + extraX, -rect.y() + extraY);
185
186         p.drawPath(*path);
187 }
188