00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "dynamicTextPage.h"
00016 #include "dynamicTextFont.h"
00017
00018 #ifdef HAVE_FREETYPE
00019
00020
00021 TypeHandle DynamicTextPage::_type_handle;
00022
00023
00024
00025
00026
00027
00028 DynamicTextPage::
00029 DynamicTextPage(DynamicTextFont *font, int page_number) :
00030 _font(font)
00031 {
00032
00033
00034 set_compression(CM_off);
00035
00036
00037
00038 set_quality_level(text_quality_level);
00039
00040 _x_size = _font->get_page_x_size();
00041 _y_size = _font->get_page_y_size();
00042
00043 setup_2d_texture(_x_size, _y_size, T_unsigned_byte, font->get_tex_format());
00044
00045
00046 ostringstream strm;
00047 strm << font->get_name() << "_" << page_number;
00048 set_name(strm.str());
00049
00050
00051 set_keep_ram_image(true);
00052
00053 set_minfilter(_font->get_minfilter());
00054 set_magfilter(_font->get_magfilter());
00055
00056 set_anisotropic_degree(_font->get_anisotropic_degree());
00057
00058
00059
00060 set_wrap_u(text_wrap_mode);
00061 set_wrap_v(text_wrap_mode);
00062 set_border_color(font->get_bg());
00063
00064
00065 fill_region(0, 0, _x_size, _y_size, font->get_bg());
00066 }
00067
00068
00069
00070
00071
00072
00073
00074
00075 DynamicTextGlyph *DynamicTextPage::
00076 slot_glyph(int character, int x_size, int y_size, int margin) {
00077 int x, y;
00078 if (!find_hole(x, y, x_size, y_size)) {
00079
00080 return (DynamicTextGlyph *)NULL;
00081 }
00082
00083
00084 PT(DynamicTextGlyph) glyph =
00085 new DynamicTextGlyph(character, this,
00086 x, y, x_size, y_size, margin);
00087 _glyphs.push_back(glyph);
00088 return glyph;
00089 }
00090
00091
00092
00093
00094
00095
00096
00097 void DynamicTextPage::
00098 fill_region(int x, int y, int x_size, int y_size, const LColor &color) {
00099 nassertv(x >= 0 && x + x_size <= _x_size && y >= 0 && y + y_size <= _y_size);
00100 int num_components = get_num_components();
00101 if (num_components == 1) {
00102
00103 int ci = 3;
00104 if (get_format() != Texture::F_alpha) {
00105 ci = 0;
00106 }
00107
00108 unsigned char v = (unsigned char)(color[ci] * 255.0f);
00109
00110 unsigned char *image = modify_ram_image();
00111 for (int yi = y; yi < y + y_size; yi++) {
00112 unsigned char *row = image + yi * _x_size;
00113 memset(row + x, v, x_size);
00114 }
00115
00116 } else if (num_components == 2) {
00117
00118
00119 union {
00120 unsigned char p[2];
00121 PN_uint16 v;
00122 } v;
00123
00124 v.p[0] = (unsigned char)(color[0] * 255.0f);
00125 v.p[1] = (unsigned char)(color[3] * 255.0f);
00126
00127 PN_uint16 *image = (PN_uint16 *)modify_ram_image().p();
00128 for (int yi = y; yi < y + y_size; yi++) {
00129 PN_uint16 *row = image + yi * _x_size ;
00130 for (int xi = x; xi < x + x_size; xi++) {
00131 row[xi] = v.v;
00132 }
00133 }
00134
00135 } else if (num_components == 3) {
00136
00137
00138 unsigned char p0 = (unsigned char)(color[2] * 255.0f);
00139 unsigned char p1 = (unsigned char)(color[1] * 255.0f);
00140 unsigned char p2 = (unsigned char)(color[0] * 255.0f);
00141
00142 unsigned char *image = modify_ram_image();
00143 for (int yi = y; yi < y + y_size; yi++) {
00144 unsigned char *row = image + yi * _x_size * 3;
00145 for (int xi = x; xi < x + x_size; xi++) {
00146 row[xi * 3] = p0;
00147 row[xi * 3 + 1] = p1;
00148 row[xi * 3 + 2] = p2;
00149 }
00150 }
00151
00152 } else {
00153
00154 union {
00155 unsigned char p[4];
00156 PN_uint32 v;
00157 } v;
00158
00159 v.p[0] = (unsigned char)(color[2] * 255.0f);
00160 v.p[1] = (unsigned char)(color[1] * 255.0f);
00161 v.p[2] = (unsigned char)(color[0] * 255.0f);
00162 v.p[3] = (unsigned char)(color[3] * 255.0f);
00163
00164 PN_uint32 *image = (PN_uint32 *)modify_ram_image().p();
00165 for (int yi = y; yi < y + y_size; yi++) {
00166 PN_uint32 *row = image + yi * _x_size;
00167 for (int xi = x; xi < x + x_size; xi++) {
00168 row[xi] = v.v;
00169 }
00170 }
00171 }
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 int DynamicTextPage::
00184 garbage_collect(DynamicTextFont *font) {
00185 int removed_count = 0;
00186
00187 Glyphs new_glyphs;
00188 Glyphs::iterator gi;
00189 for (gi = _glyphs.begin(); gi != _glyphs.end(); ++gi) {
00190 DynamicTextGlyph *glyph = (*gi);
00191 if (glyph->_geom_count != 0) {
00192
00193 new_glyphs.insert(new_glyphs.end(), (*gi));
00194 } else {
00195
00196 removed_count++;
00197 glyph->erase(font);
00198 }
00199 }
00200
00201 _glyphs.swap(new_glyphs);
00202 return removed_count;
00203 }
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 bool DynamicTextPage::
00214 find_hole(int &x, int &y, int x_size, int y_size) const {
00215 y = 0;
00216 while (y + y_size <= _y_size) {
00217 int next_y = _y_size;
00218
00219 x = 0;
00220 while (x + x_size <= _x_size) {
00221 int next_x = x;
00222
00223
00224 DynamicTextGlyph *overlap = find_overlap(x, y, x_size, y_size);
00225
00226 if (overlap == (DynamicTextGlyph *)NULL) {
00227
00228 return true;
00229 }
00230
00231 next_x = overlap->_x + overlap->_x_size;
00232 next_y = min(next_y, overlap->_y + overlap->_y_size);
00233 nassertr(next_x > x, false);
00234 x = next_x;
00235 }
00236
00237 nassertr(next_y > y, false);
00238 y = next_y;
00239 }
00240
00241
00242 return false;
00243 }
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 DynamicTextGlyph *DynamicTextPage::
00257 find_overlap(int x, int y, int x_size, int y_size) const {
00258 Glyphs::const_iterator gi;
00259 for (gi = _glyphs.begin(); gi != _glyphs.end(); ++gi) {
00260 DynamicTextGlyph *glyph = (*gi);
00261 if (glyph->intersects(x, y, x_size, y_size)) {
00262 return glyph;
00263 }
00264 }
00265
00266 return (DynamicTextGlyph *)NULL;
00267 }
00268
00269
00270 #endif // HAVE_FREETYPE