]> Shamusworld >> Repos - ttedit/commitdiff
Added rotation tool, save/load capability.
authorShamus Hammons <jlhamm@acm.org>
Sun, 18 Nov 2012 04:22:58 +0000 (04:22 +0000)
committerShamus Hammons <jlhamm@acm.org>
Sun, 18 Nov 2012 04:22:58 +0000 (04:22 +0000)
22 files changed:
Makefile
res/cursor5.png
res/cursor6.png
res/cursor7.png
res/cursor8.png
res/cursor9.png [new file with mode: 0644]
res/toolpal1.xpm
src/charwindow.cpp
src/editwindow.cpp
src/editwindow.h
src/glyphpoints.cpp
src/glyphpoints.h
src/mainwindow.cpp [moved from src/ttemainwindow.cpp with 76% similarity]
src/mainwindow.h [moved from src/ttemainwindow.h with 54% similarity]
src/toolwindow.cpp
src/toolwindow.h
src/ttedit.cpp
src/ttedit.h
src/vector.cpp
src/vector.h
ttedit.pro
ttedit.qrc

index 30e8c201e0034b305d0f9b331130493ec4625d87..d5dcd62cee0f50f283f594863628aa02b48a2e58 100755 (executable)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 #############################################################################
 # 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
@@ -16,7 +16,7 @@ CXXFLAGS      = -pipe -O2 -D_REENTRANT -Wall -W $(DEFINES)
 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
@@ -44,20 +44,20 @@ OBJECTS_DIR   = obj/
 ####### 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 \
@@ -65,7 +65,7 @@ OBJECTS       = obj/ttedit.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 \
@@ -184,7 +184,7 @@ qmake:  FORCE
 
 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 
@@ -205,11 +205,11 @@ mocclean: compiler_moc_header_clean compiler_moc_source_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 \
@@ -242,6 +242,7 @@ obj/qrc_ttedit.cpp: ttedit.qrc \
                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
 
@@ -263,15 +264,15 @@ compiler_clean: compiler_moc_header_clean compiler_rcc_clean
 ####### 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 \
@@ -286,17 +287,18 @@ obj/ttemainwindow.o: src/ttemainwindow.cpp src/ttemainwindow.h \
                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 \
