Add support to analyse driveresponse for drawing its own graphs via AGG.

This commit is contained in:
David Given
2021-01-13 01:46:48 +01:00
parent 03fc1419de
commit 57e598156c
5 changed files with 238 additions and 268 deletions

View File

@@ -22,9 +22,6 @@
#ifndef AGG2D_INCLUDED
#define AGG2D_INCLUDED
// With this define uncommented you can use FreeType font engine
//#define AGG2D_USE_FREETYPE
// With this define uncommented you can use floating-point pixel format
//#define AGG2D_USE_FLOAT_FORMAT
@@ -50,18 +47,9 @@
#include "agg_rounded_rect.h"
#include "agg_font_cache_manager.h"
// Font drawing is deactivated here because the implementation is platform-dependent and incomplete.
//#define AGG_USE_FONTS
#ifdef AGG_USE_FONTS
# ifdef AGG2D_USE_FREETYPE
# include "agg_font_freetype.h"
# else
# include "agg_font_win32_tt.h"
# endif
#endif
#include "agg_pixfmt_rgba.h"
#include "agg_image_accessors.h"
#include <string>
class Agg2D
{
@@ -95,16 +83,6 @@ class Agg2D
typedef agg::span_gradient<ColorType, agg::span_interpolator_linear<>, agg::gradient_x, GradientArray> LinearGradientSpan;
typedef agg::span_gradient<ColorType, agg::span_interpolator_linear<>, agg::gradient_circle, GradientArray> RadialGradientSpan;
#ifdef AGG_USE_FONTS
# ifdef AGG2D_USE_FREETYPE
typedef agg::font_engine_freetype_int32 FontEngine;
# else
typedef agg::font_engine_win32_tt_int32 FontEngine;
# endif
typedef agg::font_cache_manager<FontEngine> FontCacheManager;
typedef FontCacheManager::gray8_adaptor_type FontRasterizer;
typedef FontCacheManager::gray8_scanline_type FontScanline;
#endif
typedef agg::conv_curve<agg::path_storage> ConvCurve;
typedef agg::conv_stroke<ConvCurve> ConvStroke;
typedef agg::conv_transform<ConvCurve> PathTransform;
@@ -147,8 +125,6 @@ public:
AlignLeft,
AlignRight,
AlignCenter,
AlignTop = AlignRight,
AlignBottom = AlignLeft
};
@@ -337,6 +313,10 @@ public:
void fillEvenOdd(bool evenOddFlag);
bool fillEvenOdd() const;
void textAlignment(TextAlignment alignment);
void textSize(double sizeX, double sizeY);
inline void textSize(double size) { textSize(size, size); }
// Transformations
//-----------------------
Transformations transformations() const;
@@ -371,23 +351,6 @@ public:
void polygon(double* xy, int numPoints);
void polyline(double* xy, int numPoints);
#ifdef AGG_USE_FONTS
// Text
//-----------------------
void flipText(bool flip);
void font(const char* fileName, double height,
bool bold = false,
bool italic = false,
FontCacheType ch = RasterFontCache,
double angle = 0.0);
double fontHeight() const;
void textAlignment(TextAlignment alignX, TextAlignment alignY);
bool textHints() const;
void textHints(bool hints);
double textWidth(const char* str);
void text(double x, double y, const char* str, bool roundOff=false, double dx=0.0, double dy=0.0);
#endif
// Path commands
//-----------------------
void resetPath();
@@ -438,6 +401,7 @@ public:
double xTo, double yTo);
void addEllipse(double cx, double cy, double rx, double ry, Direction dir);
void text(double x, double y, const std::string& text);
void closePolygon();
void drawPath(DrawPathFlag flag = FillAndStroke);
@@ -552,14 +516,9 @@ private:
double m_fillGradientD2;
double m_lineGradientD2;
double m_textAngle;
TextAlignment m_textAlignX;
TextAlignment m_textAlignY;
bool m_textHints;
double m_fontHeight;
double m_fontAscent;
double m_fontDescent;
FontCacheType m_fontCacheType;
TextAlignment m_textAlignment;
double m_textSizeX;
double m_textSizeY;
ImageFilter m_imageFilter;
ImageResample m_imageResample;

View File

