Merge branch 'master' of git.ucc.asn.au:ipdf/code
authorDavid Gow <david@ingeniumdigital.com>
Thu, 17 Apr 2014 02:52:45 +0000 (10:52 +0800)
committerDavid Gow <david@ingeniumdigital.com>
Thu, 17 Apr 2014 02:52:45 +0000 (10:52 +0800)
17 files changed:
.gitignore
bin/ipdf [new file with mode: 0755]
contrib/vfpu [new symlink]
src/Makefile
src/ipdf.h
src/main.cpp
src/main.h
src/real.h
src/screen.cpp
src/screen.h
src/tests/repr.cpp [new file with mode: 0644]
src/tests/vfpufloat.cpp [new file with mode: 0644]
src/vfpu [new symlink]
src/vfpu.cpp [new file with mode: 0644]
src/vfpu.h [new file with mode: 0644]
src/view.cpp
src/view.h

index 365a631..5041ffa 100644 (file)
@@ -5,3 +5,5 @@
 *.test
 *.out
 *.err
+*.vcd
+*.bmp
diff --git a/bin/ipdf b/bin/ipdf
new file mode 100755 (executable)
index 0000000..f242971
Binary files /dev/null and b/bin/ipdf differ
diff --git a/contrib/vfpu b/contrib/vfpu
new file mode 120000 (symlink)
index 0000000..98828c0
--- /dev/null
@@ -0,0 +1 @@
+../../vfpu/bin/vfpu
\ No newline at end of file
index d7247ce..c788f85 100644 (file)
@@ -1,11 +1,11 @@
 #Makefile
-ARCH := $(shell uname -i)
+ARCH := $(shell uname -m)
 CXX = g++ -std=gnu++0x -Wall -Werror -Wshadow -pedantic -g
 MAIN = main.o
-OBJ = log.o document.o view.o screen.o
+OBJ = log.o document.o view.o screen.o vfpu.o
 LIB_x86_64 = ../contrib/lib/libSDL2-2.0.so.0 -lGL
 LIB_i386 = ../contrib/lib32/libSDL2-2.0.so.0 -lGL
-LIB_unknown = $(LIB_x86_64)
+
 MAINRPATH_x86_64 = -Wl,-rpath,'$$ORIGIN/../contrib/lib'
 MAINRPATH_i386 = -Wl,-rpath,'$$ORIGIN/../contrib/lib32'
 TESTRPATH_x86_64 = -Wl,-rpath,'$$ORIGIN/../../contrib/lib'
@@ -14,7 +14,7 @@ OBJPATHS = $(OBJ:%=../obj/%)
 DEPS := $(OBJPATHS:%.o=%.d)
 CFLAGS_x86_64 := -I../contrib/include/SDL2 -I`pwd`
 CFLAGS_i386 := -I../contrib/include32/SDL2 -I`pwd`
-CFLAGS_unknown = $(CFLAGS_x86_64)
+
 
 LIB := $(LIB_$(ARCH))
 MAINRPATH := $(MAINRPATH_$(ARCH))
index d6dc955..7150944 100644 (file)
@@ -35,6 +35,13 @@ namespace IPDF
                }
        };
 