@@ -324,8 +326,8 @@ obj/graphicprimitives.o: src/graphicprimitives.cpp src/graphicprimitives.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
index 234c1f3a53d75b9a1837097d05cbf404555501e7..f6e85fe49a9e0a3369e0f7ca0a8df9f8f4a24b46 100644 (file)
Binary files a/res/cursor5.png and b/res/cursor5.png differ
index 88e94bbfaa4a0130667375b23d5b17b3bd8f393b..234c1f3a53d75b9a1837097d05cbf404555501e7 100644 (file)
Binary files a/res/cursor6.png and b/res/cursor6.png differ
index b34c46dfa35371361cdaffb6ad3e25d3fbb23e61..88e94bbfaa4a0130667375b23d5b17b3bd8f393b 100644 (file)
Binary files a/res/cursor7.png and b/res/cursor7.png differ
index 1a7ffdc7834a833c72a3f129a0670c6cff2c039b..b34c46dfa35371361cdaffb6ad3e25d3fbb23e61 100644 (file)
Binary files a/res/cursor8.png and b/res/cursor8.png differ
diff --git a/res/cursor9.png b/res/cursor9.png
new file mode 100644 (file)
index 0000000..1a7ffdc
Binary files /dev/null and b/res/cursor9.png differ
index f6f329f6ea5deb7740befc4d29ee2e108985e158..c340812b3742d1ffab0381d4131e8d5094189419 100755 (executable)
@@ -1,53 +1,53 @@
 /* XPM */
 static const char * toolpal1_xpm[] = {
-"96 48 2 1",
+"120 48 2 1",
 "      c #000000",
 ".     c #FFFFFF",
-"                                                                                                ",
-"   ..................      ..................      ..................      ..................   ",
-"                                                                                                ",
-" . .................. .  . .................. .  . .................. .  . .................. . ",
-" . .... ............. .  . .................. .  . ........  ........ .  . .................. . ",
-" . ....  ............ .  . .................. .  . ........  ........ .  . ......  .......... . ",
-" . ....   ........... .  . .. ............... .  . .......    ....... .  . ....  ..  ........ . ",
-" . ....    .......... .  . ..  .............. .  . .......    ....... .  . ... ...... ....... . ",
-" . ....     ......... .  . ..   ............. .  . ...... .  . ...... .  . ... ...... ....... . ",
-" . ....      ........ .  . ..    ............ .  . ..... ..  .. ..... .  . .. ........ ...... . ",
-" . ....       ....... .  . ..     ...      .. .  . ...  ...  ...  ... .  . .. ........ ...... . ",
-" . ....        ...... .  . ..      ..       . .  . .                . .  . ... ...... ....... . ",
-" . ....         ..... .  . ..       .  ...  . .  . .                . .  . ... ...... ....... . ",
-" . ....      ........ .  . ..     ...  ...  . .  . ...  ...  ...  ... .  . ....  ..    ...... . ",
-" . ....      ........ .  . ..     ...       . .  . ..... ..  .. ..... .  . ......  ..   ..... . ",
-" . ....  ..   ....... .  . .. ..   ..      .. .  . ...... .  . ...... .  . ...........   .... . ",
-" . .... ...   ....... .  . ......  ..  ...... .  . .......    ....... .  . ............   ... . ",
-" . .........   ...... .  . ..........  ...... .  . .......    ....... .  . .............   .. . ",
-" . .........   ...... .  . ..........  ...... .  . ........  ........ .  . ..............  .. . ",
-" . .......... ....... .  . .................. .  . ........  ........ .  . .................. . ",
-" . .................. .  . .................. .  . .................. .  . .................. . ",
-"                                                                                                ",
-"   ..................      ..................      ..................      ..................   ",
-"                                                                                                ",
-"                                                                                                ",
-"   ..................      ..................      ..................      ..................   ",
-"                                                                                                ",
-" . .................. .  . .................. .  . .................. .  . .................. . ",
-" . .................. .  . .................. .  . .................. .  . .................. . ",
-" . .................. .  . ........  ........ .  . ..  ..........  .. .  . ..  ........... .. . ",
-" . .................. .  . .......    ....... .  . ..   ........   .. .  . ...  .      ..  .. . ",
-" . .................. .  . .......    ....... .  . ...   ......   ... .  . ....           ... . ",
-" . .......    ....... .  . ......  ..  ...... .  . ....          .... .  . .....   ...   .... . ",
-" . ......      ...... .  . ......  ..  ...... .  . .....        ..... .  . ......  ...  ..... . ",
-" . .....        ..... .  . .....  ....  ..... .  . .....        ..... .  . ......   .   ..... . ",
-" . .....   ..   ..... .  . .....  ....  ..... .  . .....        ..... .  . ......       ..... . ",
-" . .....   ..   ..... .  . ....  ......  .... .  . .....        ..... .  . ......       ..... . ",
-" . .....        ..... .  . ....  ......  .... .  . .....        ..... .  . ......      ...... . ",
-" . ......      ...... .  . ...  ........  ... .  . .....        ..... .  . ......  ...  ..... . ",
-" . .......    ....... .  . ...  ........  ... .  . ....          .... .  . .....   ....  .... . ",
-" . .................. .  . ..  ..........  .. .  . ...   ......   ... .  . ....    .....  ... . ",
-" . .................. .  . ..              .. .  . ..   ........   .. .  . ...  .  ......  .. . ",
-" . .................. .  . ...            ... .  . ..  ..........  .. .  . ..  ........... .. . ",
-" . .................. .  . .................. .  . .................. .  . .................. . ",
-" . .................. .  . .................. .  . .................. .  . .................. . ",
-"                                                                                                ",
-"   ..................      ..................      ..................      ..................   ",
-"                                                                                                "};
+"                                                                                                                        ",
+"   ..................      ..................      ..................      ..................      ..................   ",
+"                                                                                                                        ",
+" . .................. .  . .................. .  . .................. .  . .................. .  . .......    ....... . ",
+" . .... ............. .  . .................. .  . ........  ........ .  . .................. .  . ......      ...... . ",
+" . ....  ............ .  . .................. .  . ........  ........ .  . ......  .......... .  . ....  .    .  .... . ",
+" . ....   ........... .  . .. ............... .  . .......    ....... .  . ....  ..  ........ .  . ... .. .... .. ... . ",
+" . ....    .......... .  . ..  .............. .  . .......    ....... .  . ... ...... ....... .  . .. .. ...... .. .. . ",
+" . ....     ......... .  . ..   ............. .  . ...... .  . ...... .  . ... ...... ....... .  . .. ............ .. . ",
+" . ....      ........ .  . ..    ............ .  . ..... ..  .. ..... .  . .. ........ ...... .  . . ......  ...... . . ",
+" . ....       ....... .  . ..     ...      .. .  . ...  ...  ...  ... .  . .. ........ ...... .  . . ......  ...... . . ",
+" . ....        ...... .  . ..      ..       . .  . .                . .  . ... ...... ....... .  . . ....      .... . . ",
+" . ....         ..... .  . ..       .  ...  . .  . .                . .  . ... ...... ....... .  . . ....      .... . . ",
+" . ....      ........ .  . ..     ...  ...  . .  . ...  ...  ...  ... .  . ....  ..    ...... .  . . ......  ...... . . ",
+" . ....      ........ .  . ..     ...       . .  . ..... ..  .. ..... .  . ......  ..   ..... .  . . ......  ...... . . ",
+" . ....  ..   ....... .  . .. ..   ..      .. .  . ...... .  . ...... .  . ...........   .... .  . .. ............ .. . ",
+" . .... ...   ....... .  . ......  ..  ...... .  . .......    ....... .  . ............   ... .  . .. ............ .. . ",
+" . .........   ...... .  . ..........  ...... .  . .......    ....... .  . .............   .. .  . ... .......... ... . ",
+" . .........   ...... .  . ..........  ...... .  . ........  ........ .  . ..............  .. .  . ....  ......  .... . ",
+" . .......... ....... .  . .................. .  . ........  ........ .  . .................. .  . ......      ...... . ",
+" . .................. .  . .................. .  . .................. .  . .................. .  . .................. . ",
+"                                                                                                                        ",
+"   ..................      ..................      ..................      ..................      ..................   ",
+"                                                                                                                        ",
+"                                                                                                                        ",
+"   ..................      ..................      ..................      ..................      ..................   ",
+"                                                                                                                        ",
+" . .................. .  . .................. .  . .................. .  . .................. .  . .................. . ",
+" . .................. .  . .................. .  . .................. .  . .................. .  . .................. . ",
+" . .................. .  . ........  ........ .  . ..  ..........  .. .  . ..  ........... .. .  . .................. . ",
+" . .................. .  . .......    ....... .  . ..   ........   .. .  . ...  .      ..  .. .  . .................. . ",
+" . .................. .  . .......    ....... .  . ...   ......   ... .  . ....           ... .  . .................. . ",
+" . .......    ....... .  . ......  ..  ...... .  . ....          .... .  . .....   ...   .... .  . .................. . ",
+" . ......      ...... .  . ......  ..  ...... .  . .....        ..... .  . ......  ...  ..... .  . .................. . ",
+" . .....        ..... .  . .....  ....  ..... .  . .....        ..... .  . ......   .   ..... .  . .................. . ",
+" . .....   ..   ..... .  . .....  ....  ..... .  . .....        ..... .  . ......       ..... .  . .................. . ",
+" . .....   ..   ..... .  . ....  ......  .... .  . .....        ..... .  . ......       ..... .  . .................. . ",
+" . .....        ..... .  . ....  ......  .... .  . .....        ..... .  . ......      ...... .  . .................. . ",
+" . ......      ...... .  . ...  ........  ... .  . .....        ..... .  . ......  ...  ..... .  . .................. . ",
+" . .......    ....... .  . ...  ........  ... .  . ....          .... .  . .....   ....  .... .  . .................. . ",
+" . .................. .  . ..  ..........  .. .  . ...   ......   ... .  . ....    .....  ... .  . .................. . ",
+" . .................. .  . ..              .. .  . ..   ........   .. .  . ...  .  ......  .. .  . .................. . ",
+" . .................. .  . ...            ... .  . ..  ..........  .. .  . ..  ........... .. .  . .................. . ",
+" . .................. .  . .................. .  . .................. .  . .................. .  . .................. . ",
+" . .................. .  . .................. .  . .................. .  . .................. .  . .................. . ",
+"                                                                                                                        ",
+"   ..................      ..................      ..................      ..................      ..................   ",
+"                                                                                                                        "};
index cea3baad3d74f848d94056f22bde8be0444ef3c3..0309b78e82630cbbb00e31540b192c791257fae6 100755 (executable)
@@ -24,7 +24,8 @@
 #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");
 }