@@ -172,6 +172,9 @@ namespace agg
//--------------------------------------------------------------------
static rgba from_wavelength(double wl, double gamma = 1.0);
//--------------------------------------------------------------------
static rgba from_hsv(double h, double s, double v);
//--------------------------------------------------------------------
explicit rgba(double wavelen, double gamma=1.0)
{
@@ -235,6 +238,30 @@ namespace agg
return t;
}
inline rgba rgba::from_hsv(double h, double s, double v)
{
h = fmod(h, 360.0);
double hh = h / 60.0;
int i = (int)hh;
double ff = hh - i;
double p = v * (1.0 - s);
double q = v * (1.0 - s*ff);
double t = v * (1.0 - s*(1.0 - ff));
double r, g, b;
switch (i) {
case 0: r = v; g = t; b = p; break;
case 1: r = q; g = v; b = p; break;
case 2: r = p; g = v; b = t; break;
case 3: r = p; g = q; b = v; break;
case 4: r = t; g = p; b = v; break;
case 5:
default: r = v; g = p; b = q; break;
}
return rgba(r, g, b, 1.0);
}
inline rgba rgba_pre(double r, double g, double b, double a)
{
return rgba(r, g, b, a).premultiply();

View File

@@ -24,6 +24,7 @@
//----------------------------------------------------------------------------
#include "agg2d.h"
#include "agg_gsv_text.h"
static const double g_approxScale = 2.0;
@@ -79,14 +80,9 @@ Agg2D::Agg2D() :
m_fillGradientD2(100.0),
m_lineGradientD2(100.0),
m_textAngle(0.0),
m_textAlignX(AlignLeft),
m_textAlignY(AlignBottom),
m_textHints(true),
m_fontHeight(0.0),
m_fontAscent(0.0),
m_fontDescent(0.0),
m_fontCacheType(RasterFontCache),
m_textAlignment(AlignLeft),
m_textSizeX(10.0),
m_textSizeY(10.0),
m_imageFilter(Bilinear),
m_imageResample(NoResample),
@@ -138,15 +134,9 @@ void Agg2D::attach(unsigned char* buf, unsigned width, unsigned height, int stri
lineWidth(1.0),
lineColor(0,0,0);
fillColor(255,255,255);
#ifdef AGG_USE_FONTS
textAlignment(AlignLeft, AlignBottom);
#endif
clipBox(0, 0, width, height);
lineCap(CapRound);
lineJoin(JoinRound);
#ifdef AGG_USE_FONTS
flipText(false);
#endif
imageFilter(Bilinear);
imageResample(NoResample);
m_masterAlpha = 1.0;
@@ -908,183 +898,19 @@ void Agg2D::polyline(double* xy, int numPoints)
drawPath(StrokeOnly);
}
#ifdef AGG_USE_FONTS
//------------------------------------------------------------------------
void Agg2D::flipText(bool flip)
void Agg2D::textSize(double sizeX, double sizeY)
{
m_fontEngine.flip_y(flip);
m_textSizeX = sizeX;
m_textSizeY = sizeY;
}
//------------------------------------------------------------------------
void Agg2D::font(const char* fontName,
double height,
bool bold,
bool italic,
FontCacheType ch,
double angle)
void Agg2D::textAlignment(TextAlignment alignment)
{
m_textAngle = angle;
m_fontHeight = height;
m_fontCacheType = ch;
#ifdef AGG2D_USE_FREETYPE
m_fontEngine.load_font(fontName,
0,
(ch == VectorFontCache) ?
agg::glyph_ren_outline :
agg::glyph_ren_agg_gray8);
m_fontEngine.hinting(m_textHints);
m_fontEngine.height((ch == VectorFontCache) ? height : worldToScreen(height));
#else
m_fontEngine.hinting(m_textHints);
m_fontEngine.create_font(fontName,
(ch == VectorFontCache) ?
agg::glyph_ren_outline :
agg::glyph_ren_agg_gray8,
(ch == VectorFontCache) ? height : worldToScreen(height),
0.0,
bold ? 700 : 400,
italic);
#endif
m_textAlignment = alignment;
}
//------------------------------------------------------------------------
double Agg2D::fontHeight() const
{
return m_fontHeight;
}
//------------------------------------------------------------------------
void Agg2D::textAlignment(TextAlignment alignX, TextAlignment alignY)
{
m_textAlignX = alignX;
m_textAlignY = alignY;
}
//------------------------------------------------------------------------
double Agg2D::textWidth(const char* str)
{
double x = 0;
double y = 0;
bool first = true;
while(*str)
{
const agg::glyph_cache* glyph = m_fontCacheManager.glyph(*str);
if(glyph)
{
if(!first) m_fontCacheManager.add_kerning(&x, &y);
x += glyph->advance_x;
y += glyph->advance_y;
first = false;
}
++str;
}
return (m_fontCacheType == VectorFontCache) ? x : screenToWorld(x);
}
//------------------------------------------------------------------------
bool Agg2D::textHints() const
{
return m_textHints;
}
//------------------------------------------------------------------------
void Agg2D::textHints(bool hints)
{
m_textHints = hints;
}
//------------------------------------------------------------------------
void Agg2D::text(double x, double y, const char* str, bool roundOff, double ddx, double ddy)
{
double dx = 0.0;
double dy = 0.0;
switch(m_textAlignX)
{
case AlignCenter: dx = -textWidth(str) * 0.5; break;
case AlignRight: dx = -textWidth(str); break;
default: break;
}
double asc = fontHeight();
const agg::glyph_cache* glyph = m_fontCacheManager.glyph('H');
if(glyph)
{
asc = glyph->bounds.y2 - glyph->bounds.y1;
}
if(m_fontCacheType == RasterFontCache)
{
asc = screenToWorld(asc);
}
switch(m_textAlignY)
{
case AlignCenter: dy = -asc * 0.5; break;
case AlignTop: dy = -asc; break;
default: break;
}
if(m_fontEngine.flip_y()) dy = -dy;
agg::trans_affine mtx;
double start_x = x + dx;
double start_y = y + dy;
if (roundOff)
{
start_x = int(start_x);
start_y = int(start_y);
}
start_x += ddx;
start_y += ddy;
mtx *= agg::trans_affine_translation(-x, -y);
mtx *= agg::trans_affine_rotation(m_textAngle);
mtx *= agg::trans_affine_translation(x, y);
agg::conv_transform<FontCacheManager::path_adaptor_type> tr(m_fontCacheManager.path_adaptor(), mtx);
if(m_fontCacheType == RasterFontCache)
{
worldToScreen(start_x, start_y);
}
int i;
for (i = 0; str[i]; i++)
{
glyph = m_fontCacheManager.glyph(str[i]);
if(glyph)
{
if(i) m_fontCacheManager.add_kerning(&start_x, &start_y);
m_fontCacheManager.init_embedded_adaptors(glyph, start_x, start_y);
if(glyph->data_type == agg::glyph_data_outline)
{
m_path.remove_all();
//m_path.add_path(tr, 0, false);
m_path.concat_path(tr,0); // JME
drawPath();
}
if(glyph->data_type == agg::glyph_data_gray8)
{
render(m_fontCacheManager.gray8_adaptor(),
m_fontCacheManager.gray8_scanline());
}
start_x += glyph->advance_x;
start_y += glyph->advance_y;
}
}
}
#endif // AGG_USE_FONTS
//------------------------------------------------------------------------
void Agg2D::resetPath() { m_path.remove_all(); }
@@ -1237,6 +1063,33 @@ void Agg2D::addEllipse(double cx, double cy, double rx, double ry, Direction dir
m_path.close_polygon();
}
//------------------------------------------------------------------------
void Agg2D::text(double x, double y, const std::string& text)
{
agg::gsv_text t;
t.flip(true);
t.size(m_textSizeX, m_textSizeY);
t.text(text.c_str());
double w = t.text_width();
switch (m_textAlignment)
{
case AlignLeft:
break;
case AlignRight:
x -= w;
break;
case AlignCenter:
x -= w/2.0;
break;
}
t.start_point(x, y);
m_path.concat_path(t);
drawPath();
}
//------------------------------------------------------------------------
void Agg2D::closePolygon()
{

View File

@@ -25,7 +25,7 @@
namespace agg
{
int8u gsv_default_font[] =
const int8u gsv_default_font[] =
{
0x40,0x00,0x6c,0x0f,0x15,0x00,0x0e,0x00,0xf9,0xff,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,