00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "dynamicTextPage.h"
00020 #include "dynamicTextFont.h"
00021
00022 #ifdef HAVE_FREETYPE
00023
00024
00025 TypeHandle DynamicTextPage::_type_handle;
00026
00027
00028
00029
00030
00031
00032 DynamicTextPage::
00033 DynamicTextPage(DynamicTextFont *font) :
00034 _font(font)
00035 {
00036 _x_size = _font->get_page_x_size();
00037 _y_size = _font->get_page_y_size();
00038
00039
00040
00041 _pbuffer = new PixelBuffer(_x_size, _y_size, 1, 1,
00042 PixelBuffer::T_unsigned_byte,
00043 PixelBuffer::F_alpha);
00044 mark_dirty(DF_image);
00045
00046
00047 set_keep_ram_image(true);
00048
00049 set_minfilter(_font->get_minfilter());
00050 set_magfilter(_font->get_magfilter());
00051
00052 set_anisotropic_degree(_font->get_anisotropic_degree());
00053
00054
00055
00056 set_wrapu(WM_clamp);
00057 set_wrapv(WM_clamp);
00058 }
00059
00060
00061
00062
00063
00064
00065
00066
00067 DynamicTextGlyph *DynamicTextPage::
00068 slot_glyph(int x_size, int y_size, int margin) {
00069 int x, y;
00070 if (!find_hole(x, y, x_size, y_size)) {
00071
00072 return (DynamicTextGlyph *)NULL;
00073 }
00074
00075
00076 PT(DynamicTextGlyph) glyph =
00077 new DynamicTextGlyph(this, x, y, x_size, y_size, margin);
00078 _glyphs.push_back(glyph);
00079 return glyph;
00080 }
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 int DynamicTextPage::
00092 garbage_collect() {
00093 int removed_count = 0;
00094
00095 Glyphs new_glyphs;
00096 Glyphs::iterator gi;
00097 for (gi = _glyphs.begin(); gi != _glyphs.end(); ++gi) {
00098 DynamicTextGlyph *glyph = (*gi);
00099 if (glyph->_geom_count != 0) {
00100
00101 new_glyphs.insert(new_glyphs.end(), (*gi));
00102 } else {
00103
00104 removed_count++;
00105 glyph->erase();
00106 }
00107 }
00108
00109 if (removed_count != 0 && DynamicTextFont::get_update_cleared_glyphs()) {
00110
00111
00112 mark_dirty(Texture::DF_image);
00113 }
00114
00115 _glyphs.swap(new_glyphs);
00116 return removed_count;
00117 }
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 bool DynamicTextPage::
00128 find_hole(int &x, int &y, int x_size, int y_size) const {
00129 y = 0;
00130 while (y + y_size <= _y_size) {
00131 int next_y = _y_size;
00132
00133 x = 0;
00134 while (x + x_size <= _x_size) {
00135 int next_x = x;
00136
00137
00138 DynamicTextGlyph *overlap = find_overlap(x, y, x_size, y_size);
00139
00140 if (overlap == (DynamicTextGlyph *)NULL) {
00141
00142 return true;
00143 }
00144
00145 next_x = overlap->_x + overlap->_x_size;
00146 next_y = min(next_y, overlap->_y + overlap->_y_size);
00147 nassertr(next_x > x, false);
00148 x = next_x;
00149 }
00150
00151 nassertr(next_y > y, false);
00152 y = next_y;
00153 }
00154
00155
00156 return false;
00157 }
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 DynamicTextGlyph *DynamicTextPage::
00171 find_overlap(int x, int y, int x_size, int y_size) const {
00172 Glyphs::const_iterator gi;
00173 for (gi = _glyphs.begin(); gi != _glyphs.end(); ++gi) {
00174 DynamicTextGlyph *glyph = (*gi);
00175 if (glyph->intersects(x, y, x_size, y_size)) {
00176 return glyph;
00177 }
00178 }
00179
00180 return (DynamicTextGlyph *)NULL;
00181 }
00182
00183
00184 #endif // HAVE_FREETYPE