2006-02-01 00:09:52 +01:00
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
// Anti-Grain Geometry - Version 2.4
|
|
|
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
|
|
|
//
|
|
|
|
// Permission to copy, use, modify, sell and distribute this software
|
|
|
|
// is granted provided this copyright notice appears in all copies.
|
|
|
|
// This software is provided "as is" without express or implied
|
|
|
|
// warranty, and with no claim as to its suitability for any purpose.
|
|
|
|
//
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
// Contact: mcseem@antigrain.com
|
|
|
|
// mcseemagg@yahoo.com
|
|
|
|
// http://www.antigrain.com
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#ifndef AGG_RENDERER_RASTER_TEXT_INCLUDED
|
|
|
|
#define AGG_RENDERER_RASTER_TEXT_INCLUDED
|
|
|
|
|
|
|
|
#include "agg_basics.h"
|
|
|
|
|
|
|
|
namespace agg
|
|
|
|
{
|
|
|
|
|
|
|
|
//==============================================renderer_raster_htext_solid
|
|
|
|
template<class BaseRenderer, class GlyphGenerator>
|
|
|
|
class renderer_raster_htext_solid
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef BaseRenderer ren_type;
|
|
|
|
typedef GlyphGenerator glyph_gen_type;
|
|
|
|
typedef typename glyph_gen_type::glyph_rect glyph_rect;
|
|
|
|
typedef typename ren_type::color_type color_type;
|
|
|
|
|
|
|
|
renderer_raster_htext_solid(ren_type& ren, glyph_gen_type& glyph) :
|
|
|
|
m_ren(&ren),
|
|
|
|
m_glyph(&glyph)
|
2006-11-10 00:44:34 +01:00
|
|
|
{}
|
|
|
|
void attach(ren_type& ren) { m_ren = &ren; }
|
2006-02-01 00:09:52 +01:00
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
void color(const color_type& c) { m_color = c; }
|
|
|
|
const color_type& color() const { return m_color; }
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
template<class CharT>
|
|
|
|
void render_text(double x, double y, const CharT* str, bool flip=false)
|
|
|
|
{
|
|
|
|
glyph_rect r;
|
|
|
|
while(*str)
|
|
|
|
{
|
|
|
|
m_glyph->prepare(&r, x, y, *str, flip);
|
|
|
|
if(r.x2 >= r.x1)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
if(flip)
|
|
|
|
{
|
|
|
|
for(i = r.y1; i <= r.y2; i++)
|
|
|
|
{
|
|
|
|
m_ren->blend_solid_hspan(r.x1, i, (r.x2 - r.x1 + 1),
|
|
|
|
m_color,
|
|
|
|
m_glyph->span(r.y2 - i));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for(i = r.y1; i <= r.y2; i++)
|
|
|
|
{
|
|
|
|
m_ren->blend_solid_hspan(r.x1, i, (r.x2 - r.x1 + 1),
|
|
|
|
m_color,
|
|
|
|
m_glyph->span(i - r.y1));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
x += r.dx;
|
|
|
|
y += r.dy;
|
|
|
|
++str;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
ren_type* m_ren;
|
|
|
|
glyph_gen_type* m_glyph;
|
|
|
|
color_type m_color;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//=============================================renderer_raster_vtext_solid
|
|
|
|
template<class BaseRenderer, class GlyphGenerator>
|
|
|
|
class renderer_raster_vtext_solid
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef BaseRenderer ren_type;
|
|
|
|
typedef GlyphGenerator glyph_gen_type;
|
|
|
|
typedef typename glyph_gen_type::glyph_rect glyph_rect;
|
|
|
|
typedef typename ren_type::color_type color_type;
|
|
|
|
|
|
|
|
renderer_raster_vtext_solid(ren_type& ren, glyph_gen_type& glyph) :
|
|
|
|
m_ren(&ren),
|
|
|
|
m_glyph(&glyph)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
void color(const color_type& c) { m_color = c; }
|
|
|
|
const color_type& color() const { return m_color; }
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
template<class CharT>
|
|
|
|
void render_text(double x, double y, const CharT* str, bool flip=false)
|
|
|
|
{
|
|
|
|
glyph_rect r;
|
|
|
|
while(*str)
|
|
|
|
{
|
|
|
|
m_glyph->prepare(&r, x, y, *str, !flip);
|
|
|
|
if(r.x2 >= r.x1)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
if(flip)
|
|
|
|
{
|
|
|
|
for(i = r.y1; i <= r.y2; i++)
|
|
|
|
{
|
|
|
|
m_ren->blend_solid_vspan(i, r.x1, (r.x2 - r.x1 + 1),
|
|
|
|
m_color,
|
|
|
|
m_glyph->span(i - r.y1));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for(i = r.y1; i <= r.y2; i++)
|
|
|
|
{
|
|
|
|
m_ren->blend_solid_vspan(i, r.x1, (r.x2 - r.x1 + 1),
|
|
|
|
m_color,
|
|
|
|
m_glyph->span(r.y2 - i));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
x += r.dx;
|
|
|
|
y += r.dy;
|
|
|
|
++str;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
ren_type* m_ren;
|
|
|
|
glyph_gen_type* m_glyph;
|
|
|
|
color_type m_color;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//===================================================renderer_raster_htext
|
|
|
|
template<class ScanlineRenderer, class GlyphGenerator>
|
|
|
|
class renderer_raster_htext
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef ScanlineRenderer ren_type;
|
|
|
|
typedef GlyphGenerator glyph_gen_type;
|
|
|
|
typedef typename glyph_gen_type::glyph_rect glyph_rect;
|
|
|
|
|
|
|
|
class scanline_single_span
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef agg::cover_type cover_type;
|
|
|
|
|
|
|
|
//----------------------------------------------------------------
|
|
|
|
struct const_span
|
|
|
|
{
|
|
|
|
int x;
|
|
|
|
unsigned len;
|
|
|
|
const cover_type* covers;
|
|
|
|
|
|
|
|
const_span() {}
|
|
|
|
const_span(int x_, unsigned len_, const cover_type* covers_) :
|
|
|
|
x(x_), len(len_), covers(covers_)
|
|
|
|
{}
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef const const_span* const_iterator;
|
|
|
|
|
|
|
|
//----------------------------------------------------------------
|
|
|
|
scanline_single_span(int x, int y, unsigned len,
|
|
|
|
const cover_type* covers) :
|
|
|
|
m_y(y),
|
|
|
|
m_span(x, len, covers)
|
|
|
|
{}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------
|
|
|
|
int y() const { return m_y; }
|
|
|
|
unsigned num_spans() const { return 1; }
|
|
|
|
const_iterator begin() const { return &m_span; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
//----------------------------------------------------------------
|
|
|
|
int m_y;
|
|
|
|
const_span m_span;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
renderer_raster_htext(ren_type& ren, glyph_gen_type& glyph) :
|
|
|
|
m_ren(&ren),
|
|
|
|
m_glyph(&glyph)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
template<class CharT>
|
|
|
|
void render_text(double x, double y, const CharT* str, bool flip=false)
|
|
|
|
{
|
|
|
|
glyph_rect r;
|
|
|
|
while(*str)
|
|
|
|
{
|
|
|
|
m_glyph->prepare(&r, x, y, *str, flip);
|
|
|
|
if(r.x2 >= r.x1)
|
|
|
|
{
|
|
|
|
m_ren->prepare();
|
|
|
|
int i;
|
|
|
|
if(flip)
|
|
|
|
{
|
|
|
|
for(i = r.y1; i <= r.y2; i++)
|
|
|
|
{
|
|
|
|
m_ren->render(
|
|
|
|
scanline_single_span(r.x1,
|
|
|
|
i,
|
|
|
|
(r.x2 - r.x1 + 1),
|
|
|
|
m_glyph->span(r.y2 - i)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for(i = r.y1; i <= r.y2; i++)
|
|
|
|
{
|
|
|
|
m_ren->render(
|
|
|
|
scanline_single_span(r.x1,
|
|
|
|
i,
|
|
|
|
(r.x2 - r.x1 + 1),
|
|
|
|
m_glyph->span(i - r.y1)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
x += r.dx;
|
|
|
|
y += r.dy;
|
|
|
|
++str;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
ren_type* m_ren;
|
|
|
|
glyph_gen_type* m_glyph;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|