index f3cc70fdebc03d551e9186fc9efa898b92217202..85a8ca8d313017942dfba72e0e07eeedb6388563 100755 (executable)
 #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);
@@ -55,22 +56,25 @@ EditWindow::EditWindow(QWidget * parent/*= NULL*/): QWidget(parent),
        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);
@@ -79,6 +83,7 @@ void EditWindow::CreateCursors(void)
        }
 }
 
+
 QPoint EditWindow::GetAdjustedMousePosition(QMouseEvent * event)
 {
        QSize winSize = size();
@@ -88,6 +93,7 @@ QPoint EditWindow::GetAdjustedMousePosition(QMouseEvent * event)
        return QPoint(offsetX + event->x(), offsetY + (winSize.height() - event->y()));
 }
 
+
 QPoint EditWindow::GetAdjustedClientPosition(int x, int y)
 {
        QSize winSize = size();
@@ -96,6 +102,7 @@ QPoint EditWindow::GetAdjustedClientPosition(int x, int y)
        return QPoint(-offsetX + x, (winSize.height() - (-offsetY + y)) * +1.0);
 }
 
+
 /*
 TODO:
  o  Different colors for polys on selected points
@@ -133,13 +140,22 @@ void EditWindow::paintEvent(QPaintEvent * /*event*/)
 ////   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++)
        {
@@ -258,8 +274,115 @@ void EditWindow::paintEvent(QPaintEvent * /*event*/)
                        }
                }
        }