+       struct Colour
+       {
+               float r; float g; float b; float a;
+               Colour() = default;
+               Colour(float _r, float _g, float _b, float _a) : r(_r), g(_g), b(_b), a(_a) {}
+       };
+
        struct Objects
        {
                std::vector<ObjectType> types;          
index 1b2073e..12d8d56 100644 (file)
@@ -4,20 +4,66 @@ int main(int argc, char ** argv)
 {      
        Document doc;
        srand(time(NULL));
-       if (argc > 1)
+
+       enum {OUTPUT_TO_BMP, LOOP} mode = LOOP;
+       
+       Rect bounds(0,0,1,1);
+       Colour c(0,0,0,1);
+       const char * input_bmp = NULL;
+       const char * output_bmp = NULL;
+       const char * input_filename = NULL;
+
+       int i = 0;
+       while (++i < argc)
        {
-               for (int i = 2; i < argc; ++i)
+               if (argv[i][0] != '-')
                {
-                       if (fork() == 0) doc.Load(argv[i]);
+                       input_filename = argv[i];
+                       continue;               
                }
-               doc.Load(argv[1]);
+               switch (argv[i][1])
+               {
+                       case 'o':
+                               mode = OUTPUT_TO_BMP;
+                               if (++i >= argc)
+                                       Fatal("No input argument following -o switch");
+                               input_bmp = argv[i];
+                               if (++i >= argc)
+                                       Fatal("No output argument following -o switch");
+                               output_bmp = argv[i];
+
+                               break;
+                       case 'c':
+                       {
+                               Debug("Reading paint colour");
+                               for (int j = 1; j <= 4; ++j)
+                               {
+                                       if (i+j >= argc)
+                                               Fatal("No %d colour component following -c switch", j);
+                                       char * e;
+                                       float * comp = (j == 1) ? (&c.r) : ((j == 2) ? (&c.g) : ((j == 3) ? (&c.b) : &(c.a)));
+                                       *comp = strtof(argv[i+j], &e);
+                                       if (*e != '\0')
+                                               Fatal("Colour component %d not a valid float", j); 
+                               }
+                               i += 4;
+                               break;
+                       }
+               }       
+       }
+
+       if (input_filename != NULL)
+       {
+               doc.Load(input_filename);
        }
-       else
+       else 
        {
-               Debug("Add random object");
-               //doc.Add(RECT_FILLED, Rect(Random()*0.5, Random()*0.5, Random()*0.5, Random()*0.5));
-               doc.Add(RECT_FILLED, Rect(0.25,0.25, 0.5, 0.5));
+               doc.Add(RECT_FILLED, Rect(0.2,0.2,0.6,0.6));
        }
-       MainLoop(doc);
+
+       if (mode == LOOP)
+               MainLoop(doc, bounds, c);
+       else if (mode == OUTPUT_TO_BMP)
+               OverlayBMP(doc, input_bmp, output_bmp, bounds, c);
        return 0;
 }
index 2346119..6763042 100644 (file)
@@ -3,16 +3,28 @@
 #include "document.h"
 #include "view.h"
 #include "screen.h"
+#include <unistd.h>
 
 
 using namespace std;
 using namespace IPDF;
 
-inline void MainLoop(Document & doc)
+inline void OverlayBMP(Document & doc, const char * input, const char * output, const Rect & bounds = Rect(0,0,1,1), const Colour & c = Colour(0.f,0.f,0.f,1.f))
 {
-       View view(doc);
+       View view(doc, bounds, c);
        Screen scr;
-       scr.SetMouseHandler([&](int x, int y, int buttons, int wheel)
+       //view.Render();
+       scr.RenderBMP(input);
+       scr.Present();
+       sleep(5);
+       scr.ScreenShot(output);
+}
+
+inline void MainLoop(Document & doc, const Rect & bounds = Rect(0,0,1,1), const Colour & c = Colour(0.f,0.f,0.f,1.f))
+{
+       View view(doc,bounds, c);
+       Screen scr;
+       scr.SetMouseHandler([&](int x, int y, int buttons, int wheel) // [?] wtf
        {
                static bool oldButtonDown = false;
                static int oldx, oldy;
@@ -42,6 +54,7 @@ inline void MainLoop(Document & doc)
                }
        }
        );
+
        while (scr.PumpEvents())
        {
                view.Render();
index 5703671..73aca6d 100644 (file)
@@ -16,41 +16,7 @@ namespace IPDF
 #elif defined REAL_DOUBLE
        typedef double Real;
        inline double Float(Real r) {return r;}
-#elif defined REAL_HALF
-       struct Real
-       {
-               Real() = default;
-               Real(double r) : value(r) 
-               {
-                       int & a = *((int*)(&value)); // um...
-                       // mask out extra bits in exponent
-                        //1000 1111 1000 0000 0000 0011 1111 1111
-                       // Endianness matters
-                       a &= 0xFFC001F1; //0x8F8003FF;
-
-               }       
-       
-               Real operator+(float f) const {return Real(value+f);}
-               Real operator-(float f) const {return Real(value+f);}
-               Real operator/(float f) const {return Real(value/f);}
-               Real operator*(float f) const {return Real(value*f);}
-               Real operator+(const Real & r) const {return Real(this->value + r.value);}
-               Real operator-(const Real & r) const {return Real(this->value - r.value);}
-               Real operator*(const Real & r) const {return Real(this->value * r.value);}
-               Real operator/(const Real & r) const {return Real(this->value / r.value);}
-               Real & operator+=(const Real & r) {this->value += r.value; return *this;}
-               Real & operator-=(const Real & r) {this->value -= r.value; return *this;}
-               Real & operator/=(const Real & r) {this->value /= r.value; return *this;}
-               Real & operator*=(const Real & r) {this->value *= r.value; return *this;}
-
-               float value;
-       };
-       inline float Float(Real r) {return r.value;}
-
-       inline std::ostream & operator<<(std::ostream & os, Real & r) {return os << r.value;} // yuk
-
-#endif //REAL_HALF
-
+#endif
 }
 
 #endif //_REAL_H
index 9ee15b4..712bd26 100644 (file)
@@ -18,6 +18,10 @@ Screen::Screen()
        }
 
        m_gl_context = SDL_GL_CreateContext(m_window);
+
+       glClearColor(1.f,1.f,1.f,1.f);
+       glClear(GL_COLOR_BUFFER_BIT);
+       Present();
        
        ResizeViewport(800, 600);
 
@@ -80,6 +84,16 @@ bool Screen::PumpEvents()
                                m_mouse_handler(m_last_mouse_x, m_last_mouse_y, 0, evt.wheel.y);
                        }
                        break;
