Merge branch 'master' of git.ucc.asn.au:/ipdf/code
authorSam Moore <[email protected]>
Mon, 18 Aug 2014 13:47:51 +0000 (21:47 +0800)
committerSam Moore <[email protected]>
Mon, 18 Aug 2014 13:47:51 +0000 (21:47 +0800)
Noooo

15 files changed:
src/DejaVuSansMono.ttf [deleted file]
src/bezier.cpp
src/controlpanel.cpp
src/controlpanel.h
src/document.cpp
src/document.h
src/fonts/BleedingCowboys.ttf [new file with mode: 0644]
src/fonts/ComicSans.ttf [new file with mode: 0644]
src/fonts/DejaVuSansMono.ttf [new file with mode: 0644]
src/main.cpp
src/main.h
src/screen.cpp
src/screen.h
src/view.cpp
src/view.h

diff --git a/src/DejaVuSansMono.ttf b/src/DejaVuSansMono.ttf
deleted file mode 100644 (file)
index 1376228..0000000
Binary files a/src/DejaVuSansMono.ttf and /dev/null differ
index da65336..b3129e4 100644 (file)
@@ -71,10 +71,10 @@ static pair<Real, Real> BezierTurningPoints(const Real & p0, const Real & p1, co
                if (t < 0) t = 0;
                return pair<Real, Real>(t, t);
        }
-       Debug("a, b, c are %f, %f, %f", Float(a), Float(b), Float(c));
+       //Debug("a, b, c are %f, %f, %f", Float(a), Float(b), Float(c));
        if (b*b - 4*a*c < 0)
        {
-               Debug("No real roots");
+               //Debug("No real roots");
                return pair<Real, Real>(0,1);
        }
        pair<Real, Real> tsols = SolveQuadratic(a, b, c);
@@ -102,7 +102,7 @@ Rect Bezier::SolveBounds() const
        Evaluate(tp0, o, tsols.first);
        Evaluate(tp1, o, tsols.second);
        
-       Debug("x: tp0 is %f tp1 is %f", Float(tp0), Float(tp1));
+       //Debug("x: tp0 is %f tp1 is %f", Float(tp0), Float(tp1));
        
        vector<const Real*> v(4);
        v[0] = &x0;
@@ -122,7 +122,7 @@ Rect Bezier::SolveBounds() const
        Evaluate(o, tp1, tsols.second);
        
        
-       Debug("y: tp0 is %f tp1 is %f", Float(tp0), Float(tp1));
+       //Debug("y: tp0 is %f tp1 is %f", Float(tp0), Float(tp1));
        
        v[0] = &y0;
        v[1] = &y3;
@@ -133,7 +133,7 @@ Rect Bezier::SolveBounds() const
        result.y = *(v[0]);
        result.h = *(v[3]) - result.y;
        
-       Debug("Solved Bezier %s bounds as %s", Str().c_str(), result.Str().c_str());
+       //Debug("Solved Bezier %s bounds as %s", Str().c_str(), result.Str().c_str());
        return result;
 }
 
index 984a459..41013d0 100644 (file)
@@ -3,25 +3,28 @@
  */
 
 #include "controlpanel.h"
+
+#ifndef CONTROLPANEL_DISABLED
+
 #include "view.h"
 #include "screen.h"
 #include "document.h"
+#include <string>
+#include <algorithm>
 
