#############################################################################
# Makefile for building: ttedit
-# Generated by qmake (2.01a) (Qt 4.8.2) on: Fri Sep 14 09:37:18 2012
+# Generated by qmake (2.01a) (Qt 4.8.3) on: Sat Nov 17 12:34:10 2012
# Project: ttedit.pro
# Template: app
# Command: /usr/bin/qmake -o Makefile ttedit.pro
INCPATH = -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -Iobj
LINK = g++
LFLAGS = -Wl,-O1
-LIBS = $(SUBLIBS) -L/usr/lib64/qt4 -lQtGui -L/usr/lib64 -L/usr/lib64/qt4 -L/usr/X11R6/lib -lQtCore -lglib-2.0 -lgthread-2.0 -lrt -lpthread
+LIBS = $(SUBLIBS) -L/usr/lib64/qt4 -lQtGui -L/usr/lib64 -L/usr/lib64/qt4 -L/usr/X11R6/lib -lQtCore -lgthread-2.0 -lrt -lglib-2.0 -lpthread
AR = ar cqs
RANLIB =
QMAKE = /usr/bin/qmake
####### Files
SOURCES = src/ttedit.cpp \
- src/ttemainwindow.cpp \
+ src/mainwindow.cpp \
src/editwindow.cpp \
src/glyphpoints.cpp \
src/debug.cpp \
src/toolwindow.cpp \
src/charwindow.cpp \
src/vector.cpp \
- src/graphicprimitives.cpp obj/moc_ttemainwindow.cpp \
+ src/graphicprimitives.cpp obj/moc_mainwindow.cpp \
obj/moc_editwindow.cpp \
obj/moc_toolwindow.cpp \
obj/moc_charwindow.cpp \
obj/qrc_ttedit.cpp
OBJECTS = obj/ttedit.o \
- obj/ttemainwindow.o \
+ obj/mainwindow.o \
obj/editwindow.o \
obj/glyphpoints.o \
obj/debug.o \
obj/charwindow.o \
obj/vector.o \
obj/graphicprimitives.o \
- obj/moc_ttemainwindow.o \
+ obj/moc_mainwindow.o \
obj/moc_editwindow.o \
obj/moc_toolwindow.o \
obj/moc_charwindow.o \
dist:
@$(CHK_DIR_EXISTS) obj/ttedit1.0.0 || $(MKDIR) obj/ttedit1.0.0
- $(COPY_FILE) --parents $(SOURCES) $(DIST) obj/ttedit1.0.0/ && $(COPY_FILE) --parents src/ttedit.h src/ttemainwindow.h src/editwindow.h src/glyphpoints.h src/types.h src/debug.h src/toolwindow.h src/charwindow.h src/vector.h src/graphicprimitives.h src/list.h obj/ttedit1.0.0/ && $(COPY_FILE) --parents ttedit.qrc obj/ttedit1.0.0/ && $(COPY_FILE) --parents src/ttedit.cpp src/ttemainwindow.cpp src/editwindow.cpp src/glyphpoints.cpp src/debug.cpp src/toolwindow.cpp src/charwindow.cpp src/vector.cpp src/graphicprimitives.cpp obj/ttedit1.0.0/ && (cd `dirname obj/ttedit1.0.0` && $(TAR) ttedit1.0.0.tar ttedit1.0.0 && $(COMPRESS) ttedit1.0.0.tar) && $(MOVE) `dirname obj/ttedit1.0.0`/ttedit1.0.0.tar.gz . && $(DEL_FILE) -r obj/ttedit1.0.0
+ $(COPY_FILE) --parents $(SOURCES) $(DIST) obj/ttedit1.0.0/ && $(COPY_FILE) --parents src/ttedit.h src/mainwindow.h src/editwindow.h src/glyphpoints.h src/types.h src/debug.h src/toolwindow.h src/charwindow.h src/vector.h src/graphicprimitives.h src/list.h obj/ttedit1.0.0/ && $(COPY_FILE) --parents ttedit.qrc obj/ttedit1.0.0/ && $(COPY_FILE) --parents src/ttedit.cpp src/mainwindow.cpp src/editwindow.cpp src/glyphpoints.cpp src/debug.cpp src/toolwindow.cpp src/charwindow.cpp src/vector.cpp src/graphicprimitives.cpp obj/ttedit1.0.0/ && (cd `dirname obj/ttedit1.0.0` && $(TAR) ttedit1.0.0.tar ttedit1.0.0 && $(COMPRESS) ttedit1.0.0.tar) && $(MOVE) `dirname obj/ttedit1.0.0`/ttedit1.0.0.tar.gz . && $(DEL_FILE) -r obj/ttedit1.0.0
clean:compiler_clean
mocables: compiler_moc_header_make_all compiler_moc_source_make_all
-compiler_moc_header_make_all: obj/moc_ttemainwindow.cpp obj/moc_editwindow.cpp obj/moc_toolwindow.cpp obj/moc_charwindow.cpp
+compiler_moc_header_make_all: obj/moc_mainwindow.cpp obj/moc_editwindow.cpp obj/moc_toolwindow.cpp obj/moc_charwindow.cpp
compiler_moc_header_clean:
- -$(DEL_FILE) obj/moc_ttemainwindow.cpp obj/moc_editwindow.cpp obj/moc_toolwindow.cpp obj/moc_charwindow.cpp
-obj/moc_ttemainwindow.cpp: src/ttemainwindow.h
- /usr/bin/moc $(DEFINES) $(INCPATH) src/ttemainwindow.h -o obj/moc_ttemainwindow.cpp
+ -$(DEL_FILE) obj/moc_mainwindow.cpp obj/moc_editwindow.cpp obj/moc_toolwindow.cpp obj/moc_charwindow.cpp
+obj/moc_mainwindow.cpp: src/mainwindow.h
+ /usr/bin/moc $(DEFINES) $(INCPATH) src/mainwindow.h -o obj/moc_mainwindow.cpp
obj/moc_editwindow.cpp: src/types.h \
src/toolwindow.h \
res/act-charwin.png \
res/act-forward.png \
res/cursor2.png \
+ res/cursor9.png \
res/cursor4.png
/usr/bin/rcc -name ttedit ttedit.qrc -o obj/qrc_ttedit.cpp
####### Compile
obj/ttedit.o: src/ttedit.cpp src/ttedit.h \
- src/ttemainwindow.h
+ src/mainwindow.h
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o obj/ttedit.o src/ttedit.cpp
-obj/ttemainwindow.o: src/ttemainwindow.cpp src/ttemainwindow.h \
- src/editwindow.h \
+obj/mainwindow.o: src/mainwindow.cpp src/mainwindow.h \
+ src/charwindow.h \
+ src/glyphpoints.h \
src/types.h \
+ src/editwindow.h \
src/toolwindow.h \
- src/glyphpoints.h \
- src/charwindow.h \
src/ttedit.h \
src/debug.h \
res/cur1.xpm \
res/tool1.xpm \
res/tool2.xpm \
res/tool3.xpm
- $(CXX) -c $(CXXFLAGS) $(INCPATH) -o obj/ttemainwindow.o src/ttemainwindow.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o obj/mainwindow.o src/mainwindow.cpp
obj/editwindow.o: src/editwindow.cpp src/editwindow.h \
src/types.h \
src/toolwindow.h \
src/glyphpoints.h \
- src/graphicprimitives.h \
- src/debug.h \
- src/vector.h \
src/charwindow.h \
- src/ttedit.h
+ src/debug.h \
+ src/graphicprimitives.h \
+ src/mainwindow.h \
+ src/ttedit.h \
+ src/vector.h
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o obj/editwindow.o src/editwindow.cpp
obj/glyphpoints.o: src/glyphpoints.cpp src/glyphpoints.h \
src/types.h
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o obj/graphicprimitives.o src/graphicprimitives.cpp
-obj/moc_ttemainwindow.o: obj/moc_ttemainwindow.cpp
- $(CXX) -c $(CXXFLAGS) $(INCPATH) -o obj/moc_ttemainwindow.o obj/moc_ttemainwindow.cpp
+obj/moc_mainwindow.o: obj/moc_mainwindow.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o obj/moc_mainwindow.o obj/moc_mainwindow.cpp
obj/moc_editwindow.o: obj/moc_editwindow.cpp
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o obj/moc_editwindow.o obj/moc_editwindow.cpp
/* XPM */
static const char * toolpal1_xpm[] = {
-"96 48 2 1",
+"120 48 2 1",
" c #000000",
". c #FFFFFF",
-" ",
-" .................. .................. .................. .................. ",
-" ",
-" . .................. . . .................. . . .................. . . .................. . ",
-" . .... ............. . . .................. . . ........ ........ . . .................. . ",
-" . .... ............ . . .................. . . ........ ........ . . ...... .......... . ",
-" . .... ........... . . .. ............... . . ....... ....... . . .... .. ........ . ",
-" . .... .......... . . .. .............. . . ....... ....... . . ... ...... ....... . ",
-" . .... ......... . . .. ............. . . ...... . . ...... . . ... ...... ....... . ",
-" . .... ........ . . .. ............ . . ..... .. .. ..... . . .. ........ ...... . ",
-" . .... ....... . . .. ... .. . . ... ... ... ... . . .. ........ ...... . ",
-" . .... ...... . . .. .. . . . . . . . ... ...... ....... . ",
-" . .... ..... . . .. . ... . . . . . . . ... ...... ....... . ",
-" . .... ........ . . .. ... ... . . . ... ... ... ... . . .... .. ...... . ",
-" . .... ........ . . .. ... . . . ..... .. .. ..... . . ...... .. ..... . ",
-" . .... .. ....... . . .. .. .. .. . . ...... . . ...... . . ........... .... . ",
-" . .... ... ....... . . ...... .. ...... . . ....... ....... . . ............ ... . ",
-" . ......... ...... . . .......... ...... . . ....... ....... . . ............. .. . ",
-" . ......... ...... . . .......... ...... . . ........ ........ . . .............. .. . ",
-" . .......... ....... . . .................. . . ........ ........ . . .................. . ",
-" . .................. . . .................. . . .................. . . .................. . ",
-" ",
-" .................. .................. .................. .................. ",
-" ",
-" ",
-" .................. .................. .................. .................. ",
-" ",
-" . .................. . . .................. . . .................. . . .................. . ",
-" . .................. . . .................. . . .................. . . .................. . ",
-" . .................. . . ........ ........ . . .. .......... .. . . .. ........... .. . ",
-" . .................. . . ....... ....... . . .. ........ .. . . ... . .. .. . ",
-" . .................. . . ....... ....... . . ... ...... ... . . .... ... . ",
-" . ....... ....... . . ...... .. ...... . . .... .... . . ..... ... .... . ",
-" . ...... ...... . . ...... .. ...... . . ..... ..... . . ...... ... ..... . ",
-" . ..... ..... . . ..... .... ..... . . ..... ..... . . ...... . ..... . ",
-" . ..... .. ..... . . ..... .... ..... . . ..... ..... . . ...... ..... . ",
-" . ..... .. ..... . . .... ...... .... . . ..... ..... . . ...... ..... . ",
-" . ..... ..... . . .... ...... .... . . ..... ..... . . ...... ...... . ",
-" . ...... ...... . . ... ........ ... . . ..... ..... . . ...... ... ..... . ",
-" . ....... ....... . . ... ........ ... . . .... .... . . ..... .... .... . ",
-" . .................. . . .. .......... .. . . ... ...... ... . . .... ..... ... . ",
-" . .................. . . .. .. . . .. ........ .. . . ... . ...... .. . ",
-" . .................. . . ... ... . . .. .......... .. . . .. ........... .. . ",
-" . .................. . . .................. . . .................. . . .................. . ",
-" . .................. . . .................. . . .................. . . .................. . ",
-" ",
-" .................. .................. .................. .................. ",
-" "};
+" ",
+" .................. .................. .................. .................. .................. ",
+" ",
+" . .................. . . .................. . . .................. . . .................. . . ....... ....... . ",
+" . .... ............. . . .................. . . ........ ........ . . .................. . . ...... ...... . ",
+" . .... ............ . . .................. . . ........ ........ . . ...... .......... . . .... . . .... . ",
+" . .... ........... . . .. ............... . . ....... ....... . . .... .. ........ . . ... .. .... .. ... . ",
+" . .... .......... . . .. .............. . . ....... ....... . . ... ...... ....... . . .. .. ...... .. .. . ",
+" . .... ......... . . .. ............. . . ...... . . ...... . . ... ...... ....... . . .. ............ .. . ",
+" . .... ........ . . .. ............ . . ..... .. .. ..... . . .. ........ ...... . . . ...... ...... . . ",
+" . .... ....... . . .. ... .. . . ... ... ... ... . . .. ........ ...... . . . ...... ...... . . ",
+" . .... ...... . . .. .. . . . . . . . ... ...... ....... . . . .... .... . . ",
+" . .... ..... . . .. . ... . . . . . . . ... ...... ....... . . . .... .... . . ",
+" . .... ........ . . .. ... ... . . . ... ... ... ... . . .... .. ...... . . . ...... ...... . . ",
+" . .... ........ . . .. ... . . . ..... .. .. ..... . . ...... .. ..... . . . ...... ...... . . ",
+" . .... .. ....... . . .. .. .. .. . . ...... . . ...... . . ........... .... . . .. ............ .. . ",
+" . .... ... ....... . . ...... .. ...... . . ....... ....... . . ............ ... . . .. ............ .. . ",
+" . ......... ...... . . .......... ...... . . ....... ....... . . ............. .. . . ... .......... ... . ",
+" . ......... ...... . . .......... ...... . . ........ ........ . . .............. .. . . .... ...... .... . ",
+" . .......... ....... . . .................. . . ........ ........ . . .................. . . ...... ...... . ",
+" . .................. . . .................. . . .................. . . .................. . . .................. . ",
+" ",
+" .................. .................. .................. .................. .................. ",
+" ",
+" ",
+" .................. .................. .................. .................. .................. ",
+" ",
+" . .................. . . .................. . . .................. . . .................. . . .................. . ",
+" . .................. . . .................. . . .................. . . .................. . . .................. . ",
+" . .................. . . ........ ........ . . .. .......... .. . . .. ........... .. . . .................. . ",
+" . .................. . . ....... ....... . . .. ........ .. . . ... . .. .. . . .................. . ",
+" . .................. . . ....... ....... . . ... ...... ... . . .... ... . . .................. . ",
+" . ....... ....... . . ...... .. ...... . . .... .... . . ..... ... .... . . .................. . ",
+" . ...... ...... . . ...... .. ...... . . ..... ..... . . ...... ... ..... . . .................. . ",
+" . ..... ..... . . ..... .... ..... . . ..... ..... . . ...... . ..... . . .................. . ",
+" . ..... .. ..... . . ..... .... ..... . . ..... ..... . . ...... ..... . . .................. . ",
+" . ..... .. ..... . . .... ...... .... . . ..... ..... . . ...... ..... . . .................. . ",
+" . ..... ..... . . .... ...... .... . . ..... ..... . . ...... ...... . . .................. . ",
+" . ...... ...... . . ... ........ ... . . ..... ..... . . ...... ... ..... . . .................. . ",
+" . ....... ....... . . ... ........ ... . . .... .... . . ..... .... .... . . .................. . ",
+" . .................. . . .. .......... .. . . ... ...... ... . . .... ..... ... . . .................. . ",
+" . .................. . . .. .. . . .. ........ .. . . ... . ...... .. . . .................. . ",
+" . .................. . . ... ... . . .. .......... .. . . .. ........... .. . . .................. . ",
+" . .................. . . .................. . . .................. . . .................. . . .................. . ",
+" . .................. . . .................. . . .................. . . .................. . . .................. . ",
+" ",
+" .................. .................. .................. .................. .................. ",
+" "};
#include "charwindow.h"
#include "debug.h"
-CharWindow::CharWindow(QWidget * parent/*= NULL*/): QWidget(parent, Qt::Tool), path(NULL)
+//CharWindow::CharWindow(QWidget * parent/*= NULL*/): QWidget(parent, Qt::Tool), path(NULL)
+CharWindow::CharWindow(QWidget * parent/*= NULL*/): QWidget(parent, Qt::Window), path(NULL)
{
setWindowTitle("Character: Unknown");
}
#define DEBUGTP // Toolpalette debugging...
#include "editwindow.h"
-//#include <QtGui>
-#include "graphicprimitives.h"
-#include "debug.h"
-#include "vector.h"
#include "charwindow.h"
+#include "debug.h"
+#include "graphicprimitives.h"
+#include "mainwindow.h"
#include "ttedit.h"
+#include "vector.h"
+
EditWindow::EditWindow(QWidget * parent/*= NULL*/): QWidget(parent),
scale(1.0), offsetX(-10), offsetY(-10), tool(TOOLSelect),
ptHighlight(-1), oldPtHighlight(-1), ptNextHighlight(-1), oldPtNextHighlight(-1),
- polyFirstPoint(true)
+ polyFirstPoint(true), showRotationCenter(false), haveZeroPoint(false)
{
setBackgroundRole(QPalette::Base);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
setMouseTracking(true);
}
+
QSize EditWindow::minimumSizeHint() const
{
return QSize(50, 50);
}
+
QSize EditWindow::sizeHint() const
{
return QSize(400, 400);
}
+
void EditWindow::CreateCursors(void)
{
- int hotx[8] = { 1, 1, 11, 15, 1, 1, 1, 1 };
- int hoty[8] = { 1, 1, 11, 13, 1, 1, 1, 1 };
+ int hotx[9] = { 1, 1, 11, 15, 1, 1, 1, 1, 1 };
+ int hoty[9] = { 1, 1, 11, 13, 1, 1, 1, 1, 1 };
- for(int i=0; i<8; i++)
+ for(int i=0; i<9; i++)
{
QString s;
s.sprintf(":/res/cursor%u.png", i+1);
}
}
+
QPoint EditWindow::GetAdjustedMousePosition(QMouseEvent * event)
{
QSize winSize = size();
return QPoint(offsetX + event->x(), offsetY + (winSize.height() - event->y()));
}
+
QPoint EditWindow::GetAdjustedClientPosition(int x, int y)
{
QSize winSize = size();
return QPoint(-offsetX + x, (winSize.height() - (-offsetY + y)) * +1.0);
}
+
/*
TODO:
o Different colors for polys on selected points
//// dc.DrawLine(0, 0, 10, 10);
p.setPen(QPen(Qt::blue, 1.0, Qt::DotLine));
- // Draw coordinate axes
+ // Draw coordinate axes
// dc.CrossHair(0, 0);
p.drawLine(0, -16384, 0, 16384);
p.drawLine(-16384, 0, 16384, 0);
- // Draw points
+ // Draw rotation center (if active)
+
+ if (showRotationCenter)
+ {
+ p.setPen(QPen(Qt::red, 2.0, Qt::SolidLine));
+ p.drawLine(rotationCenter.x() + 7, rotationCenter.y(), rotationCenter.x() - 7, rotationCenter.y());
+ p.drawLine(rotationCenter.x(), rotationCenter.y() + 7, rotationCenter.x(), rotationCenter.y() - 7);
+ }
+
+ // Draw points
for(int i=0; i<pts.GetNumPoints(); i++)
{
}
}
}
+
+ if (haveZeroPoint)
+ {
+ // Rotation code
+ GlyphPoints rotated = pts;
+ rotated.RotatePoints(rotationAngle, IPoint(rotationCenter.x(), rotationCenter.y()));
+ p.setPen(QPen(QColor(255, 0, 255), 1.0, Qt::SolidLine));
+#if 0
+ for(int poly=0; poly<rotated.GetNumPolys(); poly++)
+ {
+ if (rotated.GetNumPoints(poly) > 2)
+ {
+ // Initial move...
+ // If it's not on curve, then move to it, otherwise move to last point...
+
+ int x, y;
+
+ if (rotated.GetOnCurve(poly, rotated.GetNumPoints(poly) - 1))
+ x = (int)rotated.GetX(poly, rotated.GetNumPoints(poly) - 1), y = (int)rotated.GetY(poly, rotated.GetNumPoints(poly) - 1);
+ else
+ x = (int)rotated.GetX(poly, 0), y = (int)rotated.GetY(poly, 0);
+
+ for(int i=0; i<rotated.GetNumPoints(poly); i++)
+ {
+ if (rotated.GetOnCurve(poly, i))
+ // LineTo(hdc, rotated.GetX(poly, i), rotated.GetY(poly, i));
+ {
+ p.drawLine(x, y, rotated.GetX(poly, i), rotated.GetY(poly, i));
+ x = (int)rotated.GetX(poly, i), y = (int)rotated.GetY(poly, i);
+ }
+ else
+ {
+ uint32 prev = rotated.GetPrev(poly, i), next = rotated.GetNext(poly, i);
+ float px = rotated.GetX(poly, prev), py = rotated.GetY(poly, prev),
+ nx = rotated.GetX(poly, next), ny = rotated.GetY(poly, next);
+
+ if (!rotated.GetOnCurve(poly, prev))
+ px = (px + rotated.GetX(poly, i)) / 2.0f,
+ py = (py + rotated.GetY(poly, i)) / 2.0f;
+
+ if (!rotated.GetOnCurve(poly, next))
+ nx = (nx + rotated.GetX(poly, i)) / 2.0f,
+ ny = (ny + rotated.GetY(poly, i)) / 2.0f;
+
+ Bezier(p, point(px, py), point(rotated.GetX(poly, i), rotated.GetY(poly, i)), point(nx, ny));
+ x = (int)nx, y = (int)ny;
+
+ if (rotated.GetOnCurve(poly, next))
+ i++; // Following point is on curve, so move past it
+ }
+ }
+ }
+ }
+#else
+ DrawGlyph(p, rotated);
+#endif
+ }
+}
+
+
+void EditWindow::DrawGlyph(QPainter & p, GlyphPoints & glyph)
+{
+ for(int poly=0; poly<glyph.GetNumPolys(); poly++)
+ {
+ if (glyph.GetNumPoints(poly) > 2)
+ {
+ // Initial move...
+ // If it's not on curve, then move to it, otherwise move to last point...
+
+ int x, y;
+
+ if (glyph.GetOnCurve(poly, glyph.GetNumPoints(poly) - 1))
+ x = (int)glyph.GetX(poly, glyph.GetNumPoints(poly) - 1), y = (int)glyph.GetY(poly, glyph.GetNumPoints(poly) - 1);
+ else
+ x = (int)glyph.GetX(poly, 0), y = (int)glyph.GetY(poly, 0);
+
+ for(int i=0; i<glyph.GetNumPoints(poly); i++)
+ {
+ if (glyph.GetOnCurve(poly, i))
+ {
+ p.drawLine(x, y, glyph.GetX(poly, i), glyph.GetY(poly, i));
+ x = (int)glyph.GetX(poly, i), y = (int)glyph.GetY(poly, i);
+ }
+ else
+ {
+ uint32 prev = glyph.GetPrev(poly, i), next = glyph.GetNext(poly, i);
+ float px = glyph.GetX(poly, prev), py = glyph.GetY(poly, prev),
+ nx = glyph.GetX(poly, next), ny = glyph.GetY(poly, next);
+
+ if (!glyph.GetOnCurve(poly, prev))
+ px = (px + glyph.GetX(poly, i)) / 2.0f,
+ py = (py + glyph.GetY(poly, i)) / 2.0f;
+
+ if (!glyph.GetOnCurve(poly, next))
+ nx = (nx + glyph.GetX(poly, i)) / 2.0f,
+ ny = (ny + glyph.GetY(poly, i)) / 2.0f;
+
+ Bezier(p, point(px, py), point(glyph.GetX(poly, i), glyph.GetY(poly, i)), point(nx, ny));
+ x = (int)nx, y = (int)ny;
+
+ if (glyph.GetOnCurve(poly, next))
+ i++; // Following point is on curve, so move past it
+ }
+ }
+ }
+ }
}
+
void EditWindow::mousePressEvent(QMouseEvent * event)
{
if (event->button() == Qt::RightButton)
update();
}
}
+ else if (tool == TOOLRotate)
+ {
+ // I think what's needed here is to keep the initial mouse click,
+ // paint the rotation center, then use the 1st mouse move event to establish
+ // the rotation "zero line", which becomes the line of reference to all
+ // subsequent mouse moves.
+ rotationCenter = GetAdjustedMousePosition(event);
+ showRotationCenter = true;
+ haveZeroPoint = false;
+ rotationAngle = 0;
+ update();
+ }
}
event->accept();
}
+
void EditWindow::mouseMoveEvent(QMouseEvent * event)
{
if (event->buttons() == Qt::RightButton)
}
else if (event->buttons() == Qt::LeftButton)
{
-#if 0
- if (tool == TOOLScroll)
- {
- // Extract current point from lParam/calc offset from previous point
-
- pt = e.GetPosition();
- ptOffset.x = pt.x - ptPrevious.x,
- ptOffset.y = pt.y - ptPrevious.y;
-
- // NOTE: OffsetViewportOrg operates in DEVICE UNITS...
-
-//Seems there's no equivalent for this in wxWidgets...!
-//!!! FIX !!!
-// hdc = GetDC(hWnd);
-// OffsetViewportOrgEx(hdc, ptOffset.x, ptOffset.y, NULL);
-// ReleaseDC(hWnd, hdc);
-
-// this shows that it works, so the logic above must be faulty...
-// And it is. It should convert the coords first, then do the subtraction to figure the offset...
-// Above: DONE
-// Then multiply it by the scaling factor. Whee!
- // This looks wacky because we're using screen coords for the offset...
- // Otherwise, we would subtract both offsets!
- offsetX -= ptOffset.x, offsetY += ptOffset.y;
- Refresh();
- }
- else
-#endif
- if (tool == TOOLAddPt || tool == TOOLAddPoly || tool == TOOLSelect)
+ if (tool == TOOLAddPt || tool == TOOLAddPoly || tool == TOOLSelect)
+ {
+ if (tool != TOOLAddPt || pts.GetNumPoints() > 0)//yecch.
{
- if (tool != TOOLAddPt || pts.GetNumPoints() > 0)//yecch.
- {
//temporary, for testing. BTW, Select drag bug is here...!
#if 1
- QPoint pt2 = GetAdjustedMousePosition(event);
- pts.SetXY(ptHighlight, pt2.x(), pt2.y());
- update();
+ QPoint pt2 = GetAdjustedMousePosition(event);
+ pts.SetXY(ptHighlight, pt2.x(), pt2.y());
+ update();
#endif
- }
}
- else if (tool == TOOLPolySelect)
+ }
+ else if (tool == TOOLPolySelect)
+ {
+ if (pts.GetNumPoints() > 0)
{
- if (pts.GetNumPoints() > 0)
- {
- QPoint pt2 = GetAdjustedMousePosition(event);
- // Should also set onCurve here as well, depending on keystate
+ QPoint pt2 = GetAdjustedMousePosition(event);
+ // Should also set onCurve here as well, depending on keystate
//Or should we?
- pts.OffsetPoly(pts.GetPoly(ptHighlight), pt2.x() - pts.GetX(ptHighlight), pt2.y() - pts.GetY(ptHighlight));
- update();
+ pts.OffsetPoly(pts.GetPoly(ptHighlight), pt2.x() - pts.GetX(ptHighlight), pt2.y() - pts.GetY(ptHighlight));
+ update();
+ }
+ }
+ else if (tool == TOOLRotate)
+ {
+ if (pts.GetNumPoints() > 0)
+ {
+ if (!haveZeroPoint)
+ {
+ rotationZeroPoint = GetAdjustedMousePosition(event);
+ haveZeroPoint = true;
+ }
+ else
+ {
+ // Figure out the angle between the "zero" vector and the current one,
+ // then rotate all points relative to the "zero" vector (done by paint())
+ QPoint currentPoint = GetAdjustedMousePosition(event);
+ Vector v1(rotationZeroPoint.x(), rotationZeroPoint.y(), 0,
+ rotationCenter.x(), rotationCenter.y(), 0);
+ Vector v2(currentPoint.x(), currentPoint.y(), 0,
+ rotationCenter.x(), rotationCenter.y(), 0);
+// rotationAngle = v1.Angle(v2);
+ rotationAngle = v2.Angle(v1);
+
+ QString s;
+ s.sprintf("%.3f degrees", rotationAngle * 180.0 / 3.14159265358979323);
+ ((TTEdit *)qApp)->mainWindow->statusBar()->showMessage(s);
}
+
+ update();
}
+ }
}
else if (event->buttons() == Qt::NoButton)
{
int32 p1x = pts.GetX(i), p1y = pts.GetY(i),
p2x = pts.GetX(pts.GetNext(i)), p2y = pts.GetY(pts.GetNext(i));
- vector ls(p2x, p2y, 0, p1x, p1y, 0), v1(pt2.x(), pt2.y(), 0, p1x, p1y, 0),
+ Vector ls(p2x, p2y, 0, p1x, p1y, 0), v1(pt2.x(), pt2.y(), 0, p1x, p1y, 0),
v2(pt2.x(), pt2.y(), 0, p2x, p2y, 0);
- double pp = ls.dot(v1) / ls.length(), dist;
+ double pp = ls.Dot(v1) / ls.Magnitude(), dist;
// Geometric interpretation:
// pp is the paremeterized point on the vector ls where the perpendicular intersects ls.
// If pp < 0, then the perpendicular lies beyond the 1st endpoint. If pp > length of ls,
// then the perpendicular lies beyond the 2nd endpoint.
if (pp < 0.0)
- dist = v1.length();
- else if (pp > ls.length())
- dist = v2.length();
+ dist = v1.Magnitude();
+ else if (pp > ls.Magnitude())
+ dist = v2.Magnitude();
else // distance = ?Det?(ls, v1) / |ls|
- dist = fabs((ls.x * v1.y - v1.x * ls.y) / ls.length());
+ dist = fabs((ls.x * v1.y - v1.x * ls.y) / ls.Magnitude());
//The answer to the above looks like it might be found here:
//
event->accept();
}
+
void EditWindow::mouseReleaseEvent(QMouseEvent * event)
{
if (event->button() == Qt::RightButton)
}
else if (event->button() == Qt::LeftButton)
{
+ if (showRotationCenter)
+ {
+ showRotationCenter = false;
+ haveZeroPoint = false;
+ pts.RotatePoints(rotationAngle, IPoint(rotationCenter.x(), rotationCenter.y()));
+ update();
+ ((TTEdit *)qApp)->mainWindow->statusBar()->showMessage("");
+ }
+
// if (tool == TOOLScroll || tool == TOOLZoom)
// ReleaseMouse();
//this is prolly too much
((TTEdit *)qApp)->charWnd->MakePathFromPoints(&pts);
((TTEdit *)qApp)->charWnd->update();
+
}
event->accept();
void CreateCursors(void);
QPoint GetAdjustedMousePosition(QMouseEvent * event);
QPoint GetAdjustedClientPosition(int x, int y);
+ void DrawGlyph(QPainter & p, GlyphPoints & glyph);
+ public:
QImage image;
QPoint pt, ptOffset, ptPrevious;
double scale; // Window scaling factor
GlyphPoints pts; // Glyph point structure
int32 ptHighlight, oldPtHighlight, ptNextHighlight, oldPtNextHighlight;
bool polyFirstPoint;
+ bool showRotationCenter, haveZeroPoint;
+ QPoint rotationCenter, rotationZeroPoint, rotationCurrentPoint;
+ double rotationAngle;
ToolWindow * toolPalette;
- QCursor cur[8];
+ QCursor cur[9];
};
#endif // __EDITWINDOW_H__
#ifdef DEBUG
#include "debug.h"
#endif
+#include <math.h>
+
/*GlyphPoints::GlyphPoints(void)
{
#endif
}
+
GlyphPoints::GlyphPoints(int xx, int yy, bool oc)
{
//Hmm. What to do with this...?
#endif
}
+
// Copy constructor (needed for deep copying)
//GlyphPoints::GlyphPoints(GlyphPoints &c): x(NULL), y(NULL), onCurve(NULL), polyEnd(NULL)
#endif
}
+
GlyphPoints::~GlyphPoints()
{
+ FreeAllocatedMemory();
+#if 0
if (x)
delete[] x;
if (polyEnd)
delete[] polyEnd;
+#endif
}
+
void GlyphPoints::AllocateAndCopy(int nPts, int nPlys, int * xa, int * ya, bool * oca, uint16 * pa)
{
numPoints = nPts, numPolys = nPlys;
}
}
+
+void GlyphPoints::FreeAllocatedMemory(void)
+{
+ if (x)
+ delete[] x;
+
+ if (y)
+ delete[] y;
+
+ if (onCurve)
+ delete[] onCurve;
+
+ if (polyEnd)
+ delete[] polyEnd;
+}
+
+
GlyphPoints& GlyphPoints::operator=(const GlyphPoints &c)
{
if (this == &c)
return *this; // Take care of self-assignment
+#if 0
if (x)
delete[] x;
if (polyEnd)
delete[] polyEnd;
-
+#endif
+ FreeAllocatedMemory();
AllocateAndCopy(c.numPoints, c.numPolys, c.x, c.y, c.onCurve, c.polyEnd);
return *this;
}
+
// Add another GlyphPoints' points to this one...
GlyphPoints GlyphPoints::operator+(const GlyphPoints &c)
return retVal;
}
+
// Add a point to this GlyphPoints...
GlyphPoints GlyphPoints::operator+(const IPoint &c)
return retVal;
}
+
GlyphPoints& GlyphPoints::operator+=(const IPoint &p)
{
InsertPoint(numPoints, p.x, p.y, p.onCurve);
return *this;
}
+
+void GlyphPoints::Clear(void)
+{
+ FreeAllocatedMemory();
+ x = y = NULL;
+ onCurve = NULL;
+ polyEnd = NULL;
+ numPoints = numPolys = pointsAllocated = polysAllocated = 0;
+}
+
+
void GlyphPoints::InsertPoint(uint16 pt, int xx, int yy, bool oc)
{
if (pt > numPoints) // > because we can insert at end...!
x = totX, y = totY, onCurve = totOnCurve;
}
+
void GlyphPoints::InsertPoint(uint16 pt, const IPoint &p)
{
InsertPoint(pt, p.x, p.y, p.onCurve);
}
+
//
// Delete a point from the glyph
// Note that we don't bother to reallocate anything here, just bump the
x[i] = x[i + 1], y[i] = y[i + 1], onCurve[i] = onCurve[i + 1];
}
+
uint16 GlyphPoints::GetNumPoints(void)
{
return numPoints;
}
+
uint16 GlyphPoints::GetNumPoints(uint16 poly)
{
if (poly >= numPolys)
return polyEnd[poly] - (poly == 0 ? -1 : polyEnd[poly - 1]);
}
+
uint16 GlyphPoints::GetNumPolys(void)
{
return numPolys;
}
+
int GlyphPoints::GetX(uint16 pt)
{
if (pt >= numPoints)
return x[pt];
}
+
int GlyphPoints::GetY(uint16 pt)
{
if (pt >= numPoints)
return y[pt];
}
+
bool GlyphPoints::GetOnCurve(uint16 pt)
{
if (pt >= numPoints)
return onCurve[pt];
}
+
int GlyphPoints::GetX(uint16 poly, uint16 pt)
{
if (pt >= GetNumPoints(poly))
return x[pt + (poly == 0 ? 0 : polyEnd[poly - 1] + 1)];
}
+
int GlyphPoints::GetNextX(uint16 poly, uint16 pt)
{
return GetX(poly, GetNext(poly, pt));
}
+
int GlyphPoints::GetY(uint16 poly, uint16 pt)
{
if (pt >= GetNumPoints(poly))
return y[pt + (poly == 0 ? 0 : polyEnd[poly - 1] + 1)];
}
+
int GlyphPoints::GetNextY(uint16 poly, uint16 pt)
{
return GetY(poly, GetNext(poly, pt));
}
+
IPoint GlyphPoints::GetPoint(uint16 poly, uint16 pt)
{
return IPoint(GetX(poly, pt), GetY(poly, pt));
}
+
bool GlyphPoints::GetOnCurve(uint16 poly, uint16 pt)
{
if (pt >= GetNumPoints(poly))
return onCurve[pt + (poly == 0 ? 0 : polyEnd[poly - 1] + 1)];
}
+
bool GlyphPoints::GetPrevOnCurve(uint16 poly, uint16 pt)
{
return GetOnCurve(poly, GetPrev(poly, pt));
}
+
bool GlyphPoints::GetNextOnCurve(uint16 poly, uint16 pt)
{
return GetOnCurve(poly, GetNext(poly, pt));
}
+
+uint16 GlyphPoints::GetPolyStart(uint16 poly)
+{
+ if (poly >= numPolys)
+#ifdef DEBUG
+{
+WriteLogMsg("Exception: GetPolyEnd(uint16). poly=%u, numPolys=%u\xD\xA", poly, numPolys);
+#endif
+ throw GP_OUT_OF_RANGE;
+#ifdef DEBUG
+}
+#endif
+
+ // If it's poly 0, return 0. Otherwise, get the previous poly's end & add one to it
+ return (poly == 0 ? 0 : polyEnd[poly - 1] + 1);
+}
+
+
uint16 GlyphPoints::GetPolyEnd(uint16 poly)
{
if (poly >= numPolys)
return polyEnd[poly];
}
+
void GlyphPoints::OffsetPoints(int xOff, int yOff)
{
for(int i=0; i<numPoints; i++)
x[i] += xOff, y[i] += yOff;
}
+
//
// Offset only a specific polygon in the glyph
//
x[polyStart + i] += xOff, y[polyStart + i] += yOff;
}
+
void GlyphPoints::ScalePoints(float sc)
{
for(int i=0; i<numPoints; i++)
y[i] = (int)(((float)y[i] * sc) + 0.5f);
}
+
void GlyphPoints::SetXY(uint16 pt, int xx, int yy)
{
if (pt >= numPoints)
x[pt] = xx, y[pt] = yy;
}
+
void GlyphPoints::SetOnCurve(uint16 pt, bool oc)
{
if (pt >= numPoints)
onCurve[pt] = oc;
}
+
uint16 GlyphPoints::GetPrev(uint16 pt)
{
// pt = 7, polyEnd = 4, 9, 15
return retVal;
}
+
uint16 GlyphPoints::GetNext(uint16 pt)
{
uint16 min = 0, max = numPoints - 1;
return retVal;
}
+
//
// Get previous point for this polygon using wraparound.
// Note that pt is a zero-based index!
return (pt == 0 ? GetNumPoints(poly) - 1 : pt - 1);
}
+
//
// Get next point for this polygon using wraparound.
// Note that pt is a zero-based index!
return (pt == GetNumPoints(poly) - 1 ? 0 : pt + 1);
}
+
uint16 GlyphPoints::GetPoly(uint16 pt)
{
if (pt >= numPoints)
return (uint16)-1;
}
+
void GlyphPoints::AddNewPolyAtEnd(void)
{
if (numPoints == 0) // By default, we already *have* a poly
polyEnd = newPolyEnd;
}
+
IPoint GlyphPoints::GetMidpointToPrev(uint16 poly, uint16 pt)
{
uint16 prev = GetPrev(poly, pt);
return IPoint((x1 + x2) / 2.0f, (y1 + y2) / 2.0f);
}
+
IPoint GlyphPoints::GetMidpointToNext(uint16 poly, uint16 pt)
{
uint16 next = GetNext(poly, pt);
return IPoint((x1 + x2) / 2.0f, (y1 + y2) / 2.0f);
}
+
IPoint GlyphPoints::GetPrevPoint(uint16 poly, uint16 pt)
{
uint16 prevPt = GetPrev(poly, pt);
return IPoint(GetX(poly, prevPt), GetY(poly, prevPt));
}
+
IPoint GlyphPoints::GetNextPoint(uint16 poly, uint16 pt)
{
uint16 nextPt = GetNext(poly, pt);
return IPoint(GetX(poly, nextPt), GetY(poly, nextPt));
}
+
+
+//
+// Rotate a point by "angle" around point "center"
+//
+IPoint GlyphPoints::RotatePoint(const double angle, const IPoint point, const IPoint center)
+{
+ // Translate the point to the origin
+ double xt = (double)(point.x - center.x);
+ double yt = (double)(point.y - center.y);
+
+ // Rotate the point by angle
+ double xr = (xt * cos(angle)) - (yt * sin(angle));
+ double yr = (xt * sin(angle)) + (yt * cos(angle));
+
+ // Translate it back...
+ IPoint rotated;
+ rotated.x = (int)(xr + 0.5) + center.x;
+ rotated.y = (int)(yr + 0.5) + center.y;
+ return rotated;
+}
+
+
+//
+// Rotate all points in the glyph by "angle" around point "pt"
+//
+void GlyphPoints::RotatePoints(const double angle, const IPoint pt)
+{
+ for(int i=0; i<numPoints; i++)
+ {
+ // Translate the point to the origin
+ double xt = (double)(x[i] - pt.x);
+ double yt = (double)(y[i] - pt.y);
+
+ // Rotate the point by angle
+ double xr = (xt * cos(angle)) - (yt * sin(angle));
+ double yr = (xt * sin(angle)) + (yt * cos(angle));
+
+ // Put it back...
+ x[i] = (int)(xr + 0.5) + pt.x;
+ y[i] = (int)(yr + 0.5) + pt.y;
+ }
+}
+
+
+IPoint GlyphPoints::GetPolyCentroid(const int16 poly)
+{
+ // We should throw an exception here, but meh
+ // (this actually short circuits the exception handling in all the GetPolyXXX() functions)
+ if (poly >= numPolys)
+ return IPoint(0, 0);
+
+// if (poly >= numPolys)
+//#ifdef DEBUG
+//{
+//WriteLogMsg("Exception: GetPolyEnd(uint16). poly=%u, numPolys=%u\xD\xA", poly, numPolys);
+//#endif
+// throw GP_OUT_OF_RANGE;
+//#ifdef DEBUG
+//}
+//#endif
+
+ IPoint centroid; // Initializes to (0, 0)
+ uint16 numPointsInPoly = GetNumPoints(poly);
+
+ for(uint16 i=GetPolyStart(poly); i<=GetPolyEnd(poly); i++)
+ {
+ centroid.x += x[i];
+ centroid.y += y[i];
+ }
+
+ centroid.x /= numPointsInPoly;
+ centroid.y /= numPointsInPoly;
+
+ return centroid;
+}
+
+
+void GlyphPoints::RotatePolyAroundCentroid(const int16 poly, const double angle)
+{
+ if (poly >= numPolys)
+ return;
+
+ IPoint centroid = GetPolyCentroid(poly);
+
+ for(uint16 i=GetPolyStart(poly); i<=GetPolyEnd(poly); i++)
+ {
+ IPoint rotated = RotatePoint(angle, IPoint(x[i], y[i]), centroid);
+ x[i] = rotated.x;
+ y[i] = rotated.y;
+ }
+}
+
+
+// really need to do checking on the results from fscanf...
+bool GlyphPoints::LoadGlyphFromFile(FILE * file)
+{
+ char line[512];
+ float version;
+
+ FreeAllocatedMemory();
+
+ fscanf(file, "%s V%f", line, &version);
+ fscanf(file, "%s %u", line, &numPoints);
+ x = new int[numPoints];
+ y = new int[numPoints];
+ onCurve = new bool[numPoints];
+
+ for(int i=0; i<numPoints; i++)
+ {
+ fscanf(file, "%d %d %s", &x[i], &y[i], &line);
+ onCurve[i] = (line[0] == 'T' ? true : false);
+ }
+
+ fscanf(file, "%s %u", line, &numPolys);
+ polyEnd = new uint16[numPolys];
+
+ for(int i=0; i<numPolys; i++)
+ {
+ fscanf(file, "%u", &polyEnd[i]);
+ }
+
+ return true;
+}
+
+
+bool GlyphPoints::SaveGlyphToFile(FILE * file)
+{
+// GlyphPoints glyph = editWnd->pts;
+ fprintf(file, "TTEGLYPH V1.0\n");
+ fprintf(file, "POINTS %u\n", numPoints);
+
+ for(int i=0; i<numPoints; i++)
+ {
+ fprintf(file, "%d %d %s\n", x[i], y[i], (onCurve[i] ? "T" : "F"));
+ }
+
+ fprintf(file, "POLYS %u\n", numPolys);
+
+ for(int i=0; i<numPolys; i++)
+ {
+ fprintf(file, "%u\n", polyEnd[i]);
+ }
+
+ return true;
+}
+
#define __GLYPHPOINTS_H__
#include "types.h"
+#include <stdio.h>
+// "IPoint" is an Integer based Point
struct IPoint
{
int32 x, y;
GlyphPoints operator+(const GlyphPoints &);
GlyphPoints operator+(const IPoint &);
GlyphPoints& operator+=(const IPoint &);
+ void Clear(void);
void InsertPoint(uint16, int, int, bool);
void InsertPoint(uint16, const IPoint &);
void DeletePoint(uint16);
uint16 GetNumPoints(void);
- uint16 GetNumPoints(uint16);
+ uint16 GetNumPoints(uint16 poly);
uint16 GetNumPolys(void);
int GetX(uint16);
int GetY(uint16);
bool GetOnCurve(uint16, uint16);
bool GetPrevOnCurve(uint16, uint16);
bool GetNextOnCurve(uint16, uint16);
+ uint16 GetPolyStart(uint16);
uint16 GetPolyEnd(uint16);
void OffsetPoints(int, int);
void OffsetPoly(uint16, int32, int32);
IPoint GetPrevPoint(uint16, uint16);
IPoint GetNextPoint(uint16, uint16);
+ IPoint RotatePoint(const double angle, const IPoint point, const IPoint center);
+ void RotatePoints(const double angle, const IPoint point);
+ IPoint GetPolyCentroid(const int16 poly);
+ void RotatePolyAroundCentroid(const int16 poly, const double angle);
+
+ bool LoadGlyphFromFile(FILE *);
+ bool SaveGlyphToFile(FILE *);
+
private:
void AllocateAndCopy(int, int, int *, int *, bool *, uint16 *);
+ void FreeAllocatedMemory(void);
private:
int numPoints, numPolys;
//
-// TTEMAINWINDOW.CPP - The TrueType Editor
+// MAINWINDOW.CPP - The TrueType Editor
// by James L. Hammons
// (C) 2004 Underground Software
//
#define DEBUGFOO // Various tool debugging...
//#define DEBUGTP // Toolpalette debugging...
-//#include <QtGui>
-#include "ttemainwindow.h"
-#include "editwindow.h"
+#include "mainwindow.h"
#include "charwindow.h"
+#include "editwindow.h"
#include "ttedit.h"
-TTEMainWindow::TTEMainWindow()
+
+MainWindow::MainWindow()
{
((TTEdit *)qApp)->charWnd = new CharWindow(this);
editWnd = new EditWindow(this);
editToolBar->addAction(cutAct);
editToolBar->addAction(copyAct);
editToolBar->addAction(pasteAct);
+#else
+ CreateActions();
+ CreateMenus();
+ CreateToolbars();
#endif
// Create status bar
((TTEdit *)qApp)->charWnd->show();//eh?
}
-void TTEMainWindow::closeEvent(QCloseEvent * event)
+
+//
+// Consolidates action creation from a multi-step process to a single-step one.
+//
+QAction * MainWindow::CreateAction(QString name, QString tooltip, QString statustip,
+ QIcon icon, QKeySequence key, bool checkable/*= false*/)
+{
+ QAction * action = new QAction(icon, name, this);
+ action->setToolTip(tooltip);
+ action->setStatusTip(statustip);
+ action->setShortcut(key);
+ action->setCheckable(checkable);
+
+ return action;
+}
+
+
+//
+// This is essentially the same as the previous function, but this allows more
+// than one key sequence to be added as key shortcuts.
+//
+QAction * MainWindow::CreateAction(QString name, QString tooltip, QString statustip,
+ QIcon icon, QKeySequence key1, QKeySequence key2, bool checkable/*= false*/)
+{
+ QAction * action = new QAction(icon, name, this);
+ action->setToolTip(tooltip);
+ action->setStatusTip(statustip);
+ QList<QKeySequence> keyList;
+ keyList.append(key1);
+ keyList.append(key2);
+ action->setShortcuts(keyList);
+ action->setCheckable(checkable);
+
+ return action;
+}
+
+
+void MainWindow::CreateActions(void)
+{
+ newGlyphAct = CreateAction("&New Glyph", "New Glyph", "Create a new glyph", QIcon(), QKeySequence());
+ openFileAct = CreateAction("&Open File", "Open File", "Open a glyph file", QIcon(), QKeySequence());
+ saveFileAct = CreateAction("&Save File", "Save File", "Save a glyph file", QIcon(), QKeySequence());
+
+ connect(newGlyphAct, SIGNAL(triggered()), this, SLOT(NewGlyph()));
+ connect(openFileAct, SIGNAL(triggered()), this, SLOT(OpenFile()));
+ connect(saveFileAct, SIGNAL(triggered()), this, SLOT(SaveFile()));
+}
+
+
+void MainWindow::CreateMenus(void)
+{
+ QMenu * menu = menuBar()->addMenu(tr("&File"));
+ menu->addAction(newGlyphAct);
+ menu->addAction(openFileAct);
+ menu->addAction(saveFileAct);
+// menu->addAction(fileSaveAsAct);
+// menu->addAction(fileCloseAct);
+}
+
+
+void MainWindow::CreateToolbars(void)
+{
+}
+
+
+void MainWindow::closeEvent(QCloseEvent * event)
{
WriteSettings();
event->accept(); // ignore() if can't close for some reason
}
-void TTEMainWindow::Open(void)
+
+void MainWindow::NewGlyph(void)
{
+ editWnd->pts.Clear();
+ ((TTEdit *)qApp)->charWnd->MakePathFromPoints(&(editWnd->pts));
+ ((TTEdit *)qApp)->charWnd->update();
+ editWnd->update();
}
-void TTEMainWindow::ReadSettings(void)
+
+void MainWindow::OpenFile(void)
+{
+ QString filename = QFileDialog::getOpenFileName(this, tr("Open Glyph File"),
+ "./", tr("Glyph files (*.glyph)"));
+ FILE * file = fopen(filename.toAscii().data(), "r");
+
+ //need to pop an error box here...
+ if (file == 0)
+ return;
+
+ editWnd->pts.LoadGlyphFromFile(file);
+ fclose(file);
+
+ ((TTEdit *)qApp)->charWnd->MakePathFromPoints(&(editWnd->pts));
+ ((TTEdit *)qApp)->charWnd->update();
+ editWnd->update();
+}
+
+
+void MainWindow::SaveFile(void)
+{
+ QString filename = QFileDialog::getSaveFileName(this, tr("Save Glyph File"),
+ "./", tr("Glyph files (*.glyph)"));
+ FILE * file = fopen(filename.toAscii().data(), "w");
+
+ //need to pop an error box here...
+ if (file == 0)
+ return;
+
+ editWnd->pts.SaveGlyphToFile(file);
+ fclose(file);
+}
+
+
+void MainWindow::ReadSettings(void)
{
QSettings settings("Underground Software", "TTEdit");
QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
((TTEdit *)qApp)->charWnd->move(pos);
}
-void TTEMainWindow::WriteSettings(void)
+
+void MainWindow::WriteSettings(void)
{
QSettings settings("Underground Software", "TTEdit");
settings.setValue("pos", pos());
//
-// TTEMAINWINDOW.H: Header file
+// MAINWINDOW.H: Header file
//
// by James L. Hammons
// (C) 2009 Underground Software
//
-#ifndef __TTEMAINWINDOW_H__
-#define __TTEMAINWINDOW_H__
+#ifndef __MAINWINDOW_H__
+#define __MAINWINDOW_H__
-//Hrm. uh??? I thought this wasn't the way to do this stuff...???
#include <QtGui>
-#if 0
-//#include <wx/wx.h> // So that whoever uses this can without having
- // to pull in a bunch of references manually
-//#include "ttf.h"
// Forward declarations
-//class TTEditWin;
-//class TTEditWindow;
-//class CharWindow;
-//class ToolWindow;
-
-//
-// Class representing the entire Application
-//
-class TTEditApp: public QMainWindow
-{
- public:
- TTEditFrame * mainFrame;
- CharWindow * charWin;
- ToolWindow * toolPalette;
- TTF font;
- wxCursor * cur[8];
-
- bool OnInit();
- int OnExit();
- void CreateResources(void);
-};
-
-DECLARE_APP(TTEditApp)
-#endif
-// Forward declarations
-
class EditWindow;
//class CharWindow;
-class TTEMainWindow: public QMainWindow
+
+class MainWindow: public QMainWindow
{
// All Qt apps require this macro
Q_OBJECT
public:
- TTEMainWindow();
+ MainWindow();
protected:
void closeEvent(QCloseEvent * event);
private slots:
- void Open();
+ void NewGlyph(void);
+ void OpenFile(void);
+ void SaveFile(void);
private:
+ QAction * CreateAction(QString name, QString tooltip, QString statustip,
+ QIcon icon, QKeySequence key, bool checkable = false);
+ QAction * CreateAction(QString name, QString tooltip, QString statustip,
+ QIcon icon, QKeySequence key1, QKeySequence key2, bool checkable = false);
+ void CreateActions(void);
+ void CreateMenus(void);
+ void CreateToolbars(void);
void ReadSettings(void);
void WriteSettings(void);
DECLARE_EVENT_TABLE()
#endif
+ QAction * newGlyphAct;
+ QAction * openFileAct;
+ QAction * saveFileAct;
};
-#endif // __TTEMAINWINDOW_H__
+#endif // __MAINWINDOW_H__
// Set up sizes
sizeTPBM.rx() = img.width(), sizeTPBM.ry() = img.height();
- sizeStamp.rx() = sizeTPBM.x() / 4, sizeStamp.ry() = sizeTPBM.y() / 2;
+ sizeStamp.rx() = sizeTPBM.x() / 5, sizeStamp.ry() = sizeTPBM.y() / 2;
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
setVisible(false);
{
//need ul corner of bitmap, ul corner of dest, width/height
p.setCompositionMode(QPainter::RasterOp_NotSource);
- QPoint pt(sizeStamp.x() * (prevTool & 0x03), sizeStamp.y() * (prevTool >> 2));
+// QPoint pt(sizeStamp.x() * (prevTool & 0x03), sizeStamp.y() * (prevTool >> 2));
+ QPoint pt(sizeStamp.x() * (prevTool % 5), sizeStamp.y() * (prevTool / 5));
p.drawImage(pt.x(), pt.y(), img, pt.x(), pt.y(), sizeStamp.x(), sizeStamp.y());
}
}
ToolType newTool = TOOLNone;
// NOTE: This works because x and y are UNSIGNED
- if (x < 4 && y < 2)
- newTool = (ToolType)((y * 4) + x);
+ if (x < 5 && y < 2)
+ newTool = (ToolType)((y * 5) + x);
+
+ // We don't have 10 yet, so fix this if the user selected the blank space
+ if (newTool == 9)
+ newTool = TOOLNone;
return newTool;
}
TOOLPolySelect, // Polygon selection tool
TOOLScroll, // Scroll window tool
TOOLZoom, // Zoom window tool
+ TOOLRotate, // Rotate tool
TOOLAddPt, // Add point tool
TOOLAddPoly, // Polygon creation tool
TOOLDelPt, // Delete point tool
#include "ttedit.h"
#include <QApplication>
-#include "ttemainwindow.h"
+#include "mainwindow.h"
// Main app constructor--we stick globally accessible stuff here...
TTEdit::TTEdit(int & argc, char * argv[]): QApplication(argc, argv), charWnd(NULL)
{
- mainWindow = new TTEMainWindow;
+ mainWindow = new MainWindow;
//printf("mainWindow.show();\n");
mainWindow->show();
}
#ifndef __TTEDIT_H__
#define __TTEDIT_H__
-//Hrm. uh??? I thought this wasn't the way to do this stuff...???
#include <QtGui>
// Forward declarations
class CharWindow;
-class TTEMainWindow;
+class MainWindow;
class TTEdit: public QApplication
{
public:
CharWindow * charWnd;
- TTEMainWindow * mainWindow;
+ MainWindow * mainWindow;
};
#endif // __TTEDIT_H__
+#if 0
+
//
// VECTOR.H - vector class definition
//
// JLH 05/15/2004 Added operator+ function
//
-#include <math.h>
#include "vector.h"
+#include <math.h>
vector::vector(double a1/*= 0.0*/, double b1/*= 0.0*/, double c1/*= 0.0*/,
double a2/*= 0.0*/, double b2/*= 0.0*/, double c2/*= 0.0*/):
if (fabs(z) < epsilon)
z = 0.0;
}
+
+#else
+
+//
+// vector.cpp: Various structures used for 3 dimensional imaging
+//
+// by James Hammons
+// (C) 2006 Underground Software
+//
+// JLH = James L. Hammons <jlhamm@acm.org>
+//
+// WHO WHEN WHAT
+// --- ---------- ------------------------------------------------------------
+// JLH 09/19/2006 Created this file
+// JLH 03/22/2011 Moved implementation of constructor from header to here
+// JLH 04/02/2011 Fixed divide-by-zero bug in Unit(), added Angle() function
+//
+
+#include "vector.h"
+
+#include <math.h> // For sqrt()
+//#include "mathconstants.h"
+
+#define PI 3.14159265358979323846264338327
+#define RADIANS_TO_DEGREES (180.0 / PI)
+#define DEGREES_TO_RADIANS (PI / 180.0)
+
+
+// Vector implementation
+
+Vector::Vector(double x1/*= 0*/, double y1/*= 0*/, double z1/*= 0*/,
+ double x2/*= 0*/, double y2/*= 0*/, double z2/*= 0*/):
+ x(x1 - x2), y(y1 - y2), z(z1 - z2)
+{
+}
+
+
+Vector::Vector(Vector head, Vector tail): x(head.x - tail.x), y(head.y - tail.y), z(head.z - tail.z)
+{
+}
+
+
+Vector Vector::operator=(Vector const v)
+{
+ x = v.x, y = v.y, z = v.z;
+
+ return *this;
+}
+
+
+Vector Vector::operator+(Vector const v)
+{
+ return Vector(x + v.x, y + v.y, z + v.z);
+}
+
+
+Vector Vector::operator-(Vector const v)
+{
+ return Vector(x - v.x, y - v.y, z - v.z);
+}
+
+
+// Unary negation
+
+Vector Vector::operator-(void)
+{
+ return Vector(-x, -y, -z);
+}
+
+
+// Vector x constant
+
+Vector Vector::operator*(double const v)
+{
+ return Vector(x * v, y * v, z * v);
+}
+
+
+// Vector x constant
+
+Vector Vector::operator*(float const v)
+{
+ return Vector(x * v, y * v, z * v);
+}
+
+
+// Vector / constant
+
+Vector Vector::operator/(double const v)
+{
+ return Vector(x / v, y / v, z / v);
+}
+
+
+// Vector / constant
+
+Vector Vector::operator/(float const v)
+{
+ return Vector(x / v, y / v, z / v);
+}
+
+
+// Vector (cross) product
+
+Vector Vector::operator*(Vector const v)
+{
+ // a x b = [a2b3 - a3b2, a3b1 - a1b3, a1b2 - a2b1]
+ return Vector((y * v.z) - (z * v.y), (z * v.x) - (x * v.z), (x * v.y) - (y * v.x));
+}
+
+
+// Dot product
+
+double Vector::Dot(Vector const v)
+{
+ return (x * v.x) + (y * v.y) + (z * v.z);
+}
+
+
+// Vector x constant, self assigned
+
+Vector& Vector::operator*=(double const v)
+{
+ x *= v, y *= v, z *= v;
+
+ return *this;
+}
+
+
+// Vector / constant, self assigned
+
+Vector& Vector::operator/=(double const v)
+{
+ x /= v, y /= v, z /= v;
+
+ return *this;
+}
+
+
+// Vector + vector, self assigned
+
+Vector& Vector::operator+=(Vector const v)
+{
+ x += v.x, y += v.y, z += v.z;
+
+ return *this;
+}
+
+
+// Vector + constant, self assigned
+
+Vector& Vector::operator+=(double const v)
+{
+ x += v, y += v, z += v;
+
+ return *this;
+}
+
+
+// Vector - vector, self assigned
+
+Vector& Vector::operator-=(Vector const v)
+{
+ x -= v.x, y -= v.y, z -= v.z;
+
+ return *this;
+}
+
+
+// Vector - constant, self assigned
+
+Vector& Vector::operator-=(double const v)
+{
+ x -= v, y -= v, z -= v;
+
+ return *this;
+}
+
+
+// Check for equality
+bool Vector::operator==(Vector const v)
+{
+ return (x == v.x && y == v.y && z == v.z ? true : false);
+}
+
+
+// Check for inequality
+bool Vector::operator!=(Vector const v)
+{
+ return (x != v.x || y != v.y || z != v.z ? true : false);
+}
+
+
+Vector Vector::Unit(void)
+{
+ double mag = Magnitude();
+
+ // If the magnitude of the vector is zero, then the Unit vector is undefined...
+ if (mag == 0)
+ return Vector(0, 0, 0);
+
+ return Vector(x / mag, y / mag, z / mag);
+}
+
+
+double Vector::Magnitude(void)
+{
+ return sqrt(x * x + y * y + z * z);
+}
+
+
+double Vector::Angle(void)
+{
+ // acos returns a value between zero and PI, which means we don't know which
+ // quadrant the angle is in... Though, if the y-coordinate of the vector is
+ // negative, that means that the angle is in quadrants III - IV.
+ double rawAngle = acos(Unit().x);
+ double correctedAngle = (y < 0 ? (2.0 * PI) - rawAngle : rawAngle);
+
+ return correctedAngle;
+}
+
+
+//
+// Angle between these two vectors
+//
+double Vector::Angle(Vector v)
+{
+ return Angle() - v.Angle();
+}
+
+
+bool Vector::isZero(double epsilon/*= 1e-6*/)
+{
+ return (fabs(x) < epsilon && fabs(y) < epsilon && fabs(z) < epsilon ? true : false);
+}
+
+
+// Class methods
+
+double Vector::Dot(Vector v1, Vector v2)
+{
+ return (v1.x * v2.x) + (v1.y * v2.y) + (v1.z * v2.z);
+}
+
+
+double Vector::Magnitude(Vector v1, Vector v2)
+{
+ double xx = v1.x - v2.x;
+ double yy = v1.y - v2.y;
+ double zz = v1.z - v2.z;
+ return sqrt(xx * xx + yy * yy + zz * zz);
+}
+
+#endif
+#if 0
+
//
// VECTOR.H - vector class definition
//
};
#endif // __VECTOR_H__
+
+#else
+
+//
+// vector.h (Last modified: 6/28/2001)
+//
+// Various structures used for 3 dimensional imaging
+//
+// by James L. Hammons
+// (C) 2001 Underground Software
+//
+
+#ifndef __VECTOR_H__
+#define __VECTOR_H__
+
+// What we'll do here is create the vector type and use typedef to alias Point to it. Yeah, that's it.
+
+class Vector
+{
+ public:
+// Vector(double xx = 0, double yy = 0, double zz = 0);
+ Vector(double x1 = 0, double y1 = 0, double z1 = 0, double x2 = 0, double y2 = 0, double z2 = 0);
+ Vector(Vector head, Vector tail); // Create vector from two points
+ Vector operator=(Vector const v);
+ Vector operator+(Vector const v);
+ Vector operator-(Vector const v);
+ Vector operator-(void); // Unary negation
+ Vector operator*(double const v); // Vector times constant (double)
+ Vector operator*(float const v); // Vector times constant (float)
+ Vector operator/(double const v); // Vector divided by constant (double)
+ Vector operator/(float const v); // Vector divided by constant (float)
+ Vector operator*(Vector const v); // Vector product
+ double Dot(Vector const v); // Dot product
+
+ Vector& operator*=(double const v); // Vector times constant self-assignment
+ Vector& operator/=(double const v); // Vector divided by constant self-assignment
+ Vector& operator+=(Vector const v); // Vector plus Vector self-assignment
+ Vector& operator+=(double const v); // Vector plus constant self-assignment
+ Vector& operator-=(Vector const v); // Vector minus Vector self-assignment
+ Vector& operator-=(double const v); // Vector minus constant self-assignment
+
+ bool operator==(Vector const v); // Check for equality
+ bool operator!=(Vector const v); // Check for inequality
+
+ Vector Unit(void);
+ double Magnitude(void);
+ double Angle(void); // Angle of this vector WRT positive X-axis
+ double Angle(Vector v); // Angle between these two vectors
+ bool isZero(double epsilon = 1e-6);
+
+ // Class methods
+
+ static double Dot(Vector v1, Vector v2);
+ static double Magnitude(Vector v1, Vector v2);
+
+ public:
+ double x, y, z;
+};
+
+typedef Vector Point;
+
+#endif // __VECTOR_H__
+
+#endif
\ No newline at end of file
#CONFIG += qt debug
HEADERS += src/ttedit.h
-HEADERS += src/ttemainwindow.h
+HEADERS += src/mainwindow.h
HEADERS += src/editwindow.h
HEADERS += src/glyphpoints.h
HEADERS += src/types.h
HEADERS += src/list.h
SOURCES += src/ttedit.cpp
-SOURCES += src/ttemainwindow.cpp
+SOURCES += src/mainwindow.cpp
SOURCES += src/editwindow.cpp
SOURCES += src/glyphpoints.cpp
SOURCES += src/debug.cpp
<file>res/cursor6.png</file>
<file>res/cursor7.png</file>
<file>res/cursor8.png</file>
+ <file>res/cursor9.png</file>
<file>res/act-back.png</file>
<file>res/act-forward.png</file>
<file>res/act-charwin.png</file>