60 static string svg_css = \
62 "\t\t@import url(\"https://www.ncbi.nlm.nih.gov/projects/sviewer/css/svg_fonts.css\");\n" \
67 m_SVG.reset(
new svg::SVG(svg::ViewBox(0, 0, viewport.
Width(), viewport.
Height()), svg::Style(svg_css),
NStr::XmlEncode(
"Generated by NCBI Genome Workbench http://www.ncbi.nlm.nih.gov/tools/gbench/")));
85 GLdouble bottom, GLdouble top,
86 GLdouble nearVal, GLdouble farVal)
96 LOG_POST(
"BeginText() called without first calling CSVGRenderer::EndText()");
108 LOG_POST(
"BeginText() called without first calling CSVGRenderer::EndText()");
121 LOG_POST(
"EndText() called without first calling CSVGRenderer::BeginText()");
135 LOG_POST(
Error <<
"Unable to write text - must call BeginText() first");
156 LOG_POST(
Error <<
"Unable to write text - must call BeginText() first");
162 origin.Set((
float)(x + width / 2.0), (
float)y);
165 origin.Set((
float)(x + width), (
float)y);
179 m_SVG->WriteToStream(ostrm);
235 vector<CVect2<float> > vertices;
236 vector<CRgbaColor>
colors;
241 if (vertices.size() == 0)
244 GLushort pattern = 0xffff;
247 svg::Stroke::ELineCapStyle lcap{ svg::Stroke::eDefaultCap };
248 svg::Stroke::ELineJoinStyle ljoin{ svg::Stroke::eDefaultJoin };
258 for (
size_t i = 0;
i < vertices.size();
i += 2) {
259 if (
i + 1 >= vertices.size())
262 *
m_SVG << svg::Line(vertices[
i], vertices[
i + 1], svg::Stroke(has_color ?
colors[
i] : default_color, width, ljoin, (svg::Stroke::ELineCapStyle)lcap, pattern, factor),
m_ClippingId);
266 for (
size_t i = 1;
i < vertices.size();
i++) {
267 *
m_SVG << svg::Line(vertices[
i - 1], vertices[
i], svg::Stroke(has_color ?
colors[
i - 1] : default_color, width, ljoin, (svg::Stroke::ELineCapStyle)lcap, pattern, factor),
m_ClippingId);
271 for (
size_t i = 1;
i < vertices.size();
i++) {
272 *
m_SVG << svg::Line(vertices[
i - 1], vertices[
i], svg::Stroke(has_color ?
colors[
i - 1] : default_color, width, ljoin, (svg::Stroke::ELineCapStyle)lcap, pattern, factor),
m_ClippingId);
274 *
m_SVG << svg::Line(vertices[0], vertices[vertices.size() - 1], svg::Stroke(has_color ?
colors[0] : default_color, width, ljoin, (svg::Stroke::ELineCapStyle)lcap, pattern, factor),
m_ClippingId);
281 vector<CVect2<float> > vertices;
282 vector<CRgbaColor>
colors;
287 if (vertices.size() == 0)
302 for (
size_t i = 0;
i < vertices.size(); ++
i) {
303 *
m_SVG << svg::Circle(vertices[
i], width, svg::Fill(has_color ?
colors[
i] : default_color), svg::Stroke(),
m_ClippingId);
311 vector<CVect2<float> > vertices;
312 vector<CRgbaColor>
colors;
317 if (vertices.size() == 0)
320 vector<CRgbaColor> gradient;
323 if (has_color && !flat_shading) {
331 GLushort pattern = 0xffff;
334 svg::Stroke::ELineCapStyle lcap{ svg::Stroke::eDefaultCap };
335 svg::Stroke::ELineJoinStyle ljoin{ svg::Stroke::eDefaultJoin };
351 if (!fill_pattern.empty()) {
352 fill = svg::Fill((
string const&)fill_pattern);
354 else if (gradient.size() > 1) {
358 fill = svg::Fill(has_color ?
colors[0] : default_color);
364 bool uniform_color{
true };
365 for (
size_t i = 0;
i < vertices.size();
i += 3) {
366 if (
i + 2 >= vertices.size())
369 if (has_color && flat_shading) {
372 uniform_color =
false;
377 tp.
AddTri(vertices[
i], vertices[
i + 1], vertices[
i + 2]);
382 if (perimeter.size() > 2 && filled) {
386 if (uniform_color && !gradient.empty()) {
387 fill = svg::Fill(has_color ?
colors[0] : default_color);
390 for (
size_t i = 0;
i < vertices.size();
i += 3) {
391 if (
i + 2 >= vertices.size())
394 vector<CVect2<float> > triangle;
395 triangle.push_back(vertices[
i]);
396 triangle.push_back(vertices[
i + 1]);
397 triangle.push_back(vertices[
i + 2]);
406 *
m_SVG << svg::Polygon(triangle, svg::Fill(), svg::Stroke(has_color ?
colors[0] : default_color, width, ljoin, (svg::Stroke::ELineCapStyle)lcap, pattern, factor),
m_ClippingId);
411 else if (node.
GetDrawMode() == GL_TRIANGLE_STRIP) {
412 bool uniform_color{
true };
414 for (
size_t i = 2;
i < vertices.size();
i++) {
415 tp.
AddTri(vertices[
i], vertices[
i - 1], vertices[
i - 2]);
417 if (has_color && flat_shading) {
420 uniform_color =
false;
429 if (perimeter.size() > 2 && filled) {
433 for (
size_t i = 2;
i < vertices.size();
i++) {
434 vector<CVect2<float> > triangle;
435 triangle.push_back(vertices[
i]);
436 triangle.push_back(vertices[
i - 1]);
437 triangle.push_back(vertices[
i - 2]);
446 *
m_SVG << svg::Polygon(triangle, svg::Fill(), svg::Stroke(has_color ?
colors[0] : default_color, width, ljoin, (svg::Stroke::ELineCapStyle)lcap, pattern, factor),
m_ClippingId);
454 vector<CVect2<float> > perimeter;
455 for (
size_t i = 1;
i < vertices.size();
i++) {
456 perimeter.push_back(vertices[
i]);
465 for (
size_t i = 2;
i < vertices.size();
i++) {
469 *
m_SVG << svg::Line(v1p, v2p, svg::Stroke(has_color ?
colors[0] : default_color, width, ljoin, (svg::Stroke::ELineCapStyle)lcap, pattern, factor),
m_ClippingId);
470 *
m_SVG << svg::Line(v2p, v3p, svg::Stroke(has_color ?
colors[0] : default_color, width, ljoin, (svg::Stroke::ELineCapStyle)lcap, pattern, factor),
m_ClippingId);
471 *
m_SVG << svg::Line(v3p, v1p, svg::Stroke(has_color ?
colors[0] : default_color, width, ljoin, (svg::Stroke::ELineCapStyle)lcap, pattern, factor),
m_ClippingId);
480 vector<CVect2<float> > vertices;
481 vector<CRgbaColor>
colors;
486 if (vertices.size() == 0)
496 GLushort pattern = 0xffff;
499 svg::Stroke::ELineCapStyle lcap{ svg::Stroke::eDefaultCap };
500 svg::Stroke::ELineJoinStyle ljoin{ svg::Stroke::eDefaultJoin };
509 svg::Fill fill(has_color ?
colors[0] : default_color);
511 for (
size_t i = 3;
i < vertices.size();
i += 4) {
513 vector<CVect2<float> > quad;
514 quad.push_back(vertices[
i - 3]);
515 quad.push_back(vertices[
i - 2]);
516 quad.push_back(vertices[
i - 1]);
517 quad.push_back(vertices[
i]);
520 *
m_SVG << svg::Polygon(quad, fill, svg::Stroke(has_color ?
colors[0] : default_color, width, ljoin, (svg::Stroke::ELineCapStyle)lcap, pattern, factor),
m_ClippingId);
523 *
m_SVG << svg::Polygon(quad, svg::Fill(), svg::Stroke(has_color ?
colors[0] : default_color, width, ljoin, (svg::Stroke::ELineCapStyle)lcap, pattern, factor),
m_ClippingId);
535 GLdouble model_view_matrix[16];
536 GLdouble projection_matrix[16];
547 GLdouble model_view_matrix[16];
548 GLdouble projection_matrix[16];
552 for (
auto& vertex : vertices) {
556 gluProjectX(vertex.X(), vertex.Y(), 0.0, model_view_matrix, projection_matrix,
m_Viewport, &px, &py, &dummyz);
557 vertex.Set(
float(px),
float(
m_Height - py - 1));
566 md5.Update((
const char*)stipple,
sizeof(GLubyte) * 128);
569 stipple_hash =
md5.GetHexSum();
574 unsigned char fill_color[4];
579 unsigned char empty_color[4];
584 CImage stipple_pttn(32, 32, 4);
586 for (
unsigned i = 0;
i < 128; ++
i) {
588 for (
int j = 7; j >= 0; j--) {
591 size_t x = 31 - (k / 32);
593 if (stipple[
i] & (1 << j)) {
594 memcpy(stipple_pttn(x, y), fill_color,
sizeof(fill_color));
597 memcpy(stipple_pttn(x, y), empty_color,
sizeof(empty_color));
602 std::stringstream ss;
604 string pattern_id(
"polygon-stipple");
615 string gradient_hash;
619 string color_str =
color.ToString();
620 md5.Update(color_str.c_str(), color_str.length());
622 gradient_hash =
md5.GetHexSum();
627 string gradient_id(
"gradient");
631 *
m_SVG << svg::LinearGradient(gradient_id,
colors);
641 md5.Update((
const char*)&x,
sizeof(x));
642 md5.Update((
const char*)&y,
sizeof(y));
643 md5.Update((
const char*)&width,
sizeof(width));
644 md5.Update((
const char*)&height,
sizeof(height));
645 rect_hash =
md5.GetHexSum();
650 string clipping_id(
"clipping-rect");
654 *
m_SVG << svg::ClipRect(clipping_id, x,
m_Height - y - 1, width, height);
661 vector<size_t> sorted_indices(vertices.size());
662 std::iota(std::begin(sorted_indices), std::end(sorted_indices), 0);
663 sort(sorted_indices.begin(), sorted_indices.end(),
664 [&vertices](
const size_t&
a,
const size_t&
b) ->
bool
666 return vertices[a].Y() < vertices[b].Y();
669 auto getColorAtY = [&vertices, &sorted_indices, &
colors](
float y)
672 size_t r{ sorted_indices.size() - 1 };
674 size_t m = l + (
r - l) / 2;
677 if (vertices[sorted_indices[m]].Y() == y) {
678 return colors[sorted_indices[m]];
684 if (vertices[sorted_indices[m]].Y() < y)
692 gradient.push_back(
colors[sorted_indices[0]]);
693 if (
colors[sorted_indices[0]].ToHtmlString() ==
colors[sorted_indices[sorted_indices.size() - 1]].ToHtmlString()) {
694 float step = (vertices[sorted_indices[sorted_indices.size() - 1]].Y() - vertices[sorted_indices[0]].Y()) / 2;
695 auto color = getColorAtY(vertices[sorted_indices[0]].Y() + step);
696 gradient.push_back(
color);
698 gradient.push_back(
colors[sorted_indices[sorted_indices.size() - 1]]);
CGlVboNode A rendering node that holds a vertex buffer object.
static bool WriteImage(const CImage &image, CNcbiOstream &ostr, EType type, ECompress compress=eCompress_Default)
CGlVboNode m_RenderNode
vertex buffer node for rendering all Begin()/End() renders
CRgbaColor m_TextColor
color and alpha for text only (other GL options do not apply to text)
const CGlTextureFont * m_CurrentFont
text parameters
GLint m_Viewport[4]
current projection set by Viewport()
virtual void Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
virtual void Ortho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearVal, GLdouble farVal)
virtual CMatrix4< float > GetModelViewMatrix() const
virtual void LoadMatrixf(const GLfloat *m)
virtual void PushMatrix()
virtual void MatrixMode(GLenum mode)
virtual CMatrix4< float > GetProjectionMatrix() const
class CRgbaColor provides a simple abstraction for managing colors.
Simple helper class to take a bunch of triangles and extract from that set, if possible,...
size_t AddTri(CVect2< float > &v1p, CVect2< float > &v2p, CVect2< float > &v3p)
std::vector< CVect2< float > > GetPerimiter() const
returns empty vec if no perimeter can be found.
const_iterator end() const
const_iterator find(const key_type &key) const
static const Colors colors
#define LOG_POST(message)
This macro is deprecated and it's strongly recomended to move in all projects (except tests) to macro...
void Error(CExceptionArgs_Base &args)
const T * GetData() const
GLenum GetShadeModel() const
int gluProjectX(GLdouble objx, GLdouble objy, GLdouble objz, const GLdouble modelMatrix[16], const GLdouble projMatrix[16], const GLint viewport[4], GLdouble *winx, GLdouble *winy, GLdouble *winz)
GLenum GetPolygonMode() const
void Get2DVertexBuffer(std::vector< CVect2< float > > &verts) const
bool GetDefaultColor(CRgbaColor &default_color, bool is_greyscale) const
Return default color from node in default_color.
bool LineWidthSet() const
bool GetColors(std::vector< CRgbaColor > &colors, bool is_greyscale) const
GLfloat GetLineWidth() const
CMatrix4< float > GetTransformedPosition(size_t idx)
return the position with rotation and pixel offset baked in
vector< CMatrix4< float > > & GetPositions()
return the current set of transformations for thisnode
GLfloat GetPointSize() const
bool LineCapStyleSet() const
bool IsEnabled(GLenum glstate) const
Return true if option is in m_Enabled list for this state.
void GetLineStipple(GLint &factor, GLushort &pattern) const
void BeginText() const
WriteText interface The WriteText functions produce the same results as TextOut but they are more eff...
bool PointSizeSet() const
bool LineJoinStyleSet() const
ELineCapStyle GetLineCapStyle() const
CRgbaColor GetColor() const
const GLubyte * GetPolygonStipple() const
void ProjectVertex(CVect2< float > &vertex) const
void EndText() const
Pops matrices and attributes after writing text.
virtual TModelUnit TextHeight(void) const
ELineJoinStyle GetLineJoinStyle() const
bool PolygonStippleSet() const
GLenum GetDrawMode() const
Return the current drawing mode (e.g.
string Truncate(const char *text, TModelUnit w, ETruncate trunc=eTruncate_Ellipsis) const
Truncate text to the secified width.
bool LineStippleSet() const
map< string, string > m_LinearGradients
void x_ProjectVertex(CVect2< float > &vertex)
virtual void Initialize(const TVPRect &viewport)
void x_ProjectVertices(vector< CVect2< float >> &vertices)
virtual void x_RenderBuffer(CGlVboNode *node)
string x_PolygonStippleToPattern(const GLubyte *stipple, const CRgbaColor &fill_rgba_color)
void x_PrintPointBuffer(CGlVboNode &node)
string x_LinearGradient(std::vector< CRgbaColor > const &colors)
virtual void WriteText(TModelUnit x, TModelUnit y, const char *text, TModelUnit rotate_degrees=0.0)
Write text at specified model coords.
std::stack< std::string > m_ClippingStack
virtual void EndClippingRect()
void x_PrintLineBuffer(CGlVboNode &node)
map< string, string > m_ClippingRects
map< string, string > m_PolygonStipplePatterns
virtual void Ortho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearVal, GLdouble farVal)
virtual void EndText()
Pops matrices and attributes after writing text.
virtual void BeginText(const CGlTextureFont *font, const CRgbaColor &color)
Set OpenGL state needed for writing text (call before DrawText)
void x_GetGradientColors(vector< CVect2< float >> const &vertices, vector< CRgbaColor > const &colors, vector< CRgbaColor > &gradient)
void Write(CNcbiOstream &ostrm)
string x_ClippingRect(GLint x, GLint y, GLsizei width, GLsizei height)
void x_PrintQuadBuffer(CGlVboNode &node)
virtual void Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
virtual void BeginClippingRect(GLint x, GLint y, GLsizei width, GLsizei height)
void x_PrintTriBuffer(CGlVboNode &node)
unique_ptr< svg::SVG > m_SVG
void x_GetLineStyle(CGlVboNode &node, GLushort &pattern, GLint &factor, double &width, svg::Stroke::ELineCapStyle &lcap, svg::Stroke::ELineJoinStyle &ljoin)
unsigned char GetRedUC(void) const
Get specific channels in unsigned char values.
string ToString(bool printAlpha=true, bool uchars=true) const
Return a string representation of the current color.
unsigned char GetGreenUC(void) const
unsigned char GetAlphaUC(void) const
static CRgbaColor Interpolate(const CRgbaColor &color1, const CRgbaColor &color2, float alpha)
Interpolate two colors.
unsigned char GetBlueUC(void) const
static string base64Encode(const string &str)
#define END_NCBI_SCOPE
End previously defined NCBI scope.
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
IO_PREFIX::ostream CNcbiOstream
Portable alias for ostream.
static string XmlEncode(const CTempString str, TXmlEncode flags=eXmlEnc_Contents)
Encode a string for XML.
static enable_if< is_arithmetic< TNumeric >::value||is_convertible< TNumeric, Int8 >::value, string >::type NumericToString(TNumeric value, TNumToStringFlags flags=0, int base=10)
Convert numeric value to string.
CMD5 - class for computing Message Digest version 5 checksums.
static void text(MDB_val *v)
constexpr auto sort(_Init &&init)
const struct ncbi::grid::netcache::search::fields::SIZE size
double r(size_t dimension_, const Int4 *score_, const double *prob_, double theta_)
static const GLdouble origin[]