-#ifndef CONTROLPANEL_DISABLED
+using namespace std;
 
 namespace IPDF
 {
        
        
 ControlPanel::ControlPanel(RunArgs & args, QWidget * p) : QMainWindow(p), 
-       m_view(args.view), m_doc(args.doc), m_screen(args.screen)
+       m_view(args.view), m_doc(args.doc), m_screen(args.screen), m_width(300), m_height(300),
+       m_state(ControlPanel::ABOUT), m_on_ok(NULL)
 {
        // Size
-       resize(300,300);
-       // Title
-       setWindowTitle("IPDF Control Panel");
-       // Tooltip
-       setToolTip("This is the IPDF Control Panel.\nDo you feel in control?");
+       resize(m_width,m_height);
+
        
        // Main menues
        CreateMainMenu();
@@ -29,14 +32,30 @@ ControlPanel::ControlPanel(RunArgs & args, QWidget * p) : QMainWindow(p),
        CreateDocumentMenu();
        CreateScreenMenu();
        
+       CreateLayout();
+       
        UpdateAll();
+}
 
+void ControlPanel::CreateLayout()
+{
+       m_text_edit = new QTextEdit(this);
+       m_text_edit->setGeometry(10,35,m_width-20,m_height-100);
+       
+       m_ok_button = new QPushButton("OK", this);
+       m_ok_button->setGeometry(10,35+m_height-90, m_width-20, 50);
+       connect(m_ok_button, SIGNAL(clicked()), this, SLOT(PressOK()));
 }
 
 QMenu * ControlPanel::CreateMainMenu()
 {
        QMenu * main = menuBar()->addMenu("&Main");
        
+       QAction * about = new QAction("&About", this);
+       main->addAction(about);
+       connect(about, SIGNAL(triggered()), this, SLOT(StateAbout()));
+       
+       
        // Quit entry
        QAction * quit = new QAction("&Quit", this);
        main->addAction(quit);
@@ -47,6 +66,24 @@ QMenu * ControlPanel::CreateMainMenu()
 QMenu * ControlPanel::CreateDocumentMenu()
 {
        QMenu * document = menuBar()->addMenu("&Document");
+       
+       m_document_set_font = new QAction("&Set Insertion Font", this);
+       document->addAction(m_document_set_font);
+       connect(m_document_set_font, SIGNAL(triggered()), this, SLOT(SetDocumentFont()));
+       
+       m_document_insert_text = new QAction("&Insert Text", this);
+       document->addAction(m_document_insert_text);
+       connect(m_document_insert_text, SIGNAL(triggered()), this, SLOT(StateInsertText()));
+       
+       m_document_load_svg = new QAction("&Load SVG From File", this);
+       document->addAction(m_document_load_svg);
+       connect(m_document_load_svg, SIGNAL(triggered()), this, SLOT(LoadSVGIntoDocument()));
+       
+       m_document_parse_svg = new QAction("&Input SVG Manually", this);
+       document->addAction(m_document_parse_svg);
+       connect(m_document_parse_svg, SIGNAL(triggered()), this, SLOT(StateParseSVG()));
+       
+       
        return document;
 }
 
@@ -54,7 +91,9 @@ QMenu * ControlPanel::CreateViewMenu()
 {
        QMenu * view = menuBar()->addMenu("&View");
        
-
+       m_view_set_bounds = new QAction("&Set bounds", this);
+       view->addAction(m_view_set_bounds);
+       connect(m_view_set_bounds, SIGNAL(triggered()), this, SLOT(SetViewBounds()));
        
        return view;
 }
@@ -67,9 +106,11 @@ QMenu * ControlPanel::CreateScreenMenu()
        
        m_screen_gpu_rendering = new QAction("&GPU Rendering", this);
        m_screen_gpu_rendering->setCheckable(true);
+       m_screen_gpu_rendering->setToolTip("Uses the GPU for Rendering");
        
        m_screen_cpu_rendering = new QAction("&CPU Rendering", this);
        m_screen_cpu_rendering->setCheckable(true);
+       m_screen_gpu_rendering->setToolTip("Uses the CPU for Rendering");
                
        screen->addAction(m_screen_gpu_rendering);
        screen->addAction(m_screen_cpu_rendering);
@@ -77,14 +118,73 @@ QMenu * ControlPanel::CreateScreenMenu()
        connect(m_screen_gpu_rendering, SIGNAL(triggered()), this, SLOT(SetGPURendering()));
        connect(m_screen_cpu_rendering, SIGNAL(triggered()), this, SLOT(SetCPURendering()));
        
+       m_screen_show_debug = new QAction("&Print Debug Info", this);
+       m_screen_show_debug->setCheckable(true);
+       
+       screen->addAction(m_screen_show_debug);
+       connect(m_screen_show_debug, SIGNAL(triggered()), this, SLOT(ToggleScreenDebugFont()));
+       
        return screen;
 }
 
+void ControlPanel::paintEvent(QPaintEvent * e)
+{
+//     Debug("Called");
+       
+}
+
+void ControlPanel::ChangeState(State next_state)
+{
+       m_state = next_state;
+       UpdateAll();
+}
+
+
 void ControlPanel::UpdateAll()
 {
        bool using_gpu_rendering = m_view.UsingGPURendering();
        m_screen_gpu_rendering->setChecked(using_gpu_rendering);
        m_screen_cpu_rendering->setChecked(!using_gpu_rendering);       
+       m_screen_show_debug->setChecked(m_screen.DebugFontShown());
+       
+       // update things based on state
+       const char * title;
+       const char * tooltip;
+       switch (m_state)
+       {
+               case INSERT_TEXT:
+                       title = "Insert Text";
+                       tooltip = "Type text to insert, press OK, simple.";
+                       m_text_edit->show();
+                       m_ok_button->show();
+                       m_on_ok = &ControlPanel::InsertTextIntoDocument;
+                       if (m_text_edit->toPlainText() == "")
+                               m_text_edit->setText("The quick brown\nfox jumps over\nthe lazy dog.");
+                       break;
+               case PARSE_SVG:
+                       title = "Parse SVG";
+                       tooltip = "Enter valid SVG and press OK to insert.";
+                       m_text_edit->show();
+                       m_ok_button->show();
+                       m_on_ok = &ControlPanel::InsertSVGIntoDocument;
+                       if (m_text_edit->toPlainText() == "")
+                               m_text_edit->setText("<svg width=\"104\" height=\"186\">\n<path d = \"m 57,185\n\t c 0,0 57,-13 32,-43\n\t -25,-30 -53,2 -25, -30\n\t 28,-32 52,17 28,-32\n\t -24,-50 -16,44 -35,12\n\t-19,-32 13,-64 13,-64\n\t 0,0 40,-50 -0,-14\n\t -40,36 -94,68 -59,109\n\t 35,41 45,62 45,62 z\"/>\n</svg>");
+                       
+                       break;
+               case ABOUT:
+               default:
+                       title = "IPDF Control Panel";
+                       tooltip = "This is the IPDF Control Panel\nDo you feel in control?";
+                       m_text_edit->hide();
+                       m_ok_button->hide();
+                       m_on_ok = NULL;
+                       break;
+       }
+       
+       // Title
+       setWindowTitle(title);
+       // Tooltip
+       setToolTip(tooltip);
 }
 
 void ControlPanel::SetGPURendering()
@@ -99,6 +199,79 @@ void ControlPanel::SetCPURendering()
        UpdateAll();
 }
 
