#include "qui/GlSequence.h"
#include <iostream>
+#include <cassert>
+#include <math.h>
+#include <stdexcept>
using namespace std;
GlSequence::GlSequence(const Sequence &s)
seq_y(0.0),
seq_z(1.0),
seq_width(s.size()),
- seq_height(gl_track_height)
+ seq_height(gl_track_height)
{
+ assert (seq.size() == seq_width);
}
GlSequence::GlSequence(const GlSequence &s)
seq_width(s.seq_width),
seq_height(s.seq_height)
{
+ assert (seq.size() == seq_width);
}
GlSequence &GlSequence::operator=(const GlSequence & s)
return *this;
}
-const Sequence &GlSequence::sequence() const
+const Sequence& GlSequence::sequence() const
{
return seq;
}
}
-void GlSequence::draw() const
+void GlSequence::draw(GLfloat left, GLfloat right) const
{
glLineWidth(seq_height);
glColor3f(0.0, 0.0, 0.0);
glVertex3f(annot_itor->end , seq_y, annotation_z);
glEnd();
}
+ draw_sequence(left, right);
+}
+
+const int PT = 1;
+const int STROKE = 2;
+const int END =3;
+
+typedef struct charpoint {
+ GLfloat x, y;
+ int type;
+} CP;
+
+CP Adata[] = {
+ {0, 0, PT}, {0, 9, PT}, {1, 10, PT}, {4, 10, PT},
+ {5, 9, PT}, {5, 0, STROKE}, {0, 5, PT}, {5, 5, END}
+};
+
+CP Tdata[] = {
+ {2.5, 0, PT}, {2.5,10, STROKE}, {0, 10, PT}, {5,10, END}
+};
+
+CP Gdata[] = {
+ {5, 9, PT}, {4, 10, PT}, {1, 10, PT}, {0, 9, PT}, {0, 1, PT},
+ {1, 0, PT}, {5, 0, PT}, {5, 4, PT}, {3.5, 4, END}
+};
+
+CP Cdata[] = {
+ {5, 8, PT}, {3, 10, PT}, {2, 10, PT}, {0, 8, PT}, {0, 2, PT},
+ {2, 0, PT}, {3, 0, PT}, {5, 2, END}
+};
+
+CP Xdata[] = {{ 0, 10, PT}, {5,0,STROKE},{0,0,PT},{5,10,END}};
+CP Ndata[] = {{ 0, 0, PT}, {0, 10, PT}, {5, 0, PT}, {5, 10, END}};
+
+static void drawLetter(CP *l)
+{
+ glBegin(GL_LINE_STRIP);
+ while(1) {
+ switch (l->type) {
+ case PT:
+ glVertex2fv(&l->x);
+ break;
+ case STROKE:
+ glVertex2fv(&l->x);
+ glEnd();
+ glBegin(GL_LINE_STRIP);
+ break;
+ case END:
+ glVertex2fv(&l->x);
+ glEnd();
+ return;
+ break;
+ default:
+ throw runtime_error("data structure failure");
+ }
+ l++;
+ }
+}
+
+void GlSequence::draw_sequence(GLfloat left, GLfloat right) const
+{
+ int viewport[4];
+ glGetIntegerv(GL_VIEWPORT, viewport);
+ int port_width = viewport[3]; // grab the viewport width
+ GLfloat world_width = right - left;
+ int left_base = (left > 0) ? (int)ceil(left) : 0;
+ int right_base = (int)floor(right);
+ int render_count = (right_base < seq.size()) ? right_base : seq.size();
+ render_count -= left_base;
+
+ glLineWidth(0.01);
+ GLfloat char_width = 1.1;
+ GLfloat pixels_needed = char_width * world_width;
+
+ cout << "seq width needed " << pixels_needed
+ << " port width " << port_width
+ << " count " << render_count
+ << " left " << left_base
+ << " right " << right_base
+ << " size " << seq.size() << endl;
+ // if the number of pixels taken up by rendering the characters
+ // that'd show up in the current ortho width is less than the window
+ // width we can actually draw something
+ if (pixels_needed < port_width and render_count > 0) {
+ cout << "rendering: ";
+ string bases = seq.subseq(left_base, render_count);
+ glColor3f(0.1, 0.1, 0.1);
+ for (string::size_type basepair = 0; basepair != bases.size(); ++basepair)
+ {
+ glPushMatrix();
+ glTranslatef( left_base + basepair, seq_y+20, 1.0 );
+ glScalef(0.1, 1.0, 1.0);
+ switch (bases[basepair]) {
+ case 'A': case 'a':
+ drawLetter(Adata);
+ break;
+ case 'T': case 't':
+ drawLetter(Tdata);
+ break;
+ case 'G': case 'g':
+ drawLetter(Gdata);
+ break;
+ case 'C': case 'c':
+ drawLetter(Cdata);
+ break;
+ case 'N': case 'n':
+ drawLetter(Ndata);
+ break;
+ default:
+ drawLetter(Xdata);
+ break;
+ }
+ cout << bases[basepair];
+ glPopMatrix();
+ }
+ cout << endl;
+ }
}