+               case SDL_KEYDOWN:
+               {
+                       Debug("Key %c down", (char)evt.key.keysym.sym);
+                       if (isalnum((char)evt.key.keysym.sym))
+                       {
+                               char filename[] = "0.bmp";
+                               filename[0] = (char)evt.key.keysym.sym;
+                               ScreenShot(filename);
+                       }
+               }
                default:
                        break;
                }
@@ -109,3 +123,88 @@ void Screen::Present()
        SDL_GL_SwapWindow(m_window);
 }
 
+void Screen::ScreenShot(const char * filename) const
+{
+       Debug("Attempting to save BMP to file %s", filename);
+
+       int w = ViewportWidth();
+       int h = ViewportHeight();
+       unsigned char * pixels = new unsigned char[w*h*4];
+       if (pixels == NULL)
+               Fatal("Failed to allocate %d x %d x 4 = %d pixel array", w, h, w*h*4);
+
+       glReadPixels(0,0,w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+
+       SDL_Surface * surf = SDL_CreateRGBSurfaceFrom(pixels, w, h, 8*4, w*4, 0,0,0,0);
+       if (surf == NULL)
+               Fatal("Failed to create SDL_Surface from pixel data - %s", SDL_GetError());
+
+       GLenum texture_format = (surf->format->Rmask == 0x000000FF) ? GL_RGBA : GL_BGRA;
+       Debug("SDL_Surface %d BytesPerPixel, format %d (RGB = %d, BGR = %d, RGBA = %d, BGRA = %d)", surf->format->BytesPerPixel, texture_format, GL_RGB, GL_BGR, GL_RGBA, GL_BGRA);
+
+       if (SDL_SaveBMP(surf, filename) != 0)
+               Fatal("SDL_SaveBMP failed - %s", SDL_GetError());
+       
+       SDL_FreeSurface(surf);
+       delete [] pixels;
+       Debug("Succeeded!");
+}
+
+/**
+ * Render a BMP
+ * NOT PART OF THE DOCUMENT FORMAT
+ */
+void Screen::RenderBMP(const char * filename) const
+{
+       SDL_Surface * bmp = SDL_LoadBMP(filename);
+       if (bmp == NULL)
+               Fatal("Failed to load BMP from %s - %s", filename, SDL_GetError());
+
+       int w = bmp->w;
+       int h = bmp->h;
+
+       GLenum texture_format; 
+       switch (bmp->format->BytesPerPixel)
+       {
+               case 4: //contains alpha
+                       texture_format = (bmp->format->Rmask == 0x000000FF) ? GL_RGBA : GL_BGRA;
+                       break;
+               case 3: //does not contain alpha
+                       texture_format = (bmp->format->Rmask == 0x000000FF) ? GL_RGB : GL_BGR;  
+                       break;
+               default:
+                       Fatal("Could not understand SDL_Surface format (%d colours)", bmp->format->BytesPerPixel);
+                       break;  
+       }
+
+       //Debug("SDL_Surface %d BytesPerPixel, format %d (RGB = %d, BGR = %d, RGBA = %d, BGRA = %d)", bmp->format->BytesPerPixel, texture_format, GL_RGB, GL_BGR, GL_RGBA, GL_BGRA);
+
+
+       GLuint texID;
+       glEnable(GL_TEXTURE_2D);
+       glGenTextures(1, &texID);
+       glBindTexture(GL_TEXTURE_2D, texID);
+
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+       glTexImage2D(GL_TEXTURE_2D, 0, bmp->format->BytesPerPixel, w, h, 0, texture_format, GL_UNSIGNED_BYTE, bmp->pixels);
+
+       glMatrixMode(GL_PROJECTION);
+       glLoadIdentity();
+       glOrtho(0.0, 1.0, 1.0, 0.0, -1.f, 1.f);
+       glMatrixMode(GL_MODELVIEW);
+       glLoadIdentity();
+
+       glBegin(GL_QUADS);
+               glTexCoord2i(0,0); glVertex2f(0,0);
+               glTexCoord2i(1,0); glVertex2f(1,0);
+               glTexCoord2i(1,1); glVertex2f(1,1);
+               glTexCoord2i(0,1); glVertex2f(0,1);
+       glEnd();
+
+       glDisable(GL_TEXTURE_2D);
+       SDL_FreeSurface(bmp);   
+}
index 4d92cb3..e641826 100644 (file)
@@ -24,8 +24,8 @@ namespace IPDF
                void Present();
 
                // Get the current width/height of the window's viewport.
-               int ViewportWidth() { return m_viewport_width; }
-               int ViewportHeight() { return m_viewport_height; }
+               int ViewportWidth() const { return m_viewport_width; }
+               int ViewportHeight() const { return m_viewport_height; }
                
                // Handle mouse input.
                typedef std::function<void(int x, int y, int button, int wheel)> MouseHandler;
@@ -43,6 +43,9 @@ namespace IPDF
                        CursorHand
                };
                void SetMouseCursor(MouseCursors cursor);