+void ControlPanel::ToggleScreenDebugFont()
+{
+       bool state = m_screen.DebugFontShown();
+       m_screen.ShowDebugFont(!state);
+       UpdateAll();
+       
+}
+
+void ControlPanel::SetViewBounds()
+{
+       bool ok;
+       Real xx = QInputDialog::getDouble(this, "View X Coordinate", "Enter X coordinate:", 0, -2e-30, 2e30,30,&ok);
+       
+       Real yy = QInputDialog::getDouble(this, "View Y Coordinate", "Enter Y coordinate:", 0, -2e-30, 2e30,30,&ok);
+       
+       Real w = QInputDialog::getDouble(this, "View Width", "Enter Width:", 1, -2e-30, 2e30,30,&ok);
+       
+       Real h = QInputDialog::getDouble(this, "View Height", "Enter Height:", 1, -2e-30, 2e30,30,&ok);
+       m_view.SetBounds(Rect(xx,yy,w,h));
+       
+}
+
+void ControlPanel::InsertTextIntoDocument()
+{
+       const Rect & bounds = m_view.GetBounds();
+       Real xx = bounds.x + bounds.w/Real(2);
+       Real yy = bounds.y + bounds.h/Real(2);
+       
+       string msg = m_text_edit->toPlainText().toStdString();
+       Real scale = bounds.w / Real(2);
+       Debug("Insert \"%s\" at %f, %f, scale %f", msg.c_str(), Float(xx), Float(yy), Float(scale));
+       //m_doc.Add(RECT_OUTLINE, bounds, 0); // debugging; text needs to go in the boujnds
+       m_doc.AddText(msg, xx, yy, scale);
+       m_view.ForceRenderDirty();
+       m_view.ForceBufferDirty();
+       m_view.ForceBoundsDirty();
+}
+void ControlPanel::InsertSVGIntoDocument()
+{
+       Rect bounds(m_view.GetBounds());
+       bounds.w /= Real(m_screen.ViewportWidth());
+       bounds.h /= Real(m_screen.ViewportHeight());
+       
+       m_doc.ParseSVG(m_text_edit->toPlainText().toStdString(), bounds);
+       m_view.ForceRenderDirty();
+       m_view.ForceBufferDirty();
+       m_view.ForceBoundsDirty();
+}
+
+void ControlPanel::LoadSVGIntoDocument()
+{
+
+       QString filename = QFileDialog::getOpenFileName(this, "Open SVG", "svg-tests", "Image Files (*.svg)");
+       if (filename == "")
+               return;
+       
+       Rect bounds(m_view.GetBounds());
+       bounds.w /= Real(m_screen.ViewportWidth());
+       bounds.h /= Real(m_screen.ViewportHeight());
+       
+       m_doc.LoadSVG(filename.toStdString(), bounds);
+       m_view.ForceRenderDirty();
+       m_view.ForceBufferDirty();
+       m_view.ForceBoundsDirty();
+}
+
+void ControlPanel::SetDocumentFont()
+{
+       QString filename = QFileDialog::getOpenFileName(this, "Set Font", "fonts", "True Type Fonts (*.ttf)");
+       if (filename != "")
+               m_doc.SetFont(filename.toStdString());
+}
+
 ControlPanel * ControlPanel::g_panel = NULL;
 
 int ControlPanel::Run(void * args)
