4444#include " nurbsCurveResult.h"
4545// #include "renderModeAttrib.h"
4646// #include "antialiasAttrib.h"
47+ #include " colorAttrib.h"
48+ #include " textureAttrib.h"
4749
4850TypeHandle DynamicTextFont::_type_handle;
4951
@@ -110,8 +112,7 @@ DynamicTextFont(const DynamicTextFont ©) :
110112 FreetypeFont(copy),
111113 _texture_margin(copy._texture_margin),
112114 _poly_margin(copy._poly_margin),
113- _page_x_size(copy._page_x_size),
114- _page_y_size(copy._page_y_size),
115+ _page_size(copy._page_size),
115116 _minfilter(copy._minfilter),
116117 _magfilter(copy._magfilter),
117118 _anisotropic_degree(copy._anisotropic_degree),
@@ -194,8 +195,8 @@ garbage_collect() {
194195 Cache new_cache;
195196 Cache::iterator ci;
196197 for (ci = _cache.begin (); ci != _cache.end (); ++ci) {
197- DynamicTextGlyph *glyph = (*ci).second ;
198- if (glyph == (DynamicTextGlyph *)NULL || glyph->_geom_count != 0 ) {
198+ TextGlyph *glyph = (*ci).second ;
199+ if (glyph == (TextGlyph *)NULL || glyph->get_ref_count () > 1 ) {
199200 // Keep this one.
200201 new_cache.insert (new_cache.end (), (*ci));
201202 } else {
@@ -252,7 +253,7 @@ write(ostream &out, int indent_level) const {
252253 Cache::const_iterator ci;
253254 for (ci = _cache.begin (); ci != _cache.end (); ++ci) {
254255 int glyph_index = (*ci).first ;
255- DynamicTextGlyph *glyph = (*ci).second ;
256+ TextGlyph *glyph = (*ci).second ;
256257 indent (out, indent_level + 2 )
257258 << glyph_index;
258259
@@ -269,7 +270,7 @@ write(ostream &out, int indent_level) const {
269270 }
270271 release_face (face);
271272
272- out << " , count = " << glyph-> _geom_count << " \n " ;
273+ out << ' \n ' ;
273274 }
274275}
275276
@@ -285,7 +286,7 @@ write(ostream &out, int indent_level) const {
285286// printable glyph.
286287// //////////////////////////////////////////////////////////////////
287288bool DynamicTextFont::
288- get_glyph (int character, const TextGlyph * &glyph) {
289+ get_glyph (int character, CPT( TextGlyph) &glyph) {
289290 if (!_is_valid) {
290291 glyph = (TextGlyph *)NULL ;
291292 return false ;
@@ -302,12 +303,12 @@ get_glyph(int character, const TextGlyph *&glyph) {
302303 if (ci != _cache.end ()) {
303304 glyph = (*ci).second ;
304305 } else {
305- DynamicTextGlyph *dynamic_glyph = make_glyph (character, face, glyph_index);
306+ TextGlyph *dynamic_glyph = make_glyph (character, face, glyph_index);
306307 _cache.insert (Cache::value_type (glyph_index, dynamic_glyph));
307308 glyph = dynamic_glyph;
308309 }
309310
310- if (glyph == (DynamicTextGlyph *)NULL ) {
311+ if (glyph == (TextGlyph *)NULL ) {
311312 glyph = get_invalid_glyph ();
312313 glyph_index = 0 ;
313314 }
@@ -327,8 +328,7 @@ void DynamicTextFont::
327328initialize () {
328329 _texture_margin = text_texture_margin;
329330 _poly_margin = text_poly_margin;
330- _page_x_size = text_page_size[0 ];
331- _page_y_size = text_page_size[1 ];
331+ _page_size.set (text_page_size[0 ], text_page_size[1 ]);
332332
333333 // We don't necessarily want to use mipmaps, since we don't want to
334334 // regenerate those every time the texture changes, but we probably
@@ -442,10 +442,10 @@ determine_tex_format() {
442442// newly-created TextGlyph object, or NULL if the
443443// glyph cannot be created for some reason.
444444// //////////////////////////////////////////////////////////////////
445- DynamicTextGlyph *DynamicTextFont::
445+ TextGlyph *DynamicTextFont::
446446make_glyph (int character, FT_Face face, int glyph_index) {
447447 if (!load_glyph (face, glyph_index, false )) {
448- return (DynamicTextGlyph *)NULL ;
448+ return (TextGlyph *)NULL ;
449449 }
450450
451451 FT_GlyphSlot slot = face->glyph ;
@@ -461,6 +461,7 @@ make_glyph(int character, FT_Face face, int glyph_index) {
461461 }
462462
463463 PN_stdfloat advance = slot->advance .x / 64.0 ;
464+ advance /= _font_pixels_per_unit;
464465
465466 if (_render_mode != RM_texture &&
466467 slot->format == ft_glyph_format_outline) {
@@ -520,8 +521,8 @@ make_glyph(int character, FT_Face face, int glyph_index) {
520521 _contours.clear ();
521522 FT_Outline_Decompose (&slot->outline , &funcs, (void *)this );
522523
523- PT (DynamicTextGlyph ) glyph =
524- new DynamicTextGlyph (character, advance / _font_pixels_per_unit );
524+ PT (TextGlyph ) glyph =
525+ new TextGlyph (character, advance);
525526 switch (_render_mode) {
526527 case RM_wireframe:
527528 render_wireframe_contours (glyph);
@@ -553,8 +554,8 @@ make_glyph(int character, FT_Face face, int glyph_index) {
553554 if (bitmap.width == 0 || bitmap.rows == 0 ) {
554555 // If we got an empty bitmap, it's a special case.
555556
556- PT (DynamicTextGlyph ) glyph =
557- new DynamicTextGlyph (character, advance / _font_pixels_per_unit );
557+ PT (TextGlyph ) glyph =
558+ new TextGlyph (character, advance);
558559 _empty_glyphs.push_back (glyph);
559560 return glyph;
560561
@@ -571,7 +572,7 @@ make_glyph(int character, FT_Face face, int glyph_index) {
571572 // If the bitmap produced from the font doesn't require scaling
572573 // or any other processing before it goes to the texture, we can
573574 // just copy it directly into the texture.
574- glyph = slot_glyph (character, bitmap.width , bitmap.rows );
575+ glyph = slot_glyph (character, bitmap.width , bitmap.rows , advance );
575576 copy_bitmap_to_texture (bitmap, glyph);
576577
577578 } else {
@@ -599,7 +600,7 @@ make_glyph(int character, FT_Face face, int glyph_index) {
599600 int_y_size += outline * 2 ;
600601 tex_x_size += outline * 2 ;
601602 tex_y_size += outline * 2 ;
602- glyph = slot_glyph (character, int_x_size, int_y_size);
603+ glyph = slot_glyph (character, int_x_size, int_y_size, advance );
603604
604605 if (outline != 0 ) {
605606 // Pad the glyph image to make room for the outline.
@@ -612,11 +613,43 @@ make_glyph(int character, FT_Face face, int glyph_index) {
612613 }
613614 }
614615
615- glyph->make_geom ((int )floor (slot->bitmap_top + outline * _scale_factor + 0 .5f ),
616- (int )floor (slot->bitmap_left - outline * _scale_factor + 0 .5f ),
617- advance, _poly_margin,
618- tex_x_size, tex_y_size,
619- _font_pixels_per_unit, _tex_pixels_per_unit);
616+ DynamicTextPage *page = glyph->get_page ();
617+ if (page != NULL ) {
618+ int bitmap_top = (int )floor (slot->bitmap_top + outline * _scale_factor + 0 .5f );
619+ int bitmap_left = (int )floor (slot->bitmap_left - outline * _scale_factor + 0 .5f );
620+
621+ tex_x_size += glyph->_margin * 2 ;
622+ tex_y_size += glyph->_margin * 2 ;
623+
624+ // Determine the corners of the rectangle in geometric units.
625+ PN_stdfloat tex_poly_margin = _poly_margin / _tex_pixels_per_unit;
626+ PN_stdfloat origin_y = bitmap_top / _font_pixels_per_unit;
627+ PN_stdfloat origin_x = bitmap_left / _font_pixels_per_unit;
628+
629+ LVecBase4 dimensions (
630+ origin_x - tex_poly_margin,
631+ origin_y - tex_y_size / _tex_pixels_per_unit - tex_poly_margin,
632+ origin_x + tex_x_size / _tex_pixels_per_unit + tex_poly_margin,
633+ origin_y + tex_poly_margin);
634+
635+ // And the corresponding corners in UV units. We add 0.5f to center
636+ // the UV in the middle of its texel, to minimize roundoff errors
637+ // when we are close to 1-to-1 pixel size.
638+ LVecBase2i page_size = page->get_size ();
639+ LVecBase4 texcoords (
640+ ((PN_stdfloat)(glyph->_x - _poly_margin) + 0 .5f ) / page_size[0 ],
641+ 1 .0f - ((PN_stdfloat)(glyph->_y + _poly_margin + tex_y_size) + 0 .5f ) / page_size[1 ],
642+ ((PN_stdfloat)(glyph->_x + _poly_margin + tex_x_size) + 0 .5f ) / page_size[0 ],
643+ 1 .0f - ((PN_stdfloat)(glyph->_y - _poly_margin) + 0 .5f ) / page_size[1 ]);
644+
645+ CPT (RenderState) state;
646+ state = RenderState::make (TextureAttrib::make (page),
647+ TransparencyAttrib::make (TransparencyAttrib::M_alpha));
648+ state = state->add_attrib (ColorAttrib::make_flat (LColor (1 .0f , 1 .0f , 1 .0f , 1 .0f )), -1 );
649+
650+ glyph->set_quad (dimensions, texcoords, state);
651+ }
652+
620653 return glyph;
621654 }
622655}
@@ -835,7 +868,7 @@ blend_pnmimage_to_texture(const PNMImage &image, DynamicTextGlyph *glyph,
835868// filled in yet except with its size.
836869// //////////////////////////////////////////////////////////////////
837870DynamicTextGlyph *DynamicTextFont::
838- slot_glyph (int character, int x_size, int y_size) {
871+ slot_glyph (int character, int x_size, int y_size, PN_stdfloat advance ) {
839872 // Increase the indicated size by the current margin.
840873 x_size += _texture_margin * 2 ;
841874 y_size += _texture_margin * 2 ;
@@ -850,7 +883,7 @@ slot_glyph(int character, int x_size, int y_size) {
850883
851884 do {
852885 DynamicTextPage *page = _pages[pi];
853- DynamicTextGlyph *glyph = page->slot_glyph (character, x_size, y_size, _texture_margin);
886+ DynamicTextGlyph *glyph = page->slot_glyph (character, x_size, y_size, _texture_margin, advance );
854887 if (glyph != (DynamicTextGlyph *)NULL ) {
855888 // Once we found a page to hold the glyph, that becomes our
856889 // new preferred page.
@@ -874,15 +907,15 @@ slot_glyph(int character, int x_size, int y_size) {
874907 // glyphs?
875908 if (garbage_collect () != 0 ) {
876909 // Yes, we just freed up some space. Try once more, recursively.
877- return slot_glyph (character, x_size, y_size);
910+ return slot_glyph (character, x_size, y_size, advance );
878911
879912 } else {
880913 // No good; all recorded glyphs are actually in use. We need to
881914 // make a new page.
882915 _preferred_page = _pages.size ();
883916 PT (DynamicTextPage) page = new DynamicTextPage (this , _preferred_page);
884917 _pages.push_back (page);
885- return page->slot_glyph (character, x_size, y_size, _texture_margin);
918+ return page->slot_glyph (character, x_size, y_size, _texture_margin, advance );
886919 }
887920}
888921
@@ -893,7 +926,7 @@ slot_glyph(int character, int x_size, int y_size) {
893926// geometry, as a wireframe render.
894927// //////////////////////////////////////////////////////////////////
895928void DynamicTextFont::
896- render_wireframe_contours (DynamicTextGlyph *glyph) {
929+ render_wireframe_contours (TextGlyph *glyph) {
897930 PT (GeomVertexData) vdata = new GeomVertexData
898931 (string (), GeomVertexFormat::get_v3 (),
899932 Geom::UH_static);
@@ -926,7 +959,7 @@ render_wireframe_contours(DynamicTextGlyph *glyph) {
926959// geometry, as a polygon render.
927960// //////////////////////////////////////////////////////////////////
928961void DynamicTextFont::
929- render_polygon_contours (DynamicTextGlyph *glyph, bool face, bool extrude) {
962+ render_polygon_contours (TextGlyph *glyph, bool face, bool extrude) {
930963 PT (GeomVertexData) vdata = new GeomVertexData
931964 (string (), GeomVertexFormat::get_v3n3 (),
932965 Geom::UH_static);
0 commit comments