+
+               void ScreenShot(const char * filename) const;
+               void RenderBMP(const char * filename) const;
        private:
                void ResizeViewport(int width, int height);
                
diff --git a/src/tests/repr.cpp b/src/tests/repr.cpp
new file mode 100644 (file)
index 0000000..26ed668
--- /dev/null
@@ -0,0 +1,33 @@
+#include "main.h"
+
+#include <bitset>
+
+using namespace std;
+
+
+
+int main(int argc, char ** argv)
+{
+       char buffer[BUFSIZ];
+       double input;
+       printf("Enter a double: ");
+       fgets(buffer, BUFSIZ, stdin);
+       sscanf(buffer, "%lf", &input);
+
+
+       float f = (float)(input);
+
+       unsigned long long i;
+       memcpy(&i, &f, 4);
+       bitset<32> b32(i);
+       memcpy(&i, &input, 8);
+       bitset<64> b64(i);
+
+       printf("\nAs float: %s\n", b32.to_string().c_str());
+       printf("\nAs double: %s\n", b64.to_string().c_str());
+       #ifdef REAL_BITSET
+               Real r(input);
+               printf("\nAs real: %s\n", r.repr.to_string().c_str());
+       #endif //REAL_BITSET
+       
+}
diff --git a/src/tests/vfpufloat.cpp b/src/tests/vfpufloat.cpp
new file mode 100644 (file)
index 0000000..dae457b
--- /dev/null
@@ -0,0 +1,18 @@
+#include "main.h"
+
+#include "vfpu.h"
+using namespace std;
+
+
+int main(int argc, char ** argv)
+{
+       if (argc > 1)
+               VFPU::Start(argv[1]);
+       else
+               VFPU::Start();
+       float result = VFPU::Exec(25,10, VFPU::SUB);
+       Debug("%f\n", result);
+       VFPU::Halt();
+
+       return 0;
+}
diff --git a/src/vfpu b/src/vfpu
new file mode 120000 (symlink)
index 0000000..2fcb913
--- /dev/null
+++ b/src/vfpu
@@ -0,0 +1 @@
+../contrib/vfpu
\ No newline at end of file
diff --git a/src/vfpu.cpp b/src/vfpu.cpp
new file mode 100644 (file)
index 0000000..8783ca1
--- /dev/null
@@ -0,0 +1,148 @@
+#include "vfpu.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <stdbool.h>
+#include <signal.h>
+#include <string.h>
+
+#include <sstream>
+#include <iomanip>
+
+#include "common.h"
+
+using namespace std;
+
+namespace VFPU
+{
+
+static const char g_fpu[] = "vfpu";
+
+static bool g_running = false;
+static int g_fpu_socket[2] = {-1,-1};
+static pid_t g_fpu_pid = -1;
+
+/**
+ * Starts the VFPU
+ * @returns 0 on success, errno of the failing function on failure
+ */
+int Start(const char * vcd_output)
+{
+       assert(!g_running);
+       // create unix socket pair
+       
+       if (socketpair(AF_UNIX, SOCK_STREAM, 0, g_fpu_socket) != 0)
+               return errno;
+       
+
+       g_fpu_pid = fork();
+       if (g_fpu_pid < 0) // error check
+               return errno;
+
+
+       // Child branch
+       if (g_fpu_pid == 0)
+       {
+               
+               // Remap stdio to the socket
+               dup2(g_fpu_socket[0],fileno(stdin));
+               dup2(g_fpu_socket[0],fileno(stdout));
+               
+               // Unbuffer things; buffers are a pain
+               setbuf(stdin, NULL); setbuf(stdout, NULL); setbuf(stderr, NULL);
+
+               Debug("Child about to suppress stderr and exec vfpu");
+               dup2(open("/dev/null", O_APPEND), fileno(stderr)); //LALALA I AM NOT LISTENING TO YOUR STUPID ERRORS GHDL
+               if (vcd_output != NULL)
+               {
+                       string s("--vcd=");
+                       s += vcd_output;
+                       execl(g_fpu, g_fpu, s.c_str(), NULL);
+               }
+               else    
+               {
+                       execl(g_fpu, g_fpu,NULL);
+               }
+               int err = errno; // Because errno will be set again by the next system call
+               Fatal("Uh oh! %s\n", strerror(err)); // We will never see this if something goes wrong... oh dear
+               exit(err); // Child exits here.
+       }
+
+       // Parent branch
+       usleep(100);
+       g_running = true; // We are ready!
+       return 0;
+}
+
+/**
+ * Halt the VFPU
+ */
+int Halt()
+{
+       assert(g_running);
+       // Tell the child to stop running the VHDL simulation
+       if (close(g_fpu_socket[1]) != 0)
+               return errno;
+       usleep(1000);
+       if (kill(g_fpu_pid, SIGKILL) != 0)
+               return errno;
+       g_running = false;
+       return 0;
+}
+
+float Exec(float opa, float opb, Opcode op, Rmode rmode)
+{
+       unsigned a; memcpy(&a, &opa, sizeof(float));
+       unsigned b; memcpy(&b, &opb, sizeof(float));
+       
+       unsigned r = (unsigned)(Exec(Register(a), Register(b), op, rmode).to_ulong());
+       float result; memcpy(&result, &r, sizeof(float));
+       return result;
+}
+
+/**
+ * Tell the VFPU to execute an instruction, wait for it to finish, return the result
+ * TODO: Make this not mix C++ and C so badly?
+ * TODO: It will still only work for magic 32 bit FPU
+ */
+Register Exec(const Register & a, const Register &  b, Opcode op, Rmode rmode)
+{
+       assert(g_running);
+               
+       stringstream s;
+       s << hex << setw(8) << setfill('0') << a.to_ullong() << "\n" << b.to_ullong() << "\n" << setw(1) << op <<"\n" << setw(1) << rmode << "\n";
+       string str(s.str());
+       //Debug("Writing: %s", str.c_str());
+
+       // So we used C++ streams to make our C string...
+       assert(write(g_fpu_socket[1], str.c_str(), str.size()) == (int)str.size());
+
+       char buffer[BUFSIZ]; 
+       int len = read(g_fpu_socket[1], buffer, sizeof(buffer));
+       //assert(len == 9);
+       buffer[--len] = '\0'; // Get rid of newline
+       //Debug("Read: %s", buffer);
+       
+       Register result(0);
+       for (int i = 0; i < len/2; ++i)
+       {
+               unsigned byte; // It is ONE byte (2 nibbles == 2 hex digits)
+               sscanf(buffer+2*i, "%02x", &byte);
+               result |= (byte << 8*(len/2-i-1));
+       }
+       
+       stringstream s2;
+       s2 << hex << result.to_ullong();
+       //Debug("Result is: %s", s2.str().c_str());
+       return result;
+}
+
+}
+
+
diff --git a/src/vfpu.h b/src/vfpu.h
new file mode 100644 (file)
index 0000000..12ac9bc
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef _VFPU_H
+#define _VFPU_H
+
+/**
+ * Implements a terrible and hacky interface to use a virtual FPU to do floating point operations
+ */
+
+#include <bitset>
+
+namespace VFPU
+{
+       extern int Start(const char * vcd_output = NULL); // Starts the VFPU
+       extern int Halt(); // Halts the VFPU
+
+/**
+               -- 000 = add, 
+               -- 001 = substract, 
+               -- 010 = multiply, 
+               -- 011 = divide,
+               -- 100 = square root
+               -- 101 = unused
+               -- 110 = unused
+               -- 111 = unused
+ */
+       typedef enum {ADD=0x000, SUB=0x001, MULT=0x010, DIV=0x011, SQRT=0x100} Opcode;
+       typedef enum {EVEN=0x00, ZERO=0x01, UP=0x10, DOWN=0x11} Rmode;
+       typedef std::bitset<32> Register;
+       
+       extern Register Exec(const Register & a, const Register & b, Opcode op, Rmode rmode = EVEN); // operate with registers
+       extern float Exec(float a, float b, Opcode op, Rmode rmode = EVEN); //converts floats into registers and back
+}
+
+#endif //_VFPU_H
+
+
index 969bbb3..3c6e2f5 100644 (file)
@@ -35,6 +35,31 @@ void View::ScaleAroundPoint(Real x, Real y, Real scaleAmt)
        m_bounds.h *= scaleAmt;
 }
 