index f799375..90394f8 100644 (file)
@@ -16,7 +16,9 @@
 #include <QMenu>
 #include <QMenuBar>
 #include <QApplication>
-
+#include <QTextEdit>
+#include <QInputDialog>
+#include <QFileDialog>
 
 
 namespace IPDF
@@ -47,34 +49,69 @@ namespace IPDF
                        };
                        
                        static int Run(void * args);
-                       static void Update() {if (g_panel != NULL) g_panel->UpdateAll();};
-                       
-                       ControlPanel(RunArgs & a, QWidget * p = NULL);
-                       virtual ~ControlPanel() {}
+                       static void Update() {if (g_panel != NULL) g_panel->UpdateAll();}                       
+       
+               private:
+                       typedef enum {
+                               ABOUT,
+                               INSERT_TEXT,
+                               PARSE_SVG
+                       } State;
                        
                private slots:
                        void SetGPURendering();
                        void SetCPURendering();
-
+                       void ToggleScreenDebugFont();
+                       void SetViewBounds();
+                       void LoadSVGIntoDocument();
+                       void SetDocumentFont();
+                       void StateInsertText() {ChangeState(INSERT_TEXT);}
+                       void StateAbout() {ChangeState(ABOUT);}
+                       void StateParseSVG() {ChangeState(PARSE_SVG);}
+                       void PressOK() {if (m_on_ok != NULL) (this->*m_on_ok)();}
 
                private:
                        static ControlPanel * g_panel;
-
-                       
+                       void paintEvent(QPaintEvent * e);
+                       ControlPanel(RunArgs & a, QWidget * p = NULL);
+                       virtual ~ControlPanel() {}
                        void UpdateAll();
-                                       
+                       void ChangeState(State next_state);
                        View & m_view;
                        Document & m_doc;
                        Screen & m_screen;
                        
+                       int m_width;
+                       int m_height;
+                       
+                       
+                       State m_state;
+                       
                        QMenu * CreateMainMenu();
                        QMenu * CreateViewMenu();
                        QMenu * CreateDocumentMenu();
                        QMenu * CreateScreenMenu();
+                       void CreateLayout();
+                       
+                       void InsertTextIntoDocument();
+                       void InsertSVGIntoDocument();
                        
                        QAction * m_screen_gpu_rendering;
                        QAction * m_screen_cpu_rendering;
+                       QAction * m_screen_show_debug;
+                       
+                       QAction * m_document_set_font;
+                       QAction * m_document_insert_text;
+                       QAction * m_document_parse_svg;
+                       QAction * m_document_load_svg;
+                       QAction * m_view_set_bounds;
                        
+               
+                       QTextEdit * m_text_edit;
+                       QPushButton * m_ok_button;
+                       
+                       void (ControlPanel::* m_on_ok)();
+
 
        };
 
