1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry (AGG) - Version 2.5
3 // A high quality rendering engine for C++
4 // Copyright (C) 2002-2006 Maxim Shemanarev
5 // Contact: mcseem@antigrain.com
6 //          mcseemagg@yahoo.com
7 //          http://antigrain.com
8 //
9 // AGG is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU General Public License
11 // as published by the Free Software Foundation; either version 2
12 // of the License, or (at your option) any later version.
13 //
14 // AGG is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 // GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with AGG; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22 // MA 02110-1301, USA.
23 //----------------------------------------------------------------------------
24 
25 #ifndef AGG_GLYPH_RASTER_BIN_INCLUDED
26 #define AGG_GLYPH_RASTER_BIN_INCLUDED
27 
28 #include <string.h>
29 #include "agg_basics.h"
30 
31 namespace agg
32 {
33 
34     //========================================================glyph_raster_bin
35     template<class ColorT> class glyph_raster_bin
36     {
37     public:
38         typedef ColorT color_type;
39 
40         //--------------------------------------------------------------------
41         struct glyph_rect
42         {
43             int x1,y1,x2,y2;
44             double dx, dy;
45         };
46 
47         //--------------------------------------------------------------------
glyph_raster_bin(const int8u * font)48         glyph_raster_bin(const int8u* font) :
49             m_font(font),
50             m_big_endian(false)
51         {
52             int t = 1;
53             if(*(char*)&t == 0) m_big_endian = true;
54             memset(m_span, 0, sizeof(m_span));
55         }
56 
57         //--------------------------------------------------------------------
font()58         const int8u* font() const { return m_font; }
font(const int8u * f)59         void font(const int8u* f) { m_font = f; }
60 
61         //--------------------------------------------------------------------
height()62         double height()    const { return m_font[0]; }
base_line()63         double base_line() const { return m_font[1]; }
64 
65         //--------------------------------------------------------------------
66         template<class CharT>
width(const CharT * str)67         double width(const CharT* str) const
68         {
69             unsigned start_char = m_font[2];
70             unsigned num_chars = m_font[3];
71 
72             unsigned w = 0;
73             while(*str)
74             {
75                 unsigned glyph = *str;
76                 const int8u* bits = m_font + 4 + num_chars * 2 +
77                                     value(m_font + 4 + (glyph - start_char) * 2);
78                 w += *bits;
79                 ++str;
80             }
81             return w;
82         }
83 
84         //--------------------------------------------------------------------
prepare(glyph_rect * r,double x,double y,unsigned glyph,bool flip)85         void prepare(glyph_rect* r, double x, double y, unsigned glyph, bool flip)
86         {
87             unsigned start_char = m_font[2];
88             unsigned num_chars = m_font[3];
89 
90             m_bits = m_font + 4 + num_chars * 2 +
91                      value(m_font + 4 + (glyph - start_char) * 2);
92 
93             m_glyph_width = *m_bits++;
94             m_glyph_byte_width = (m_glyph_width + 7) >> 3;
95 
96             r->x1 = int(x);
97             r->x2 = r->x1 + m_glyph_width - 1;
98             if(flip)
99             {
100                 r->y1 = int(y) - m_font[0] + m_font[1];
101                 r->y2 = r->y1 + m_font[0] - 1;
102             }
103             else
104             {
105                 r->y1 = int(y) - m_font[1] + 1;
106                 r->y2 = r->y1 + m_font[0] - 1;
107             }
108             r->dx = m_glyph_width;
109             r->dy = 0;
110         }
111 
112         //--------------------------------------------------------------------
span(unsigned i)113         const cover_type* span(unsigned i)
114         {
115             i = m_font[0] - i - 1;
116             const int8u* bits = m_bits + i * m_glyph_byte_width;
117             unsigned j;
118             unsigned val = *bits;
119             unsigned nb = 0;
120             for(j = 0; j < m_glyph_width; ++j)
121             {
122                 m_span[j] = (cover_type)((val & 0x80) ? cover_full : cover_none);
123                 val <<= 1;
124                 if(++nb >= 8)
125                 {
126                     val = *++bits;
127                     nb = 0;
128                 }
129             }
130             return m_span;
131         }
132 
133     private:
134         //--------------------------------------------------------------------
value(const int8u * p)135         int16u value(const int8u* p) const
136         {
137             int16u v;
138             if(m_big_endian)
139             {
140                  *(int8u*)&v      = p[1];
141                 *((int8u*)&v + 1) = p[0];
142             }
143             else
144             {
145                  *(int8u*)&v      = p[0];
146                 *((int8u*)&v + 1) = p[1];
147             }
148             return v;
149         }
150 
151 
152         //--------------------------------------------------------------------
153         const int8u* m_font;
154         bool m_big_endian;
155         cover_type m_span[32];
156         const int8u* m_bits;
157         unsigned m_glyph_width;
158         unsigned m_glyph_byte_width;
159     };
160 
161 
162 }
163 
164 #endif
165