+
+       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)
@@ -336,11 +459,24 @@ WriteLogMsg(" --> [# polys: %u, # points: %u]\n", pts.GetNumPolys(), pts.GetNumP
                                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)
@@ -368,57 +504,58 @@ void EditWindow::mouseMoveEvent(QMouseEvent * event)
        }
        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)
        {
@@ -463,20 +600,20 @@ void EditWindow::mouseMoveEvent(QMouseEvent * event)
                                        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:
 //
@@ -520,6 +657,7 @@ void EditWindow::mouseMoveEvent(QMouseEvent * event)
        event->accept();
 }
 
+
 void EditWindow::mouseReleaseEvent(QMouseEvent * event)
 {
        if (event->button() == Qt::RightButton)
@@ -550,11 +688,21 @@ void EditWindow::mouseReleaseEvent(QMouseEvent * event)
        }
        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();
index 1b24dde34c675dd8cb32bd5c11ad617169f6cf75..9ca997be19e2d8acf2396373d10df340fce24c9c 100755 (executable)
@@ -32,7 +32,9 @@ class EditWindow: public QWidget
                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
@@ -41,9 +43,12 @@ class EditWindow: public QWidget
                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__
index 0fc62f3cd40af42b8bf2603bc8d5aad7330e2bb2..e6dc52c11ca5ec7ffef3dad62ddcbef2fa1c0fe0 100755 (executable)
@@ -22,6 +22,8 @@
 #ifdef DEBUG
 #include "debug.h"
 #endif