index 3f00e64..48e15a8 100644 (file)
@@ -545,6 +545,24 @@ void Document::ParseSVGNode(pugi::xml_node & root, SVGMatrix & parent_transform)
        }
 }
 
+/**
+ * Parse an SVG string into a rectangle
+ */
+void Document::ParseSVG(const string & input, const Rect & bounds)
+{
+       using namespace pugi;
+       
+       xml_document doc_xml;
+       xml_parse_result result = doc_xml.load(input.c_str());
+       
+       if (!result)
+               Error("Couldn't parse SVG input - %s", result.description());
+               
+       Debug("Loaded XML - %s", result.description());
+       SVGMatrix transform = {bounds.w, 0,bounds.x, 0,bounds.h,bounds.y};
+       ParseSVGNode(doc_xml, transform);
+}
+
 /**
  * Load an SVG into a rectangle
  */
@@ -557,7 +575,7 @@ void Document::LoadSVG(const string & filename, const Rect & bounds)
        xml_parse_result result = doc_xml.load(input);
        
        if (!result)
-               Fatal("Couldn't load \"%s\" - %s", filename.c_str(), result.description());
+               Error("Couldn't load \"%s\" - %s", filename.c_str(), result.description());
                
        Debug("Loaded XML - %s", result.description());
        
@@ -758,7 +776,7 @@ void Document::SetFont(const string & font_filename)
                free(m_font_data);
        }
        
-       FILE *font_file = fopen("DejaVuSansMono.ttf", "rb");
+       FILE *font_file = fopen(font_filename.c_str(), "rb");
        fseek(font_file, 0, SEEK_END);
        size_t font_file_size = ftell(font_file);
        fseek(font_file, 0, SEEK_SET);
@@ -863,6 +881,7 @@ void Document::AddFontGlyphAtPoint(stbtt_fontinfo *font, int character, Real sca
        {
                AddGroup(start_index, end_index);
        }
+       Debug("Added Glyph \"%c\" at %f %f, scale %f", (char)character, Float(x), Float(y), Float(scale));
 
        stbtt_FreeShape(font, instructions);
 }
