1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
4 //
5 // Permission to copy, use, modify, sell and distribute this software
6 // is granted provided this copyright notice appears in all copies.
7 // This software is provided "as is" without express or implied
8 // warranty, and with no claim as to its suitability for any purpose.
9 //
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 //          mcseemagg@yahoo.com
13 //          http://www.antigrain.com
14 //----------------------------------------------------------------------------
15 
16 #ifndef AGG_GLYPH_RASTER_BIN_INCLUDED
17 #define AGG_GLYPH_RASTER_BIN_INCLUDED
18 
19 #include <cstring>
20 #include "agg_basics.h"
21 
22 namespace agg
23 {
24 
25     //========================================================glyph_raster_bin
26     template<class ColorT> class glyph_raster_bin
27     {
28     public:
29         typedef ColorT color_type;
30 
31         //--------------------------------------------------------------------
32         struct glyph_rect
33         {
34             int x1,y1,x2,y2;
35             double dx, dy;
36         };
37 
38         //--------------------------------------------------------------------
glyph_raster_bin(const int8u * font)39         glyph_raster_bin(const int8u* font) :
40             m_font(font),
41             m_big_endian(false)
42         {
43             int t = 1;
44             if(*(char*)&t == 0) m_big_endian = true;
45             std::memset(m_span, 0, sizeof(m_span));
46         }
47 
48         //--------------------------------------------------------------------
font()49         const int8u* font() const { return m_font; }
font(const int8u * f)50         void font(const int8u* f) { m_font = f; }
51 
52         //--------------------------------------------------------------------
height()53         double height()    const { return m_font[0]; }
base_line()54         double base_line() const { return m_font[1]; }
55 
56         //--------------------------------------------------------------------
57         template<class CharT>
width(const CharT * str)58         double width(const CharT* str) const
59         {
60             unsigned start_char = m_font[2];
61             unsigned num_chars = m_font[3];
62 
63             unsigned w = 0;
64             while(*str)
65             {
66                 unsigned glyph = *str;
67                 const int8u* bits = m_font + 4 + num_chars * 2 +
68                                     value(m_font + 4 + (glyph - start_char) * 2);
69                 w += *bits;
70                 ++str;
71             }
72             return w;
73         }
74 
75         //--------------------------------------------------------------------
prepare(glyph_rect * r,double x,double y,unsigned glyph,bool flip)76         void prepare(glyph_rect* r, double x, double y, unsigned glyph, bool flip)
77         {
78             unsigned start_char = m_font[2];
79             unsigned num_chars = m_font[3];
80 
81             m_bits = m_font + 4 + num_chars * 2 +
82                      value(m_font + 4 + (glyph - start_char) * 2);
83 
84             m_glyph_width = *m_bits++;
85             m_glyph_byte_width = (m_glyph_width + 7) >> 3;
86 
87             r->x1 = int(x);
88             r->x2 = r->x1 + m_glyph_width - 1;
89             if(flip)
90             {
91                 r->y1 = int(y) - m_font[0] + m_font[1];
92                 r->y2 = r->y1 + m_font[0] - 1;
93             }
94             else
95             {
96                 r->y1 = int(y) - m_font[1] + 1;
97                 r->y2 = r->y1 + m_font[0] - 1;
98             }
99             r->dx = m_glyph_width;
100             r->dy = 0;
101         }
102 
103         //--------------------------------------------------------------------
span(unsigned i)104         const cover_type* span(unsigned i)
105         {
106             i = m_font[0] - i - 1;
107             const int8u* bits = m_bits + i * m_glyph_byte_width;
108             unsigned j;
109             unsigned val = *bits;
110             unsigned nb = 0;
111             for(j = 0; j < m_glyph_width; ++j)
112             {
113                 m_span[j] = (cover_type)((val & 0x80) ? cover_full : cover_none);
114                 val <<= 1;
115                 if(++nb >= 8)
116                 {
117                     val = *++bits;
118                     nb = 0;
119                 }
120             }
121             return m_span;
122         }
123 
124     private:
125         //--------------------------------------------------------------------
value(const int8u * p)126         int16u value(const int8u* p) const
127         {
128             int16u v;
129             if(m_big_endian)
130             {
131                  *(int8u*)&v      = p[1];
132                 *((int8u*)&v + 1) = p[0];
133             }
134             else
135             {
136                  *(int8u*)&v      = p[0];
137                 *((int8u*)&v + 1) = p[1];
138             }
139             return v;
140         }
141 
142 
143         //--------------------------------------------------------------------
144         const int8u* m_font;
145         bool m_big_endian;
146         cover_type m_span[32];
147         const int8u* m_bits;
148         unsigned m_glyph_width;
149         unsigned m_glyph_byte_width;
150     };
151 
152 
153 }
154 
155 #endif
156