+#include <math.h>
+
 
 /*GlyphPoints::GlyphPoints(void)
 {
@@ -46,6 +48,7 @@ WriteLogMsg("GlyphPoints: Default constructor. %u points, %u polys.\n", numPoint
 #endif
 }
 
+
 GlyphPoints::GlyphPoints(int xx, int yy, bool oc)
 {
 //Hmm. What to do with this...?
@@ -55,6 +58,7 @@ WriteLogMsg("GlyphPoints: Single point constructor. %u points, %u polys.\n", num
 #endif
 }
 
+
 // Copy constructor (needed for deep copying)
 
 //GlyphPoints::GlyphPoints(GlyphPoints &c): x(NULL), y(NULL), onCurve(NULL), polyEnd(NULL)
@@ -66,8 +70,11 @@ WriteLogMsg("GlyphPoints: Copy constructor. %u points, %u polys.\n", numPoints,
 #endif
 }
 
+
 GlyphPoints::~GlyphPoints()
 {
+       FreeAllocatedMemory();
+#if 0
        if (x)
                delete[] x;
 
@@ -79,8 +86,10 @@ GlyphPoints::~GlyphPoints()
 
        if (polyEnd)
                delete[] polyEnd;
+#endif
 }
 
+
 void GlyphPoints::AllocateAndCopy(int nPts, int nPlys, int * xa, int * ya, bool * oca, uint16 * pa)
 {
        numPoints = nPts, numPolys = nPlys;
@@ -114,11 +123,29 @@ void GlyphPoints::AllocateAndCopy(int nPts, int nPlys, int * xa, int * ya, bool
        }
 }
 
+
+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;
 
@@ -130,12 +157,14 @@ GlyphPoints& GlyphPoints::operator=(const GlyphPoints &c)
 
        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)
@@ -177,6 +206,7 @@ GlyphPoints GlyphPoints::operator+(const GlyphPoints &c)
        return retVal;
 }
 
+
 // Add a point to this GlyphPoints...
 
 GlyphPoints GlyphPoints::operator+(const IPoint &c)
@@ -205,6 +235,7 @@ GlyphPoints GlyphPoints::operator+(const IPoint &c)
        return retVal;
 }
 
+
 GlyphPoints& GlyphPoints::operator+=(const IPoint &p)
 {
        InsertPoint(numPoints, p.x, p.y, p.onCurve);
@@ -212,6 +243,17 @@ GlyphPoints& GlyphPoints::operator+=(const IPoint &p)
        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...!
@@ -246,11 +288,13 @@ void GlyphPoints::InsertPoint(uint16 pt, int xx, int yy, bool oc)
        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
@@ -283,11 +327,13 @@ void GlyphPoints::DeletePoint(uint16 pt)
                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)
@@ -303,11 +349,13 @@ WriteLogMsg("Exception: GetNumPoints(uint16). poly=%u, numPolys=%u\xD\xA", poly,
        return polyEnd[poly] - (poly == 0 ? -1 : polyEnd[poly - 1]);
 }
 
+
 uint16 GlyphPoints::GetNumPolys(void)
 {
        return numPolys;
 }
 
+
 int GlyphPoints::GetX(uint16 pt)
 {
        if (pt >= numPoints)
@@ -323,6 +371,7 @@ WriteLogMsg("Exception: GetX(uint16). pt=%u, numPoints=%u\xD\xA", pt, numPoints)
        return x[pt];
 }
 
+
 int GlyphPoints::GetY(uint16 pt)
 {
        if (pt >= numPoints)
@@ -338,6 +387,7 @@ WriteLogMsg("Exception: GetY(uint16). pt=%u, numPoints=%u\xD\xA", pt, numPoints)
        return y[pt];
 }
 
+
 bool GlyphPoints::GetOnCurve(uint16 pt)
 {
        if (pt >= numPoints)
@@ -353,6 +403,7 @@ WriteLogMsg("Exception: GetOnCurve(uint16). pt=%u, numPoints=%u\xD\xA", pt, numP
        return onCurve[pt];
 }
 
+
 int GlyphPoints::GetX(uint16 poly, uint16 pt)
 {
        if (pt >= GetNumPoints(poly))
@@ -368,11 +419,13 @@ WriteLogMsg("Exception: GetX(uint16, uint16). poly= %u, pt=%u, numPoints=%u\xD\x
        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))
@@ -388,16 +441,19 @@ WriteLogMsg("Exception: GetY(uint16, uint16). poly= %u, pt=%u, numPoints=%u\xD\x
        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))
@@ -413,16 +469,36 @@ WriteLogMsg("Exception: GetOnCurve(uint16, uint16). poly= %u, pt=%u, numPoints=%
        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)
@@ -438,12 +514,14 @@ WriteLogMsg("Exception: GetPolyEnd(uint16). poly=%u, numPolys=%u\xD\xA", poly, n
        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
 //
@@ -465,6 +543,7 @@ WriteLogMsg("Exception: GetPolyEnd(uint16). poly=%u, numPolys=%u\xD\xA", poly, n
                x[polyStart + i] += xOff, y[polyStart + i] += yOff;
 }
 
+
 void GlyphPoints::ScalePoints(float sc)
 {
        for(int i=0; i<numPoints; i++)
@@ -472,6 +551,7 @@ void GlyphPoints::ScalePoints(float sc)
                y[i] = (int)(((float)y[i] * sc) + 0.5f);
 }
 
+
 void GlyphPoints::SetXY(uint16 pt, int xx, int yy)
 {
        if (pt >= numPoints)
@@ -487,6 +567,7 @@ WriteLogMsg("Exception: SetXY(uint16, int, int). pt=%u, numPoints=%u\xD\xA", pt,
        x[pt] = xx, y[pt] = yy;
 }
 
+
 void GlyphPoints::SetOnCurve(uint16 pt, bool oc)
 {
        if (pt >= numPoints)
@@ -502,6 +583,7 @@ WriteLogMsg("Exception: SetOnCurve(uint16, bool). pt=%u, numPoints=%u\xD\xA", pt
        onCurve[pt] = oc;
 }
 
+
 uint16 GlyphPoints::GetPrev(uint16 pt)
 {
 // pt = 7, polyEnd = 4, 9, 15
@@ -527,6 +609,7 @@ uint16 GlyphPoints::GetPrev(uint16 pt)
        return retVal;
 }
 
+
 uint16 GlyphPoints::GetNext(uint16 pt)
 {
        uint16 min = 0, max = numPoints - 1;
@@ -551,6 +634,7 @@ uint16 GlyphPoints::GetNext(uint16 pt)
        return retVal;
 }
 
+
 //
 // Get previous point for this polygon using wraparound.
 // Note that pt is a zero-based index!
@@ -560,6 +644,7 @@ uint16 GlyphPoints::GetPrev(uint16 poly, uint16 pt)
        return (pt == 0 ? GetNumPoints(poly) - 1 : pt - 1);
 }
 
+
 //
 // Get next point for this polygon using wraparound.
 // Note that pt is a zero-based index!
@@ -569,6 +654,7 @@ uint16 GlyphPoints::GetNext(uint16 poly, uint16 pt)
        return (pt == GetNumPoints(poly) - 1 ? 0 : pt + 1);
 }
 
+
 uint16 GlyphPoints::GetPoly(uint16 pt)
 {
        if (pt >= numPoints)
@@ -588,6 +674,7 @@ WriteLogMsg("Exception: GetPoly(uint16). pt=%u, numPoints=%u\xD\xA", pt, numPoin
        return (uint16)-1;
 }
 
+
 void GlyphPoints::AddNewPolyAtEnd(void)
 {
        if (numPoints == 0)                                                     // By default, we already *have* a poly
@@ -604,6 +691,7 @@ void GlyphPoints::AddNewPolyAtEnd(void)
        polyEnd = newPolyEnd;
 }
 
+
 IPoint GlyphPoints::GetMidpointToPrev(uint16 poly, uint16 pt)
 {
        uint16 prev = GetPrev(poly, pt);
@@ -614,6 +702,7 @@ IPoint GlyphPoints::GetMidpointToPrev(uint16 poly, uint16 pt)
        return IPoint((x1 + x2) / 2.0f, (y1 + y2) / 2.0f);
 }
 
+
 IPoint GlyphPoints::GetMidpointToNext(uint16 poly, uint16 pt)
 {
        uint16 next = GetNext(poly, pt);
@@ -624,6 +713,7 @@ IPoint GlyphPoints::GetMidpointToNext(uint16 poly, uint16 pt)
        return IPoint((x1 + x2) / 2.0f, (y1 + y2) / 2.0f);
 }
 
+
 IPoint GlyphPoints::GetPrevPoint(uint16 poly, uint16 pt)
 {
        uint16 prevPt = GetPrev(poly, pt);
@@ -631,9 +721,157 @@ IPoint GlyphPoints::GetPrevPoint(uint16 poly, uint16 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;
+}
+
index fbcf0a80008110ea9036378b3321c9111e7b0ae8..09b422cde5967b107901e686e68c8d4dc0845060 100755 (executable)
 #define __GLYPHPOINTS_H__
 
 #include "types.h"
+#include <stdio.h>
 
 
+// "IPoint" is an Integer based Point
 struct IPoint
 {
        int32 x, y;
@@ -46,11 +48,12 @@ class GlyphPoints
                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);
@@ -63,6 +66,7 @@ class GlyphPoints
                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);
@@ -80,8 +84,17 @@ class GlyphPoints
                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;
similarity index 76%
rename from src/ttemainwindow.cpp
rename to src/mainwindow.cpp
index 2e155d385fd5aa0f522273a49d3b66770e51e1b2..8c7524f500a1d37f9e409920cb9fd8d6df901c6f 100644 (file)
@@ -1,5 +1,5 @@
 //
-// 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);
@@ -94,6 +94,10 @@ TTEMainWindow::TTEMainWindow()
        editToolBar->addAction(cutAct);
        editToolBar->addAction(copyAct);
        editToolBar->addAction(pasteAct);
+#else
+       CreateActions();
+       CreateMenus();
+       CreateToolbars();
 #endif
 
        //      Create status bar
@@ -110,17 +114,122 @@ TTEMainWindow::TTEMainWindow()
        ((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();
@@ -133,7 +242,8 @@ void TTEMainWindow::ReadSettings(void)
        ((TTEdit *)qApp)->charWnd->move(pos);
 }
 
-void TTEMainWindow::WriteSettings(void)
+
+void MainWindow::WriteSettings(void)
 {
        QSettings settings("Underground Software", "TTEdit");
        settings.setValue("pos", pos());
similarity index 54%
rename from src/ttemainwindow.h
rename to src/mainwindow.h
index 8de8ec1b99f7f6ee450542117612cab01f51f074..166a87ec92eec5bcb0cac994f2a0225163d7eca9 100644 (file)
@@ -1,67 +1,46 @@
 //
-// 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);
 
@@ -88,6 +67,9 @@ class TTEMainWindow: public QMainWindow
 
        DECLARE_EVENT_TABLE()
 #endif
+               QAction * newGlyphAct;
+               QAction * openFileAct;
+               QAction * saveFileAct;
 };
 
-#endif // __TTEMAINWINDOW_H__
+#endif // __MAINWINDOW_H__
index 75eaa0e1a3c129aec0d176ac9f7979e0cfb1c956..0bee1face47b438a5ca7de8e75e8cd39987b7dda 100755 (executable)
@@ -34,7 +34,7 @@ ToolWindow::ToolWindow(void): QWidget(NULL, Qt::Window | Qt::FramelessWindowHint
        // 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);
@@ -54,7 +54,8 @@ void ToolWindow::paintEvent(QPaintEvent * event)
        {
            //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());
        }
 }
@@ -76,8 +77,12 @@ ToolType ToolWindow::FindSelectedTool(void)
        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;
 }
index 1623eb44bc6edb3ec6f5c76bc382407c9ccbd8b3..27a0cb35d96b8309e375f72095064d5b26527067 100755 (executable)
@@ -18,6 +18,7 @@ enum ToolType {
        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
index 62417b5fd010ff88c20f6bfed5a2e60ecdd33856..9f34039982ccb8231ca5302734ff28e456e592a5 100755 (executable)
 
 #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();
 }
index 9bc6b598ab813b0be990c89c404bc43cefeb61ad..3c63025e561b9434ea8288a7d19d76ecca9da9b4 100755 (executable)
@@ -8,12 +8,11 @@
 #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
 {
@@ -22,7 +21,7 @@ class TTEdit: public QApplication
 
        public:
                CharWindow * charWnd;
-               TTEMainWindow * mainWindow;
+               MainWindow * mainWindow;
 };
 
 #endif // __TTEDIT_H__
index 32fe4e1cb7f4e47046cf163827ad1260f195b9e4..1f4c29cc5ae5b69eedd639efaa5fa0a6bc56883c 100755 (executable)
@@ -1,3 +1,5 @@
+#if 0
+
 //
 // VECTOR.H - vector class definition
 //
@@ -14,8 +16,8 @@
 // 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*/):
@@ -139,3 +141,258 @@ void vector::zero(const double epsilon/*= 1.0e-6*/)
        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
index 36025b9c075c44f8103219d2085ad436a97e5a04..6c46dffa842fc7f956ff8c37a0f446a343a70866 100755 (executable)
@@ -1,3 +1,5 @@
+#if 0
+
 //
 // VECTOR.H - vector class definition
 //
@@ -33,3 +35,67 @@ struct vector
 };
 
 #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
index dd20f26e529da47b6f203d982c5aaacff83fc2cf..78798a3033a0878df7edf2d65bdb404224ea30ce 100644 (file)
@@ -5,7 +5,7 @@ CONFIG += qt
 #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
@@ -17,7 +17,7 @@ HEADERS += src/graphicprimitives.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
index ca2b69b057e1fb4192f1d30d9bcbb6897cda6c58..27c4f83a88a87e478b4ca98ef9d1de6a3abaee31 100644 (file)
@@ -8,6 +8,7 @@
        <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>