index 6592f4b..3ff607b 100644 (file)
@@ -27,7 +27,7 @@ namespace IPDF
        class Document
        {
                public:
-                       Document(const std::string & filename = "", const std::string & font_filename = "DejaVuSansMono.ttf") : m_objects(), m_count(0), m_font_data(NULL), m_font()
+                       Document(const std::string & filename = "", const std::string & font_filename = "fonts/DejaVuSansMono.ttf") : m_objects(), m_count(0), m_font_data(NULL), m_font()
                        {
                                Load(filename);
                                if (font_filename != "")
@@ -65,6 +65,7 @@ namespace IPDF
                        
                        /** Load an SVG text file and add to the document **/
                        void LoadSVG(const std::string & filename, const Rect & bounds = Rect(0,0,1,1));
+                       void ParseSVG(const std::string & svg, const Rect & bounds = Rect(0,0,1,1));
                        
                        /** Parse an SVG node or SVG-group node, adding children to the document **/
                        void ParseSVGNode(pugi::xml_node & root, SVGMatrix & transform);
diff --git a/src/fonts/BleedingCowboys.ttf b/src/fonts/BleedingCowboys.ttf
new file mode 100644 (file)
index 0000000..9aeda00
Binary files /dev/null and b/src/fonts/BleedingCowboys.ttf differ
diff --git a/src/fonts/ComicSans.ttf b/src/fonts/ComicSans.ttf
new file mode 100644 (file)
index 0000000..d17e1be
Binary files /dev/null and b/src/fonts/ComicSans.ttf differ
diff --git a/src/fonts/DejaVuSansMono.ttf b/src/fonts/DejaVuSansMono.ttf
new file mode 100644 (file)
index 0000000..1376228
Binary files /dev/null and b/src/fonts/DejaVuSansMono.ttf differ
index 2612afc..848debc 100644 (file)
@@ -14,7 +14,7 @@ int main(int argc, char ** argv)
 
        Debug("Compiled with REAL = %d => \"%s\" sizeof(Real) == %d bytes", REAL, g_real_name[REAL], sizeof(Real));
 
-       Document doc;
+       Document doc("","fonts/ComicSans.ttf");
        srand(time(NULL));
 
        enum {OUTPUT_TO_BMP, LOOP} mode = LOOP;
@@ -86,9 +86,7 @@ int main(int argc, char ** argv)
        }
        else 
        {
-               //doc.AddBezier(Bezier(0,0, 1,0.5, 0.5,1, 1,1));
-               doc.AddText("The quick brown\nfox jumps over\nthe lazy dog",0.1,0,0.5);
-               //doc.AddBezier(Bezier(0,0,0,0.1,0,0.1,0,0.1));
+               doc.Add(RECT_OUTLINE, Rect(0,0,0,0),0); // hack to stop segfault if document is empty (:S)
        }
        Debug("Start!");
        Rect bounds(b[0],b[1],b[2],b[3]);
index 9e48967..5ca71ef 100644 (file)
@@ -82,7 +82,7 @@ inline void MainLoop(Document & doc, Screen & scr, View & view)
 {
        // order is important... segfaults occur when screen (which inits GL) is not constructed first -_-
 
-       scr.DebugFontInit("DejaVuSansMono.ttf");
+       scr.DebugFontInit("fonts/DejaVuSansMono.ttf");
        scr.SetMouseHandler(RatCatcher);
 
        double total_cpu_time = 0;
index 223f4a3..a32b1e2 100644 (file)
@@ -93,9 +93,12 @@ Screen::Screen()
 
        m_debug_font_atlas = 0;
        m_no_quit_requested = true;
+       m_show_debug_font = true;
        m_view = NULL;
        ResizeViewport(800, 600);
        
+       
+       
        Clear();
        Present();
        
@@ -454,7 +457,7 @@ struct fontvertex
 
 void Screen::DebugFontPrint(const char* str)
 {
-       if (!m_debug_font_atlas) return;
+       if (!m_debug_font_atlas || !m_show_debug_font) return;
 
        glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 41, -1, "Screen::DebugFontPrint()");
 
index 6b52a09..aed042d 100644 (file)
@@ -72,6 +72,9 @@ namespace IPDF
                
                void RequestQuit() {m_no_quit_requested = false;}
                bool QuitRequested() const {return !m_no_quit_requested;}
+               
+               void ShowDebugFont(bool show = true) {m_show_debug_font = show;}
+               bool DebugFontShown() const {return m_show_debug_font;}
        private:
                void ResizeViewport(int width, int height);
                void DebugFontFlush();
@@ -104,6 +107,7 @@ namespace IPDF
                int m_debug_font_index_head;
                View * m_view;
                bool m_no_quit_requested;
+               bool m_show_debug_font;
        };
 
 }
index a953579..d7d1e34 100644 (file)
@@ -77,6 +77,21 @@ void View::Translate(Real x, Real y)
        m_bounds_dirty = true;
 }
 
+/**
+ * Set View bounds
+ * @param bounds - New bounds
+ */
+void View::SetBounds(const Rect & bounds)
+{
+       m_bounds.x = bounds.x;
+       m_bounds.y = bounds.y;
+       m_bounds.w = bounds.w;
+       m_bounds.h = bounds.h;
+       if (!m_use_gpu_transform)
+               m_buffer_dirty = true;
+       m_bounds_dirty = true;
+}
+
 /**
  * Scale the View at a point
  * @param x, y - Coordinates to scale at (eg: Mouse cursor position)
index ff34415..fe93e6c 100644 (file)
@@ -27,11 +27,13 @@ namespace IPDF
                        
                        void Translate(Real x, Real y);
                        void ScaleAroundPoint(Real x, Real y, Real scale_amount);
+                       void SetBounds(const Rect & new_bounds);
                        
                        Rect TransformToViewCoords(const Rect& inp) const;
                        
                        const Rect& GetBounds() const { return m_bounds; }
                        
+                       
                        const bool UsingGPUTransform() const { return m_use_gpu_transform; } // whether view transform calculated on CPU or GPU
                        const bool UsingGPURendering() const { return m_use_gpu_rendering; } // whether GPU shaders are used or CPU rendering
                        void ToggleGPUTransform() { m_use_gpu_transform = (!m_use_gpu_transform); m_bounds_dirty = true; m_buffer_dirty = true; }

UCC git Repository :: git.ucc.asn.au