Skip to content

Commit

Permalink
Fix ghaerr#1 Add colour font support
Browse files Browse the repository at this point in the history
  • Loading branch information
thomasp85 committed Nov 19, 2020
1 parent 1bc3b26 commit 878d843
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 158 deletions.
88 changes: 44 additions & 44 deletions src/AggDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
* regardless. The base class outputs images in ppm format which is not realy
* a usable format. See png and tiff versions for actual usable classes.
*/
template<class PIXFMT, class R_COLOR = agg::rgba8>
template<class PIXFMT, class R_COLOR = agg::rgba8, typename BLNDFMT = pixfmt_type_32>
class AggDevice {
public:
typedef PIXFMT pixfmt_type;
Expand Down Expand Up @@ -63,7 +63,7 @@ class AggDevice {
double res_mod;
double lwd_mod;

TextRenderer t_ren;
TextRenderer<BLNDFMT> t_ren;

// Lifecycle methods
AggDevice(const char* fp, int w, int h, double ps, int bg, double res,
Expand Down Expand Up @@ -156,9 +156,9 @@ class AggDevice {
/* The initialiser takes care of setting up the buffer, and caching a pixel
* formatter and renderer.
*/
template<class PIXFMT, class R_COLOR>
AggDevice<PIXFMT, R_COLOR>::AggDevice(const char* fp, int w, int h, double ps,
int bg, double res, double scaling) :
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
AggDevice<PIXFMT, R_COLOR, BLNDFMT>::AggDevice(const char* fp, int w, int h, double ps,
int bg, double res, double scaling) :
width(w),
height(h),
clip_left(0),
Expand All @@ -181,8 +181,8 @@ AggDevice<PIXFMT, R_COLOR>::AggDevice(const char* fp, int w, int h, double ps,
background = convertColour(background_int);
renderer.clear(background);
}
template<class PIXFMT, class R_COLOR>
AggDevice<PIXFMT, R_COLOR>::~AggDevice() {
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
AggDevice<PIXFMT, R_COLOR, BLNDFMT>::~AggDevice() {
delete pixf;
delete [] buffer;
}
Expand All @@ -191,8 +191,8 @@ AggDevice<PIXFMT, R_COLOR>::~AggDevice() {
* appropriate savePage() method. For screen devices it may make sense to change
* it for performance
*/
template<class PIXFMT, class R_COLOR>
void AggDevice<PIXFMT, R_COLOR>::newPage(unsigned int bg) {
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
void AggDevice<PIXFMT, R_COLOR, BLNDFMT>::newPage(unsigned int bg) {
if (pageno != 0) {
if (!savePage()) {
Rf_warning("agg could not write to the given file");
Expand All @@ -206,25 +206,25 @@ void AggDevice<PIXFMT, R_COLOR>::newPage(unsigned int bg) {
}
pageno++;
}
template<class PIXFMT, class R_COLOR>
void AggDevice<PIXFMT, R_COLOR>::close() {
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
void AggDevice<PIXFMT, R_COLOR, BLNDFMT>::close() {
if (pageno == 0) pageno++;
if (!savePage()) {
Rf_warning("agg could not write to the given file");
}
}

template<class PIXFMT, class R_COLOR>
SEXP AggDevice<PIXFMT, R_COLOR>::capture() {
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
SEXP AggDevice<PIXFMT, R_COLOR, BLNDFMT>::capture() {
return Rf_allocVector(INTSXP, 0);
}

/* This takes care of writing the buffer to an appropriate file. The filename
* may be specified as a printf string with room for a page counter, so the
* method should take care of resolving that together with the pageno field.
*/
template<class PIXFMT, class R_COLOR>
bool AggDevice<PIXFMT, R_COLOR>::savePage() {
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
bool AggDevice<PIXFMT, R_COLOR, BLNDFMT>::savePage() {
return true;
}

Expand All @@ -235,8 +235,8 @@ bool AggDevice<PIXFMT, R_COLOR>::savePage() {
* gain the different drawing methods should set it on the rasterizer as well
* to avoid unneccesary allocation and looping
*/
template<class PIXFMT, class R_COLOR>
void AggDevice<PIXFMT, R_COLOR>::clipRect(double x0, double y0, double x1,
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
void AggDevice<PIXFMT, R_COLOR, BLNDFMT>::clipRect(double x0, double y0, double x1,
double y1) {
clip_left = x0;
clip_right = x1;
Expand All @@ -251,8 +251,8 @@ void AggDevice<PIXFMT, R_COLOR>::clipRect(double x0, double y0, double x1,
* They work on gray8 bitmap to speed it up as all metrixs are assumed to be in
* horizontal mode only
*/
template<class PIXFMT, class R_COLOR>
double AggDevice<PIXFMT, R_COLOR>::stringWidth(const char *str,
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
double AggDevice<PIXFMT, R_COLOR, BLNDFMT>::stringWidth(const char *str,
const char *family, int face,
double size) {
size *= res_mod;
Expand All @@ -263,8 +263,8 @@ double AggDevice<PIXFMT, R_COLOR>::stringWidth(const char *str,

return t_ren.get_text_width(str);
}
template<class PIXFMT, class R_COLOR>
void AggDevice<PIXFMT, R_COLOR>::charMetric(int c, const char *family, int face,
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
void AggDevice<PIXFMT, R_COLOR, BLNDFMT>::charMetric(int c, const char *family, int face,
double size, double *ascent, double *descent,
double *width) {
if (c < 0) {
Expand Down Expand Up @@ -296,8 +296,8 @@ void AggDevice<PIXFMT, R_COLOR>::charMetric(int c, const char *family, int face,
* number of points around the circle is precalculated below a radius of 64
* pixels in order to speed up point rendering
*/
template<class PIXFMT, class R_COLOR>
void AggDevice<PIXFMT, R_COLOR>::drawCircle(double x, double y, double r,
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
void AggDevice<PIXFMT, R_COLOR, BLNDFMT>::drawCircle(double x, double y, double r,
int fill, int col, double lwd,
int lty, R_GE_lineend lend) {
bool draw_fill = visibleColour(fill);
Expand Down Expand Up @@ -349,8 +349,8 @@ void AggDevice<PIXFMT, R_COLOR>::drawCircle(double x, double y, double r,
}
}

template<class PIXFMT, class R_COLOR>
void AggDevice<PIXFMT, R_COLOR>::drawRect(double x0, double y0, double x1,
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
void AggDevice<PIXFMT, R_COLOR, BLNDFMT>::drawRect(double x0, double y0, double x1,
double y1, int fill, int col,
double lwd, int lty,
R_GE_lineend lend) {
Expand Down Expand Up @@ -395,8 +395,8 @@ void AggDevice<PIXFMT, R_COLOR>::drawRect(double x0, double y0, double x1,
}
}

template<class PIXFMT, class R_COLOR>
void AggDevice<PIXFMT, R_COLOR>::drawPolygon(int n, double *x, double *y,
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
void AggDevice<PIXFMT, R_COLOR, BLNDFMT>::drawPolygon(int n, double *x, double *y,
int fill, int col, double lwd,
int lty, R_GE_lineend lend,
R_GE_linejoin ljoin,
Expand Down Expand Up @@ -447,8 +447,8 @@ void AggDevice<PIXFMT, R_COLOR>::drawPolygon(int n, double *x, double *y,
}
}

template<class PIXFMT, class R_COLOR>
void AggDevice<PIXFMT, R_COLOR>::drawLine(double x1, double y1, double x2,
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
void AggDevice<PIXFMT, R_COLOR, BLNDFMT>::drawLine(double x1, double y1, double x2,
double y2, int col, double lwd,
int lty, R_GE_lineend lend) {
if (!visibleColour(col) || lwd == 0.0 || lty == LTY_BLANK) return;
Expand Down Expand Up @@ -480,8 +480,8 @@ void AggDevice<PIXFMT, R_COLOR>::drawLine(double x1, double y1, double x2,
}
}

template<class PIXFMT, class R_COLOR>
void AggDevice<PIXFMT, R_COLOR>::drawPolyline(int n, double* x, double* y,
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
void AggDevice<PIXFMT, R_COLOR, BLNDFMT>::drawPolyline(int n, double* x, double* y,
int col, double lwd, int lty,
R_GE_lineend lend,
R_GE_linejoin ljoin,
Expand Down Expand Up @@ -521,8 +521,8 @@ void AggDevice<PIXFMT, R_COLOR>::drawPolyline(int n, double* x, double* y,
}
}

template<class PIXFMT, class R_COLOR>
void AggDevice<PIXFMT, R_COLOR>::drawPath(int npoly, int* nper, double* x,
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
void AggDevice<PIXFMT, R_COLOR, BLNDFMT>::drawPath(int npoly, int* nper, double* x,
double* y, int col, int fill,
double lwd, int lty,
R_GE_lineend lend,
Expand Down Expand Up @@ -586,18 +586,18 @@ void AggDevice<PIXFMT, R_COLOR>::drawPath(int npoly, int* nper, double* x,
}
}

template<class PIXFMT, class R_COLOR>
void AggDevice<PIXFMT, R_COLOR>::drawRaster(unsigned int *raster, int w, int h,
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
void AggDevice<PIXFMT, R_COLOR, BLNDFMT>::drawRaster(unsigned int *raster, int w, int h,
double x, double y,
double final_width,
double final_height, double rot,
bool interpolate) {
agg::rendering_buffer rbuf(reinterpret_cast<unsigned char*>(raster), w, h,
w * 4);

unsigned char * buffer8 = new unsigned char[w * h * pixfmt_type_32::pix_width];
agg::rendering_buffer rbuf8(buffer8, w, h, w * pixfmt_type_32::pix_width);
agg::convert<pixfmt_type_32, pixfmt_r_raster>(&rbuf8, &rbuf);
unsigned char * buffer8 = new unsigned char[w * h * BLNDFMT::pix_width];
agg::rendering_buffer rbuf8(buffer8, w, h, w * BLNDFMT::pix_width);
agg::convert<BLNDFMT, pixfmt_r_raster>(&rbuf8, &rbuf);

agg::trans_affine img_mtx;
img_mtx *= agg::trans_affine_reflection(0);
Expand All @@ -612,11 +612,11 @@ void AggDevice<PIXFMT, R_COLOR>::drawRaster(unsigned int *raster, int w, int h,
typedef agg::span_interpolator_linear<> interpolator_type;
interpolator_type interpolator(img_mtx);

typedef agg::image_accessor_clone<pixfmt_type_32> img_source_type;
typedef agg::image_accessor_clone<BLNDFMT> img_source_type;

pixfmt_type_32 img_pixf(rbuf8);
BLNDFMT img_pixf(rbuf8);
img_source_type img_src(img_pixf);
agg::span_allocator<agg::rgba8> sa;
agg::span_allocator<R_COLOR> sa;
agg::rasterizer_scanline_aa<> ras;
ras.clip_box(clip_left, clip_top, clip_right, clip_bottom);
agg::scanline_u8 sl;
Expand Down Expand Up @@ -646,8 +646,8 @@ void AggDevice<PIXFMT, R_COLOR>::drawRaster(unsigned int *raster, int w, int h,
delete [] buffer8;
}

template<class PIXFMT, class R_COLOR>
void AggDevice<PIXFMT, R_COLOR>::drawText(double x, double y, const char *str,
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
void AggDevice<PIXFMT, R_COLOR, BLNDFMT>::drawText(double x, double y, const char *str,
const char *family, int face,
double size, double rot, double hadj,
int col) {
Expand All @@ -662,7 +662,7 @@ void AggDevice<PIXFMT, R_COLOR>::drawText(double x, double y, const char *str,
renderer_solid ren_solid(renderer);
ren_solid.color(convertColour(col));

t_ren.plot_text(x, y, str, rot, hadj, ren_solid);
t_ren.plot_text(x, y, str, rot, hadj, ren_solid, renderer);
}


Expand Down
62 changes: 2 additions & 60 deletions src/AggDevice16.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,77 +25,19 @@ struct AlphaDim {
};

template<class PIXFMT>
class AggDevice16 : public AggDevice<PIXFMT, agg::rgba16> {
class AggDevice16 : public AggDevice<PIXFMT, agg::rgba16, pixfmt_type_64> {
public:
double alpha_mod;

AggDevice16(const char* fp, int w, int h, double ps, int bg, double res,
double scaling, double alpha_mod = 1.0) :
AggDevice<PIXFMT, agg::rgba16>(fp, w, h, ps, bg, res, scaling),
AggDevice<PIXFMT, agg::rgba16, pixfmt_type_64>(fp, w, h, ps, bg, res, scaling),
alpha_mod(alpha_mod)
{
this->background = convertColour(this->background_int);
this->renderer.clear(this->background);
}

void drawRaster(unsigned int *raster, int w, int h, double x, double y,
double final_width, double final_height, double rot,
bool interpolate) {
agg::rendering_buffer rbuf(reinterpret_cast<unsigned char*>(raster), w, h,
w * 4);

unsigned char * buffer16 = new unsigned char[w * h * pixfmt_type_64::pix_width];
agg::rendering_buffer rbuf16(buffer16, w, h, w * pixfmt_type_64::pix_width);

agg::convert<pixfmt_type_64, pixfmt_r_raster>(&rbuf16, &rbuf);

agg::trans_affine img_mtx;
img_mtx *= agg::trans_affine_reflection(0);
img_mtx *= agg::trans_affine_translation(0, h);
img_mtx *= agg::trans_affine_scaling(final_width / double(w),
final_height / double (h));
img_mtx *= agg::trans_affine_rotation(-rot * agg::pi / 180.0);
img_mtx *= agg::trans_affine_translation(x, y);
agg::trans_affine src_mtx = img_mtx;
img_mtx.invert();

typedef agg::span_interpolator_linear<> interpolator_type;
interpolator_type interpolator(img_mtx);

typedef agg::image_accessor_clone<pixfmt_type_64> img_source_type;

pixfmt_type_64 img_pixf(rbuf16);
img_source_type img_src(img_pixf);
agg::span_allocator<agg::rgba16> sa;
agg::rasterizer_scanline_aa<> ras;
ras.clip_box(this->clip_left, this->clip_top, this->clip_right,
this->clip_bottom);
agg::scanline_u8 sl;

agg::path_storage rect;
rect.remove_all();
rect.move_to(0, 0);
rect.line_to(0, h);
rect.line_to(w, h);
rect.line_to(w, 0);
rect.close_polygon();
agg::conv_transform<agg::path_storage> tr(rect, src_mtx);
ras.add_path(tr);

if (interpolate) {
typedef agg::span_image_filter_rgba_bilinear<img_source_type, interpolator_type> span_gen_type;
span_gen_type sg(img_src, interpolator);

agg::render_scanlines_aa(ras, sl, this->renderer, sa, sg);
} else {
typedef agg::span_image_filter_rgba_nn<img_source_type, interpolator_type> span_gen_type;
span_gen_type sg(img_src, interpolator);

agg::render_scanlines_aa(ras, sl, this->renderer, sa, sg);
}

delete [] buffer16;
}
void to_bigend() {
uint16_t * buf = reinterpret_cast<uint16_t *>(this->buffer);
for (int i = 0; i < this->width * this->height * PIXFMT::num_components; i++) {
Expand Down
7 changes: 4 additions & 3 deletions src/agg/include/agg_font_cache_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ namespace agg
glyph_data_invalid = 0,
glyph_data_mono = 1,
glyph_data_gray8 = 2,
glyph_data_outline = 3
glyph_data_outline = 3,
glyph_data_color = 4
};


Expand Down Expand Up @@ -248,7 +249,8 @@ namespace agg
glyph_ren_native_gray8,
glyph_ren_outline,
glyph_ren_agg_mono,
glyph_ren_agg_gray8
glyph_ren_agg_gray8,
glyph_ren_native_color
};


Expand Down Expand Up @@ -323,7 +325,6 @@ namespace agg
case glyph_data_mono:
m_mono_adaptor.init(gl->data, gl->data_size, x, y);
break;

case glyph_data_gray8:
m_gray8_adaptor.init(gl->data, gl->data_size, x, y);
break;
Expand Down
3 changes: 3 additions & 0 deletions src/agg/include/agg_font_freetype.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ namespace agg
unsigned data_size() const { return m_data_size; }
glyph_data_type data_type() const { return m_data_type; }
const rect_i& bounds() const { return m_bounds; }
double ascent() const { return double(m_cur_face->size->metrics.ascender) / 64;}
double descent() const { return double(m_cur_face->size->metrics.descender) / 64;}
double max_advance() const { return double(m_cur_face->size->metrics.max_advance) / 64;}
double advance_x() const { return m_advance_x; }
double advance_y() const { return m_advance_y; }
void write_glyph_to(int8u* data) const;
Expand Down
Loading

0 comments on commit 878d843

Please sign in to comment.