+void View::DrawGrid()
+{
+       // Draw some grid lines at fixed pixel positions
+       glMatrixMode(GL_PROJECTION);
+       glLoadIdentity();
+       glOrtho(0.0, 1.0, 1.0, 0.0, -1.f, 1.f);
+       glMatrixMode(GL_MODELVIEW);
+       glLoadIdentity();
+
+       glColor4f(0.9,0.9,0.9,0.1);
+       const float num_lines = 50.0;
+       for (float i = 0; i < num_lines; ++i)
+       {
+               glBegin(GL_LINES);
+               glVertex2f(i*(1.0/num_lines), 0.0);
+               glVertex2f(i*(1.0/num_lines), 1.0);
+               glEnd();
+               glBegin(GL_LINES);
+               glVertex2f(0.0,i*(1.0/num_lines));
+               glVertex2f(1.0,i*(1.0/num_lines));
+               glEnd();
+       
+       }
+}
+
 void View::Render()
 {
        static bool debug_output_done = false;
@@ -47,13 +72,15 @@ void View::Render()
        glClearColor(1.f,1.f,1.f,1.f);
        glClear(GL_COLOR_BUFFER_BIT);
 
+       //DrawGrid(); // Draw the gridlines
+
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(Float(m_bounds.x), Float(m_bounds.x)+Float(m_bounds.w), Float(m_bounds.y) + Float(m_bounds.h), Float(m_bounds.y), -1.f, 1.f);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
 
-       glColor4f(0.f,0.f,0.f,1.f);
+       glColor4f(m_colour.r, m_colour.g, m_colour.b, m_colour.a);
        glBegin(GL_QUADS);
        for (unsigned id = 0; id < m_document.ObjectCount(); ++id)
        {
@@ -67,6 +94,7 @@ void View::Render()
        }
        glEnd();
 
+       
        for (unsigned id = 0; id < m_document.ObjectCount(); ++id)
        {
                if (m_document.m_objects.types[id] != RECT_OUTLINE)
index 6b63799..24ae6d9 100644 (file)
@@ -9,7 +9,8 @@ namespace IPDF
        class View
        {
                public:
-                       View(Document & document) : m_document(document), m_bounds(0,0,1,1) {}
+                       View(Document & document, const Rect & bounds = Rect(0,0,1,1), const Colour & colour = Colour(0.f,0.f,0.f,1.f)) 
+                               : m_document(document), m_bounds(bounds), m_colour(colour) {}
                        virtual ~View() {}
 
                        void Render();
@@ -18,8 +19,10 @@ namespace IPDF
                        void ScaleAroundPoint(Real x, Real y, Real scaleAmt);
                
                private:
+                       void DrawGrid();
                        Document & m_document;
                        Rect m_bounds;
+                       Colour m_colour;
        };
 }
 

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