open_toontown_panda3d/panda/src/text/dynamicTextGlyph.cxx

178 lines
6.3 KiB
C++

// Filename: dynamicTextGlyph.cxx
// Created by: drose (09Feb02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "dynamicTextGlyph.h"
#ifdef HAVE_FREETYPE
#include "dynamicTextPage.h"
#include "geomTextGlyph.h"
#include "textureAttrib.h"
#include "transparencyAttrib.h"
#include "renderState.h"
#include "textureTransition.h"
#include "transparencyTransition.h"
////////////////////////////////////////////////////////////////////
// Function: DynamicTextGlyph::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
DynamicTextGlyph::
~DynamicTextGlyph() {
}
////////////////////////////////////////////////////////////////////
// Function: DynamicTextGlyph::get_geom
// Access: Public, Virtual
// Description: Returns a Geom that renders the particular glyph.
////////////////////////////////////////////////////////////////////
PT(Geom) DynamicTextGlyph::
get_geom() const {
if (_geom == (Geom *)NULL) {
return _geom;
}
// A DynamicTextGlyph must make a copy of its GeomTextGlyph, so that
// it will increase the reference count properly.
return _geom->make_copy();
}
////////////////////////////////////////////////////////////////////
// Function: DynamicTextGlyph::get_row
// Access: Publiic
// Description: Returns a pointer to the first byte in the pixel
// buffer associated with the leftmost pixel in the
// indicated row, where 0 is the topmost row and _y_size
// - _margin * 2 - 1 is the bottommost row.
////////////////////////////////////////////////////////////////////
unsigned char *DynamicTextGlyph::
get_row(int y) {
nassertr(y >= 0 && y < _y_size - _margin * 2, (unsigned char *)NULL);
nassertr(_page != (DynamicTextPage *)NULL, (unsigned char *)NULL);
nassertr(_page->_pbuffer != (PixelBuffer *)NULL, (unsigned char *)NULL);
// First, offset y by the glyph's start.
y += _y + _margin;
// Also, get the x start.
int x = _x + _margin;
// Invert y.
y = _page->_pbuffer->get_ysize() - 1 - y;
int offset = (y * _page->_pbuffer->get_xsize()) + x;
return _page->_pbuffer->_image + offset;
}
////////////////////////////////////////////////////////////////////
// Function: DynamicTextGlyph::erase
// Access: Publiic
// Description: Erases the glyph from the texture map.
////////////////////////////////////////////////////////////////////
void DynamicTextGlyph::
erase() {
nassertv(_page != (DynamicTextPage *)NULL);
nassertv(_page->_pbuffer != (PixelBuffer *)NULL);
int ysizetop = _page->_pbuffer->get_ysize() - 1;
int xsize = _page->_pbuffer->get_xsize();
unsigned char *buffer = _page->_pbuffer->_image;
for (int y = _y; y < _y + _y_size; y++) {
int offset = (ysizetop - y) * xsize + _x;
memset(buffer + offset, 0, _x_size);
}
}
////////////////////////////////////////////////////////////////////
// Function: DynamicTextGlyph::make_geom
// Access: Publiic
// Description: Creates the actual geometry for the glyph. The
// parameters bitmap_top and bitmap_left are from
// FreeType, and indicate the position of the top left
// corner of the bitmap relative to the glyph's origin.
// The advance number represents the number of pixels
// the pen should be advanced after drawing this glyph.
////////////////////////////////////////////////////////////////////
void DynamicTextGlyph::
make_geom(int bitmap_top, int bitmap_left,
float advance, float poly_margin, float pixels_per_unit) {
nassertv(_page != (DynamicTextPage *)NULL);
// This function should not be called twice.
nassertv(_geom_count == 0);
// Determine the corners of the rectangle in geometric units.
float top = (bitmap_top + poly_margin) / pixels_per_unit;
float left = (bitmap_left - poly_margin) / pixels_per_unit;
float bottom = (bitmap_top - _y_size - poly_margin) / pixels_per_unit;
float right = (bitmap_left + _x_size + poly_margin) / pixels_per_unit;
// And the corresponding corners in UV units.
float uv_top = 1.0f - (float)(_y - poly_margin) / _page->get_y_size();
float uv_left = (float)(_x - poly_margin) / _page->get_x_size();
float uv_bottom = 1.0f - (float)(_y + _y_size + poly_margin) / _page->get_y_size();
float uv_right = (float)(_x + _x_size + poly_margin) / _page->get_x_size();
// Create a corresponding tristrip.
_geom = new GeomTextGlyph(this);
// The above will increment our _geom_count to 1. Reset it back
// down to 0, since our own internal Geom doesn't count.
nassertv(_geom_count == 1);
_geom_count--;
PTA_Vertexf coords;
coords.push_back(Vertexf(left, 0, top));
coords.push_back(Vertexf(left, 0, bottom));
coords.push_back(Vertexf(right, 0, top));
coords.push_back(Vertexf(right, 0, bottom));
PTA_TexCoordf texcoords;
texcoords.push_back(TexCoordf(uv_left, uv_top));
texcoords.push_back(TexCoordf(uv_left, uv_bottom));
texcoords.push_back(TexCoordf(uv_right, uv_top));
texcoords.push_back(TexCoordf(uv_right, uv_bottom));
PTA_Colorf colors;
colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
PTA_int lengths;
lengths.push_back(4);
_geom->set_coords(coords);
_geom->set_texcoords(texcoords, G_PER_VERTEX);
_geom->set_colors(colors, G_OVERALL);
_geom->set_lengths(lengths);
_geom->set_num_prims(1);
TextureTransition *tex = new TextureTransition(_page);
TransparencyTransition *trans = new TransparencyTransition(TransparencyProperty::M_alpha);
_trans.set_transition(tex);
_trans.set_transition(trans);
_state = RenderState::make(TextureAttrib::make(_page),
TransparencyAttrib::make(TransparencyAttrib::M_alpha));
_advance = advance / pixels_per_unit;
}
#endif // HAVE_FREETYPE