r-lib / ragg

@@ -98,6 +98,9 @@
Loading
98 98
        unsigned        data_size()   const { return m_data_size;   }
99 99
        glyph_data_type data_type()   const { return m_data_type;   }
100 100
        const rect_i&   bounds()      const { return m_bounds;      }
101 +
        double          ascent()      const { return double(m_cur_face->size->metrics.ascender) / 64;}
102 +
        double          descent()     const { return double(m_cur_face->size->metrics.descender) / 64;}
103 +
        double          max_advance() const { return double(m_cur_face->size->metrics.max_advance) / 64;}
101 104
        double          advance_x()   const { return m_advance_x;   }
102 105
        double          advance_y()   const { return m_advance_y;   }
103 106
        void            write_glyph_to(int8u* data) const;

@@ -30,7 +30,7 @@
Loading
30 30
 * regardless. The base class outputs images in ppm format which is not realy
31 31
 * a usable format. See png and tiff versions for actual usable classes.
32 32
 */
33 -
template<class PIXFMT, class R_COLOR = agg::rgba8>
33 +
template<class PIXFMT, class R_COLOR = agg::rgba8, typename BLNDFMT = pixfmt_type_32>
34 34
class AggDevice {
35 35
public:
36 36
  typedef PIXFMT pixfmt_type;
@@ -63,7 +63,7 @@
Loading
63 63
  double res_mod;
64 64
  double lwd_mod;
65 65
  
66 -
  TextRenderer t_ren;
66 +
  TextRenderer<BLNDFMT> t_ren;
67 67
  
68 68
  // Lifecycle methods
69 69
  AggDevice(const char* fp, int w, int h, double ps, int bg, double res, 
@@ -156,9 +156,9 @@
Loading
156 156
/* The initialiser takes care of setting up the buffer, and caching a pixel 
157 157
 * formatter and renderer.
158 158
 */
159 -
template<class PIXFMT, class R_COLOR>
160 -
AggDevice<PIXFMT, R_COLOR>::AggDevice(const char* fp, int w, int h, double ps, 
161 -
                                      int bg, double res, double scaling) : 
159 +
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
160 +
AggDevice<PIXFMT, R_COLOR, BLNDFMT>::AggDevice(const char* fp, int w, int h, double ps, 
161 +
                                               int bg, double res, double scaling) : 
162 162
  width(w),
163 163
  height(h),
164 164
  clip_left(0),
@@ -181,8 +181,8 @@
Loading
181 181
  background = convertColour(background_int);
182 182
  renderer.clear(background);
183 183
}
184 -
template<class PIXFMT, class R_COLOR>
185 -
AggDevice<PIXFMT, R_COLOR>::~AggDevice() {
184 +
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
185 +
AggDevice<PIXFMT, R_COLOR, BLNDFMT>::~AggDevice() {
186 186
  delete pixf;
187 187
  delete [] buffer;
188 188
}
@@ -191,8 +191,8 @@
Loading
191 191
 * appropriate savePage() method. For screen devices it may make sense to change
192 192
 * it for performance
193 193
 */
194 -
template<class PIXFMT, class R_COLOR>
195 -
void AggDevice<PIXFMT, R_COLOR>::newPage(unsigned int bg) {
194 +
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
195 +
void AggDevice<PIXFMT, R_COLOR, BLNDFMT>::newPage(unsigned int bg) {
196 196
  if (pageno != 0) {
197 197
    if (!savePage()) {
198 198
      Rf_warning("agg could not write to the given file");
@@ -206,16 +206,16 @@
Loading
206 206
  }
207 207
  pageno++;
208 208
}
209 -
template<class PIXFMT, class R_COLOR>
210 -
void AggDevice<PIXFMT, R_COLOR>::close() {
209 +
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
210 +
void AggDevice<PIXFMT, R_COLOR, BLNDFMT>::close() {
211 211
  if (pageno == 0) pageno++;
212 212
  if (!savePage()) {
213 213
    Rf_warning("agg could not write to the given file");
214 214
  }
215 215
}
216 216
217 -
template<class PIXFMT, class R_COLOR>
218 -
SEXP AggDevice<PIXFMT, R_COLOR>::capture() {
217 +
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
218 +
SEXP AggDevice<PIXFMT, R_COLOR, BLNDFMT>::capture() {
219 219
  return Rf_allocVector(INTSXP, 0);
220 220
}
221 221
@@ -223,8 +223,8 @@
Loading
223 223
 * may be specified as a printf string with room for a page counter, so the 
224 224
 * method should take care of resolving that together with the pageno field.
225 225
 */
226 -
template<class PIXFMT, class R_COLOR>
227 -
bool AggDevice<PIXFMT, R_COLOR>::savePage() {
226 +
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
227 +
bool AggDevice<PIXFMT, R_COLOR, BLNDFMT>::savePage() {
228 228
  return true;
229 229
}
230 230
@@ -235,8 +235,8 @@
Loading
235 235
 * gain the different drawing methods should set it on the rasterizer as well
236 236
 * to avoid unneccesary allocation and looping
237 237
 */
238 -
template<class PIXFMT, class R_COLOR>
239 -
void AggDevice<PIXFMT, R_COLOR>::clipRect(double x0, double y0, double x1, 
238 +
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
239 +
void AggDevice<PIXFMT, R_COLOR, BLNDFMT>::clipRect(double x0, double y0, double x1, 
240 240
                                          double y1) {
241 241
  clip_left = x0;
242 242
  clip_right = x1;
@@ -251,8 +251,8 @@
Loading
251 251
 * They work on gray8 bitmap to speed it up as all metrixs are assumed to be in
252 252
 * horizontal mode only
253 253
 */
254 -
template<class PIXFMT, class R_COLOR>
255 -
double AggDevice<PIXFMT, R_COLOR>::stringWidth(const char *str, 
254 +
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
255 +
double AggDevice<PIXFMT, R_COLOR, BLNDFMT>::stringWidth(const char *str, 
256 256
                                               const char *family, int face, 
257 257
                                               double size) {
258 258
  size *= res_mod;
@@ -263,8 +263,8 @@
Loading
263 263
  
264 264
  return t_ren.get_text_width(str);
265 265
}
266 -
template<class PIXFMT, class R_COLOR>
267 -
void AggDevice<PIXFMT, R_COLOR>::charMetric(int c, const char *family, int face, 
266 +
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
267 +
void AggDevice<PIXFMT, R_COLOR, BLNDFMT>::charMetric(int c, const char *family, int face, 
268 268
                                   double size, double *ascent, double *descent, 
269 269
                                   double *width) {
270 270
  if (c < 0) {
@@ -296,8 +296,8 @@
Loading
296 296
 * number of points around the circle is precalculated below a radius of 64
297 297
 * pixels in order to speed up point rendering
298 298
 */
299 -
template<class PIXFMT, class R_COLOR>
300 -
void AggDevice<PIXFMT, R_COLOR>::drawCircle(double x, double y, double r, 
299 +
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
300 +
void AggDevice<PIXFMT, R_COLOR, BLNDFMT>::drawCircle(double x, double y, double r, 
301 301
                                            int fill, int col, double lwd, 
302 302
                                            int lty, R_GE_lineend lend) {
303 303
  bool draw_fill = visibleColour(fill);
@@ -349,8 +349,8 @@
Loading
349 349
  }
350 350
}
351 351
352 -
template<class PIXFMT, class R_COLOR>
353 -
void AggDevice<PIXFMT, R_COLOR>::drawRect(double x0, double y0, double x1, 
352 +
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
353 +
void AggDevice<PIXFMT, R_COLOR, BLNDFMT>::drawRect(double x0, double y0, double x1, 
354 354
                                          double y1, int fill, int col, 
355 355
                                          double lwd, int lty, 
356 356
                                          R_GE_lineend lend) {
@@ -395,8 +395,8 @@
Loading
395 395
  }
396 396
}
397 397
398 -
template<class PIXFMT, class R_COLOR>
399 -
void AggDevice<PIXFMT, R_COLOR>::drawPolygon(int n, double *x, double *y, 
398 +
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
399 +
void AggDevice<PIXFMT, R_COLOR, BLNDFMT>::drawPolygon(int n, double *x, double *y, 
400 400
                                             int fill, int col, double lwd, 
401 401
                                             int lty, R_GE_lineend lend, 
402 402
                                             R_GE_linejoin ljoin, 
@@ -447,8 +447,8 @@
Loading
447 447
  }
448 448
}
449 449
450 -
template<class PIXFMT, class R_COLOR>
451 -
void AggDevice<PIXFMT, R_COLOR>::drawLine(double x1, double y1, double x2, 
450 +
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
451 +
void AggDevice<PIXFMT, R_COLOR, BLNDFMT>::drawLine(double x1, double y1, double x2, 
452 452
                                          double y2, int col, double lwd, 
453 453
                                          int lty, R_GE_lineend lend) {
454 454
  if (!visibleColour(col) || lwd == 0.0 || lty == LTY_BLANK) return;
@@ -480,8 +480,8 @@
Loading
480 480
  }
481 481
}
482 482
483 -
template<class PIXFMT, class R_COLOR>
484 -
void AggDevice<PIXFMT, R_COLOR>::drawPolyline(int n, double* x, double* y, 
483 +
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
484 +
void AggDevice<PIXFMT, R_COLOR, BLNDFMT>::drawPolyline(int n, double* x, double* y, 
485 485
                                              int col, double lwd, int lty, 
486 486
                                              R_GE_lineend lend, 
487 487
                                              R_GE_linejoin ljoin, 
@@ -521,8 +521,8 @@
Loading
521 521
  }
522 522
}
523 523
524 -
template<class PIXFMT, class R_COLOR>
525 -
void AggDevice<PIXFMT, R_COLOR>::drawPath(int npoly, int* nper, double* x, 
524 +
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
525 +
void AggDevice<PIXFMT, R_COLOR, BLNDFMT>::drawPath(int npoly, int* nper, double* x, 
526 526
                                          double* y, int col, int fill, 
527 527
                                          double lwd, int lty, 
528 528
                                          R_GE_lineend lend, 
@@ -586,8 +586,8 @@
Loading
586 586
  }
587 587
}
588 588
589 -
template<class PIXFMT, class R_COLOR>
590 -
void AggDevice<PIXFMT, R_COLOR>::drawRaster(unsigned int *raster, int w, int h, 
589 +
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
590 +
void AggDevice<PIXFMT, R_COLOR, BLNDFMT>::drawRaster(unsigned int *raster, int w, int h, 
591 591
                                            double x, double y, 
592 592
                                            double final_width, 
593 593
                                            double final_height, double rot, 
@@ -595,9 +595,9 @@
Loading
595 595
  agg::rendering_buffer rbuf(reinterpret_cast<unsigned char*>(raster), w, h, 
596 596
                             w * 4);
597 597
  
598 -
  unsigned char * buffer8 = new unsigned char[w * h * pixfmt_type_32::pix_width];
599 -
  agg::rendering_buffer rbuf8(buffer8, w, h, w * pixfmt_type_32::pix_width);
600 -
  agg::convert<pixfmt_type_32, pixfmt_r_raster>(&rbuf8, &rbuf);
598 +
  unsigned char * buffer8 = new unsigned char[w * h * BLNDFMT::pix_width];
599 +
  agg::rendering_buffer rbuf8(buffer8, w, h, w * BLNDFMT::pix_width);
600 +
  agg::convert<BLNDFMT, pixfmt_r_raster>(&rbuf8, &rbuf);
601 601
602 602
  agg::trans_affine img_mtx;
603 603
  img_mtx *= agg::trans_affine_reflection(0);
@@ -612,11 +612,11 @@
Loading
612 612
  typedef agg::span_interpolator_linear<> interpolator_type;
613 613
  interpolator_type interpolator(img_mtx);
614 614
  
615 -
  typedef agg::image_accessor_clone<pixfmt_type_32> img_source_type;
615 +
  typedef agg::image_accessor_clone<BLNDFMT> img_source_type;
616 616
  
617 -
  pixfmt_type_32 img_pixf(rbuf8);
617 +
  BLNDFMT img_pixf(rbuf8);
618 618
  img_source_type img_src(img_pixf);
619 -
  agg::span_allocator<agg::rgba8> sa;
619 +
  agg::span_allocator<R_COLOR> sa;
620 620
  agg::rasterizer_scanline_aa<> ras;
621 621
  ras.clip_box(clip_left, clip_top, clip_right, clip_bottom);
622 622
  agg::scanline_u8 sl;
@@ -646,8 +646,8 @@
Loading
646 646
  delete [] buffer8;
647 647
}
648 648
649 -
template<class PIXFMT, class R_COLOR>
650 -
void AggDevice<PIXFMT, R_COLOR>::drawText(double x, double y, const char *str, 
649 +
template<class PIXFMT, class R_COLOR, typename BLNDFMT>
650 +
void AggDevice<PIXFMT, R_COLOR, BLNDFMT>::drawText(double x, double y, const char *str, 
651 651
                                          const char *family, int face, 
652 652
                                          double size, double rot, double hadj, 
653 653
                                          int col) {
@@ -662,7 +662,7 @@
Loading
662 662
  renderer_solid ren_solid(renderer);
663 663
  ren_solid.color(convertColour(col));
664 664
  
665 -
  t_ren.plot_text(x, y, str, rot, hadj, ren_solid);
665 +
  t_ren.plot_text(x, y, str, rot, hadj, ren_solid, renderer);
666 666
}
667 667
668 668

@@ -483,8 +483,43 @@
Loading
483 483
    }
484 484
485 485
486 -
487 -
486 +
    //------------------------------------------------------------------------
487 +
    template<class Rasterizer, class Scanline, class ScanlineStorage>
488 +
    void decompose_ft_bitmap_color(const FT_Bitmap& bitmap,
489 +
                                   int x, int y,
490 +
                                   bool flip_y,
491 +
                                   Rasterizer& ras,
492 +
                                   Scanline& sl,
493 +
                                   ScanlineStorage& storage)
494 +
    {
495 +
        unsigned int i, j;
496 +
        const int8u* buf = (const int8u*)bitmap.buffer;
497 +
        int pitch = bitmap.pitch;
498 +
        sl.reset(x, x + bitmap.width*4);
499 +
        storage.prepare();
500 +
        if(flip_y)
501 +
        {
502 +
            buf += bitmap.pitch * (bitmap.rows - 1);
503 +
            y += bitmap.rows;
504 +
            pitch = -pitch;
505 +
        }
506 +
        for(i = 0; i < bitmap.rows; i++)
507 +
        {
508 +
            sl.reset_spans();
509 +
            const int8u* p = buf;
510 +
            for(j = 0; j < bitmap.width*4; j++)
511 +
            {
512 +
                if(*p) sl.add_cell(x + j, *p);
513 +
                ++p;
514 +
            }
515 +
            buf += pitch;
516 +
            if(sl.num_spans())
517 +
            {
518 +
                sl.finalize(y - i - 1);
519 +
                storage.render(sl);
520 +
            }
521 +
        }
522 +
    }
488 523
489 524
490 525
@@ -680,49 +715,59 @@
Loading
680 715
            if(m_last_error == 0)
681 716
            {
682 717
                ret = true;
683 -
                
684 -
                switch(ren_type)
718 +
                if (FT_HAS_COLOR(m_cur_face))
685 719
                {
686 -
                case glyph_ren_native_mono:
687 -
                    m_glyph_rendering = glyph_ren_native_mono;
688 -
                    break;
689 -
690 -
                case glyph_ren_native_gray8:
691 -
                    m_glyph_rendering = glyph_ren_native_gray8;
692 -
                    break;
693 -
694 -
                case glyph_ren_outline:
695 -
                    if(FT_IS_SCALABLE(m_cur_face))
696 -
                    {
697 -
                        m_glyph_rendering = glyph_ren_outline;
698 -
                    }
699 -
                    else
700 -
                    {
701 -
                        m_glyph_rendering = glyph_ren_native_gray8;
702 -
                    }
703 -
                    break;
704 -
705 -
                case glyph_ren_agg_mono:
706 -
                    if(FT_IS_SCALABLE(m_cur_face))
707 -
                    {
708 -
                        m_glyph_rendering = glyph_ren_agg_mono;
709 -
                    }
710 -
                    else
720 +
                    m_glyph_rendering = glyph_ren_native_color;
721 +
                }
722 +
                else
723 +
                {
724 +
                    switch(ren_type)
711 725
                    {
726 +
                    case glyph_ren_native_mono:
712 727
                        m_glyph_rendering = glyph_ren_native_mono;
713 -
                    }
714 -
                    break;
715 -
716 -
                case glyph_ren_agg_gray8:
717 -
                    if(FT_IS_SCALABLE(m_cur_face))
718 -
                    {
719 -
                        m_glyph_rendering = glyph_ren_agg_gray8;
720 -
                    }
721 -
                    else
722 -
                    {
728 +
                        break;
729 +
                      
730 +
                    case glyph_ren_native_gray8:
723 731
                        m_glyph_rendering = glyph_ren_native_gray8;
724 -
                    }
725 -
                    break;
732 +
                        break;
733 +
                        
734 +
                    case glyph_ren_native_color: // Not a color font so use gray8
735 +
                      m_glyph_rendering = glyph_ren_native_gray8;
736 +
                      break;
737 +
                      
738 +
                    case glyph_ren_outline:
739 +
                        if(FT_IS_SCALABLE(m_cur_face))
740 +
                        {
741 +
                            m_glyph_rendering = glyph_ren_outline;
742 +
                        }
743 +
                        else
744 +
                        {
745 +
                            m_glyph_rendering = glyph_ren_native_gray8;
746 +
                        }
747 +
                        break;
748 +
                      
749 +
                    case glyph_ren_agg_mono:
750 +
                        if(FT_IS_SCALABLE(m_cur_face))
751 +
                        {
752 +
                            m_glyph_rendering = glyph_ren_agg_mono;
753 +
                        }
754 +
                        else
755 +
                        {
756 +
                            m_glyph_rendering = glyph_ren_native_mono;
757 +
                        }
758 +
                        break;
759 +
                      
760 +
                    case glyph_ren_agg_gray8:
761 +
                        if(FT_IS_SCALABLE(m_cur_face))
762 +
                        {
763 +
                            m_glyph_rendering = glyph_ren_agg_gray8;
764 +
                        }
765 +
                        else
766 +
                        {
767 +
                            m_glyph_rendering = glyph_ren_native_gray8;
768 +
                        }
769 +
                        break;
770 +
                    }  
726 771
                }
727 772
                update_signature();
728 773
            }
@@ -836,7 +881,7 @@
Loading
836 881
            }
837 882
838 883
            unsigned gamma_hash = 0;
839 -
            if(m_glyph_rendering == glyph_ren_native_gray8 ||
884 +
            if(m_glyph_rendering == glyph_ren_native_gray8 || m_glyph_rendering == glyph_ren_native_color ||
840 885
               m_glyph_rendering == glyph_ren_agg_mono || 
841 886
               m_glyph_rendering == glyph_ren_agg_gray8)
842 887
            {
@@ -892,7 +937,7 @@
Loading
892 937
              int diff = 1e6;
893 938
              for (int i = 0; i < m_cur_face->num_fixed_sizes; ++i)
894 939
              {
895 -
                  int ndiff = m_cur_face->available_sizes[i].height - (m_height >> 6);
940 +
                  int ndiff = m_cur_face->available_sizes[i].size - m_height;
896 941
                  if(ndiff >= 0 && ndiff < diff) 
897 942
                  {
898 943
                      best_match = i;
@@ -933,8 +978,7 @@
Loading
933 978
        m_glyph_index = glyph_index;
934 979
        m_last_error = FT_Load_Glyph(m_cur_face, 
935 980
                                     m_glyph_index, 
936 -
                                     m_hinting ? FT_LOAD_DEFAULT : FT_LOAD_NO_HINTING);
937 -
//                                     m_hinting ? FT_LOAD_FORCE_AUTOHINT : FT_LOAD_NO_HINTING);
981 +
                                     m_glyph_rendering == glyph_ren_native_color ? FT_LOAD_COLOR : (m_hinting ? FT_LOAD_DEFAULT : FT_LOAD_NO_HINTING));
938 982
        if(m_last_error == 0)
939 983
        {
940 984
            switch(m_glyph_rendering)
@@ -963,6 +1007,23 @@
Loading
963 1007
                break;
964 1008
965 1009
1010 +
                
1011 +
            case glyph_ren_native_color:
1012 +
                m_last_error = FT_Render_Glyph(m_cur_face->glyph, FT_RENDER_MODE_NORMAL);
1013 +
                if(m_last_error == 0)
1014 +
                {
1015 +
                    m_bounds.x1 = m_cur_face->glyph->bitmap_left;
1016 +
                    m_bounds.y1 = m_cur_face->glyph->bitmap_top;
1017 +
                    m_bounds.x2 = m_bounds.x1 + m_cur_face->glyph->bitmap.width;
1018 +
                    m_bounds.y2 = m_bounds.y1 - m_cur_face->glyph->bitmap.rows;
1019 +
                    m_data_size = m_cur_face->glyph->bitmap.rows * m_cur_face->glyph->bitmap.pitch; 
1020 +
                    m_data_type = glyph_data_color;
1021 +
                    m_advance_x = int26p6_to_dbl(m_cur_face->glyph->advance.x);
1022 +
                    m_advance_y = int26p6_to_dbl(m_cur_face->glyph->advance.y);
1023 +
                    return true;
1024 +
                }
1025 +
                break;
1026 +
                
966 1027
            case glyph_ren_native_gray8:
967 1028
                m_last_error = FT_Render_Glyph(m_cur_face->glyph, FT_RENDER_MODE_NORMAL);
968 1029
                if(m_last_error == 0)
@@ -1127,6 +1188,7 @@
Loading
1127 1188
            {
1128 1189
            default: return;
1129 1190
            case glyph_data_mono:    m_scanlines_bin.serialize(data); break;
1191 +
            case glyph_data_color:   memcpy(data, m_cur_face->glyph->bitmap.buffer, m_data_size); break;
1130 1192
            case glyph_data_gray8:   m_scanlines_aa.serialize(data);  break;
1131 1193
            case glyph_data_outline: 
1132 1194
                if(m_flag32)

@@ -10,6 +10,13 @@
Loading
10 10
#include "ragg.h"
11 11
12 12
#include "agg_font_freetype.h"
13 +
#include "agg_span_interpolator_linear.h"
14 +
#include "agg_image_accessors.h"
15 +
#include "agg_span_image_filter_rgba.h"
16 +
#include "agg_span_allocator.h"
17 +
#include "agg_path_storage.h"
18 +
19 +
#include "util/agg_color_conv.h"
13 20
14 21
typedef agg::font_engine_freetype_int32 font_engine_type;
15 22
typedef agg::font_cache_manager<font_engine_type> font_manager_type;
@@ -121,6 +128,7 @@
Loading
121 128
  }
122 129
};
123 130
131 +
template<typename PIXFMT>
124 132
class TextRenderer {
125 133
  UTF_UCS converter;
126 134
  FontSettings last_font;
@@ -188,17 +196,17 @@
Loading
188 196
      
189 197
      *width = glyph->advance_x;
190 198
    } else if (c == 77) { // GE uses M (77) to figure out size
191 -
      // Use height as a proxy - this fallback is mostly relevant for emoji
192 -
      *ascent = get_engine().height();
193 -
      *descent = get_engine().height();
199 +
      // Use global font metrics
200 +
      *ascent = get_engine().ascent();
201 +
      *descent = get_engine().descent();
194 202
      
195 -
      *width = get_engine().height();
203 +
      *width = get_engine().max_advance();
196 204
    }
197 205
  }
198 206
  
199 -
  template<typename renderer_solid>
207 +
  template<typename renderer_solid, typename renderer>
200 208
  void plot_text(double x, double y, const char *string, double rot, double hadj, 
201 -
                 renderer_solid &ren_solid) {
209 +
                 renderer_solid &ren_solid, renderer &ren) {
202 210
    agg::scanline_u8 sl;
203 211
    agg::rasterizer_scanline_aa<> ras;
204 212
    agg::conv_curve<font_manager_type::path_adaptor_type> curves(get_manager().path_adaptor());
@@ -274,6 +282,10 @@
Loading
274 282
                                ren_solid);
275 283
          break;
276 284
          
285 +
        case agg::glyph_data_color:
286 +
          renderColourGlyph(glyph, x + x_offset, y + y_offset, rot, ren);
287 +
          break;
288 +
          
277 289
        case agg::glyph_data_outline:
278 290
          ras.reset();
279 291
          ras.add_path(curves);
@@ -326,6 +338,52 @@
Loading
326 338
    }
327 339
    return locate_font_with_features(fontfamily, italic, bold);
328 340
  }
341 +
  
342 +
  template<typename ren>
343 +
  void renderColourGlyph(const agg::glyph_cache* glyph, double x, double y, double rot, ren &renderer) {
344 +
    int w = glyph->bounds.x2 - glyph->bounds.x1;
345 +
    int h = glyph->bounds.y1 - glyph->bounds.y2;
346 +
    x += glyph->bounds.x1;
347 +
    y -= glyph->bounds.y1;
348 +
    agg::rendering_buffer rbuf(glyph->data, w, h, w * 4);
349 +
    
350 +
    unsigned char * buffer = new unsigned char[w * h * PIXFMT::pix_width];
351 +
    agg::rendering_buffer rbuf_conv(buffer, w, h, w * PIXFMT::pix_width);
352 +
    agg::convert<PIXFMT, pixfmt_col_glyph>(&rbuf_conv, &rbuf);
353 +
    
354 +
    agg::trans_affine img_mtx;
355 +
    img_mtx *= agg::trans_affine_rotation(rot);
356 +
    img_mtx *= agg::trans_affine_translation(x, y);
357 +
    agg::trans_affine src_mtx = img_mtx;
358 +
    img_mtx.invert();
359 +
    
360 +
    typedef agg::span_interpolator_linear<> interpolator_type;
361 +
    interpolator_type interpolator(img_mtx);
362 +
    
363 +
    typedef agg::image_accessor_clone<PIXFMT> img_source_type;
364 +
    
365 +
    PIXFMT img_pixf(rbuf_conv);
366 +
    img_source_type img_src(img_pixf);
367 +
    agg::span_allocator<typename PIXFMT::blender_type::color_type> sa;
368 +
    agg::rasterizer_scanline_aa<> ras;
369 +
    agg::scanline_u8 sl;
370 +
    
371 +
    agg::path_storage rect;
372 +
    rect.remove_all();
373 +
    rect.move_to(0, 0);
374 +
    rect.line_to(0, h);
375 +
    rect.line_to(w, h);
376 +
    rect.line_to(w, 0);
377 +
    rect.close_polygon();
378 +
    agg::conv_transform<agg::path_storage> tr(rect, src_mtx);
379 +
    ras.add_path(tr);
380 +
    
381 +
    typedef agg::span_image_filter_rgba_bilinear<img_source_type, interpolator_type> span_gen_type;
382 +
    span_gen_type sg(img_src, interpolator);
383 +
    agg::render_scanlines_aa(ras, sl, renderer, sa, sg);
384 +
    
385 +
    delete [] buffer;
386 +
  }
329 387
};
330 388
331 389
#endif

@@ -33,6 +33,7 @@
Loading
33 33
typedef agg::pixfmt_rgba32_pre                  pixfmt_type_32;
34 34
typedef agg::pixfmt_rgb48_pre                   pixfmt_type_48;
35 35
typedef agg::pixfmt_rgba64_pre                  pixfmt_type_64;
36 +
typedef agg::pixfmt_bgra32_pre                  pixfmt_col_glyph;
36 37
37 38
#ifdef WORDS_BIGENDIAN
38 39
typedef agg::pixfmt_abgr32_plain                pixfmt_r_raster;

@@ -28,7 +28,8 @@
Loading
28 28
        glyph_data_invalid = 0,
29 29
        glyph_data_mono    = 1,
30 30
        glyph_data_gray8   = 2,
31 -
        glyph_data_outline = 3
31 +
        glyph_data_outline = 3,
32 +
        glyph_data_color   = 4
32 33
    };
33 34
34 35
@@ -248,7 +249,8 @@
Loading
248 249
        glyph_ren_native_gray8,
249 250
        glyph_ren_outline,
250 251
        glyph_ren_agg_mono,
251 -
        glyph_ren_agg_gray8
252 +
        glyph_ren_agg_gray8,
253 +
        glyph_ren_native_color
252 254
    };
253 255
254 256
@@ -323,7 +325,6 @@
Loading
323 325
                case glyph_data_mono:
324 326
                    m_mono_adaptor.init(gl->data, gl->data_size, x, y);
325 327
                    break;
326 -
327 328
                case glyph_data_gray8:
328 329
                    m_gray8_adaptor.init(gl->data, gl->data_size, x, y);
329 330
                    break;

@@ -25,77 +25,19 @@
Loading
25 25
};
26 26
27 27
template<class PIXFMT>
28 -
class AggDevice16 : public AggDevice<PIXFMT, agg::rgba16> {
28 +
class AggDevice16 : public AggDevice<PIXFMT, agg::rgba16, pixfmt_type_64> {
29 29
public:
30 30
  double alpha_mod;
31 31
  
32 32
  AggDevice16(const char* fp, int w, int h, double ps, int bg, double res, 
33 33
              double scaling, double alpha_mod = 1.0) : 
34 -
    AggDevice<PIXFMT, agg::rgba16>(fp, w, h, ps, bg, res, scaling),
34 +
    AggDevice<PIXFMT, agg::rgba16, pixfmt_type_64>(fp, w, h, ps, bg, res, scaling),
35 35
    alpha_mod(alpha_mod)
36 36
  {
37 37
      this->background = convertColour(this->background_int);
38 38
      this->renderer.clear(this->background);
39 39
  }
40 -
  
41 -
  void drawRaster(unsigned int *raster, int w, int h, double x, double y, 
42 -
                  double final_width, double final_height, double rot, 
43 -
                  bool interpolate) {
44 -
    agg::rendering_buffer rbuf(reinterpret_cast<unsigned char*>(raster), w, h, 
45 -
                               w * 4);
46 -
    
47 -
    unsigned char * buffer16 = new unsigned char[w * h * pixfmt_type_64::pix_width];
48 -
    agg::rendering_buffer rbuf16(buffer16, w, h, w * pixfmt_type_64::pix_width);
49 -
    
50 -
    agg::convert<pixfmt_type_64, pixfmt_r_raster>(&rbuf16, &rbuf);
51 -
    
52 -
    agg::trans_affine img_mtx;
53 -
    img_mtx *= agg::trans_affine_reflection(0);
54 -
    img_mtx *= agg::trans_affine_translation(0, h);
55 -
    img_mtx *= agg::trans_affine_scaling(final_width / double(w), 
56 -
                                         final_height / double (h));
57 -
    img_mtx *= agg::trans_affine_rotation(-rot * agg::pi / 180.0);
58 -
    img_mtx *= agg::trans_affine_translation(x, y);
59 -
    agg::trans_affine src_mtx = img_mtx;
60 -
    img_mtx.invert();
61 -
    
62 -
    typedef agg::span_interpolator_linear<> interpolator_type;
63 -
    interpolator_type interpolator(img_mtx);
64 -
    
65 -
    typedef agg::image_accessor_clone<pixfmt_type_64> img_source_type;
66 40
    
67 -
    pixfmt_type_64 img_pixf(rbuf16);
68 -
    img_source_type img_src(img_pixf);
69 -
    agg::span_allocator<agg::rgba16> sa;
70 -
    agg::rasterizer_scanline_aa<> ras;
71 -
    ras.clip_box(this->clip_left, this->clip_top, this->clip_right, 
72 -
                 this->clip_bottom);
73 -
    agg::scanline_u8 sl;
74 -
    
75 -
    agg::path_storage rect;
76 -
    rect.remove_all();
77 -
    rect.move_to(0, 0);
78 -
    rect.line_to(0, h);
79 -
    rect.line_to(w, h);
80 -
    rect.line_to(w, 0);
81 -
    rect.close_polygon();
82 -
    agg::conv_transform<agg::path_storage> tr(rect, src_mtx);
83 -
    ras.add_path(tr);
84 -
    
85 -
    if (interpolate) {
86 -
      typedef agg::span_image_filter_rgba_bilinear<img_source_type, interpolator_type> span_gen_type;
87 -
      span_gen_type sg(img_src, interpolator);
88 -
      
89 -
      agg::render_scanlines_aa(ras, sl, this->renderer, sa, sg);
90 -
    } else {
91 -
      typedef agg::span_image_filter_rgba_nn<img_source_type, interpolator_type> span_gen_type;
92 -
      span_gen_type sg(img_src, interpolator);
93 -
      
94 -
      agg::render_scanlines_aa(ras, sl, this->renderer, sa, sg);
95 -
    }
96 -
    
97 -
    delete [] buffer16;
98 -
  }
99 41
  void to_bigend() {
100 42
    uint16_t * buf =  reinterpret_cast<uint16_t *>(this->buffer);
101 43
    for (int i = 0; i < this->width * this->height * PIXFMT::num_components; i++) {
Files Coverage
R 76.00%
src 71.12%
Project Totals (69 files) 71.22%
1
comment: false
2

3
coverage:
4
  status:
5
    project:
6
      default:
7
        target: auto
8
        threshold: 1%
9
        informational: true
10
    patch:
11
      default:
12
        target: auto
13
        threshold: 1%
14
        informational: true
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading