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 <string.h>
20#include "agg_basics.h"
21
22namespace 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        //--------------------------------------------------------------------
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            memset(m_span, 0, sizeof(m_span));
46        }
47
48        //--------------------------------------------------------------------
49        const int8u* font() const { return m_font; }
50        void font(const int8u* f) { m_font = f; }
51
52        //--------------------------------------------------------------------
53        double height()    const { return m_font[0]; }
54        double base_line() const { return m_font[1]; }
55
56        //--------------------------------------------------------------------
57        template<class CharT>
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        //--------------------------------------------------------------------
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        //--------------------------------------------------------------------
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        //--------------------------------------------------------------------
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