Anti-Grain Geometry - AGG (libagg)
2.5
|
00001 //---------------------------------------------------------------------------- 00002 // Anti-Grain Geometry (AGG) - Version 2.5 00003 // A high quality rendering engine for C++ 00004 // Copyright (C) 2002-2006 Maxim Shemanarev 00005 // Contact: mcseem@antigrain.com 00006 // mcseemagg@yahoo.com 00007 // http://antigrain.com 00008 // 00009 // AGG is free software; you can redistribute it and/or 00010 // modify it under the terms of the GNU General Public License 00011 // as published by the Free Software Foundation; either version 2 00012 // of the License, or (at your option) any later version. 00013 // 00014 // AGG is distributed in the hope that it will be useful, 00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 // GNU General Public License for more details. 00018 // 00019 // You should have received a copy of the GNU General Public License 00020 // along with AGG; if not, write to the Free Software 00021 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00022 // MA 02110-1301, USA. 00023 //---------------------------------------------------------------------------- 00024 00025 #ifndef AGG_GLYPH_RASTER_BIN_INCLUDED 00026 #define AGG_GLYPH_RASTER_BIN_INCLUDED 00027 00028 #include <string.h> 00029 #include "agg_basics.h" 00030 00031 namespace agg 00032 { 00033 00034 //========================================================glyph_raster_bin 00035 template<class ColorT> class glyph_raster_bin 00036 { 00037 public: 00038 typedef ColorT color_type; 00039 00040 //-------------------------------------------------------------------- 00041 struct glyph_rect 00042 { 00043 int x1,y1,x2,y2; 00044 double dx, dy; 00045 }; 00046 00047 //-------------------------------------------------------------------- 00048 glyph_raster_bin(const int8u* font) : 00049 m_font(font), 00050 m_big_endian(false) 00051 { 00052 int t = 1; 00053 if(*(char*)&t == 0) m_big_endian = true; 00054 memset(m_span, 0, sizeof(m_span)); 00055 } 00056 00057 //-------------------------------------------------------------------- 00058 const int8u* font() const { return m_font; } 00059 void font(const int8u* f) { m_font = f; } 00060 00061 //-------------------------------------------------------------------- 00062 double height() const { return m_font[0]; } 00063 double base_line() const { return m_font[1]; } 00064 00065 //-------------------------------------------------------------------- 00066 template<class CharT> 00067 double width(const CharT* str) const 00068 { 00069 unsigned start_char = m_font[2]; 00070 unsigned num_chars = m_font[3]; 00071 00072 unsigned w = 0; 00073 while(*str) 00074 { 00075 unsigned glyph = *str; 00076 const int8u* bits = m_font + 4 + num_chars * 2 + 00077 value(m_font + 4 + (glyph - start_char) * 2); 00078 w += *bits; 00079 ++str; 00080 } 00081 return w; 00082 } 00083 00084 //-------------------------------------------------------------------- 00085 void prepare(glyph_rect* r, double x, double y, unsigned glyph, bool flip) 00086 { 00087 unsigned start_char = m_font[2]; 00088 unsigned num_chars = m_font[3]; 00089 00090 m_bits = m_font + 4 + num_chars * 2 + 00091 value(m_font + 4 + (glyph - start_char) * 2); 00092 00093 m_glyph_width = *m_bits++; 00094 m_glyph_byte_width = (m_glyph_width + 7) >> 3; 00095 00096 r->x1 = int(x); 00097 r->x2 = r->x1 + m_glyph_width - 1; 00098 if(flip) 00099 { 00100 r->y1 = int(y) - m_font[0] + m_font[1]; 00101 r->y2 = r->y1 + m_font[0] - 1; 00102 } 00103 else 00104 { 00105 r->y1 = int(y) - m_font[1] + 1; 00106 r->y2 = r->y1 + m_font[0] - 1; 00107 } 00108 r->dx = m_glyph_width; 00109 r->dy = 0; 00110 } 00111 00112 //-------------------------------------------------------------------- 00113 const cover_type* span(unsigned i) 00114 { 00115 i = m_font[0] - i - 1; 00116 const int8u* bits = m_bits + i * m_glyph_byte_width; 00117 unsigned j; 00118 unsigned val = *bits; 00119 unsigned nb = 0; 00120 for(j = 0; j < m_glyph_width; ++j) 00121 { 00122 m_span[j] = (cover_type)((val & 0x80) ? cover_full : cover_none); 00123 val <<= 1; 00124 if(++nb >= 8) 00125 { 00126 val = *++bits; 00127 nb = 0; 00128 } 00129 } 00130 return m_span; 00131 } 00132 00133 private: 00134 //-------------------------------------------------------------------- 00135 int16u value(const int8u* p) const 00136 { 00137 int16u v; 00138 if(m_big_endian) 00139 { 00140 *(int8u*)&v = p[1]; 00141 *((int8u*)&v + 1) = p[0]; 00142 } 00143 else 00144 { 00145 *(int8u*)&v = p[0]; 00146 *((int8u*)&v + 1) = p[1]; 00147 } 00148 return v; 00149 } 00150 00151 00152 //-------------------------------------------------------------------- 00153 const int8u* m_font; 00154 bool m_big_endian; 00155 cover_type m_span[32]; 00156 const int8u* m_bits; 00157 unsigned m_glyph_width; 00158 unsigned m_glyph_byte_width; 00159 }; 00160 00161 00162 } 00163 00164 #endif