Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/text/dynamicTextPage.cxx

Go to the documentation of this file.
00001 // Filename: dynamicTextPage.cxx
00002 // Created by:  drose (09Feb02)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
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 //     Function: DynamicTextPage::Constructor
00029 //       Access: Publiic
00030 //  Description: 
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   // Initialize the Texture to an empty, black (transparent) image of
00040   // the appropriate size.
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   // We'd better never free this image.
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   // It's slightly better to let the texture clamp, rather than
00055   // wrapping, so we're less likely to get bleeding at the edges.
00056   set_wrapu(WM_clamp);
00057   set_wrapv(WM_clamp);
00058 }
00059 
00060 ////////////////////////////////////////////////////////////////////
00061 //     Function: DynamicTextPage::slot_glyph
00062 //       Access: Publiic
00063 //  Description: Finds space within the page for a glyph of the
00064 //               indicated size.  If space is found, creates a new
00065 //               glyph object and returns it; otherwise, returns NULL.
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     // No room for the glyph.
00072     return (DynamicTextGlyph *)NULL;
00073   }
00074 
00075   // The glyph can be fit at (x, y).  Slot it.
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 //     Function: DynamicTextPage::garbage_collect
00084 //       Access: Private
00085 //  Description: Removes all of the glyphs from the page that are no
00086 //               longer being used by any Geoms.  This should only be
00087 //               called from DynamicTextFont::garbage_collect(), since
00088 //               it is important to remove these glyphs from the
00089 //               font's index first.
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       // Keep this one.
00101       new_glyphs.insert(new_glyphs.end(), (*gi));
00102     } else {
00103       // Drop this one.
00104       removed_count++;
00105       glyph->erase();
00106     }
00107   }
00108 
00109   if (removed_count != 0 && DynamicTextFont::get_update_cleared_glyphs()) {
00110     // Only mark the texture dirty if the user specifically requested
00111     // an automatic texture memory update upon clearing glyphs.
00112     mark_dirty(Texture::DF_image);
00113   }
00114 
00115   _glyphs.swap(new_glyphs);
00116   return removed_count;
00117 }
00118 
00119 ////////////////////////////////////////////////////////////////////
00120 //     Function: DynamicTextPage::find_hole
00121 //       Access: Private
00122 //  Description: Searches for a hole of at least x_size by y_size
00123 //               pixels somewhere within the page.  If a suitable hole
00124 //               is found, sets x and y to the top left corner and
00125 //               returns true; otherwise, returns false.
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     // Scan along the row at 'y'.
00133     x = 0;
00134     while (x + x_size <= _x_size) {
00135       int next_x = x;
00136 
00137       // Consider the spot at x, y.
00138       DynamicTextGlyph *overlap = find_overlap(x, y, x_size, y_size);
00139 
00140       if (overlap == (DynamicTextGlyph *)NULL) {
00141         // Hooray!
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   // Nope, wouldn't fit anywhere.
00156   return false;
00157 }
00158 
00159 ////////////////////////////////////////////////////////////////////
00160 //     Function: DynamicTextPage::find_overlap
00161 //       Access: Private
00162 //  Description: If the rectangle whose top left corner is x, y and
00163 //               whose size is x_size, y_size describes an empty hole
00164 //               that does not overlap any placed glyphs, returns
00165 //               NULL; otherwise, returns the first placed glyph
00166 //               that the image does overlap.  It is assumed the
00167 //               rectangle lies completely within the boundaries of
00168 //               the page itself.
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

Generated on Fri May 2 00:44:15 2003 for Panda by doxygen1.3