/*
								+---------------------------------+
								|                                 |
								|    ***   Bitmap font 2   ***    |
								|                                 |
								|  Copyright  © -tHE SWINe- 2007  |
								|                                 |
								|          BitmapFont.h           |
								|                                 |
								+---------------------------------+
*/

#pragma once
#ifndef __FONTENG_INCLUDED
#define __FONTENG_INCLUDED

/**
 *	@file gl2/BitmapFont.h
 *	@author -tHE SWINe-
 *	@date 2007
 *	@brief Bitmap font implementation for OpenGL.
 *
 *	@note This file contains references to FontTexture.cpp (not vice-versa), not including it in
 *		the project will result in link-time errors (unresolved symbols).
 *
 *	@date 2007-06-04
 *
 *	passed code revision
 *
 *	changed bitmap font zoom style so when zoomed to 1 / pixel size, user gets perfectly crisp
 *	letters (in case font rendering functions are passed pixel aligned coordinates)
 *
 *	@date 2007-07-10
 *
 *	added CBitmapFont::SetTextureFilters() to set texture filtering mode in order to improve
 *	rendering of pixel-accurate font
 *
 *	moved function objects sources to BitmapFont.cpp in order to clean-up the header
 *
 *	@date 2007-07-16
 *
 *	updated so now it works with new ÜberLame CGLTexture_2D constructors (texture target
 *	was omitted from constructor parameter list)
 *
 *	added BITMAP_FONT_USE_CLEARTYPE directive for enabling cleartype font support
 *	note (color) cleartype glyphs are converted to greyscale (alpha) but it gives better
 *	results than antialiassed font quality anyway
 *
 *	@date 2007-07-17
 *
 *	added line descent and height font parameters, ie virtual CGLFont::f_LineDescent(),
 *	virtual CGLFont::f_LineHeight() as well as CGLBitmapFont::f_LineDescent() and
 *	CGLBitmapFont::f_LineHeight()
 *
 *	@date 2007-11-10
 *
 *	improved linux compatibility
 *
 *	@date 2007-12-24
 *
 *	improved linux compatibility by adding posix integer types
 *
 *	@date 2008-03-04
 *
 *	now using Integer.h header
 *
 *	@date 2008-08-08
 *
 *	added \#ifdef for windows 64
 *
 *	@date 2008-09-15
 *
 *	added support for anisotropic texture filtering for font textures
 *
 *	@date 2009-01-11
 *
 *	added the geometry padding feature
 *
 *	@date 2009-01-12
 *
 *	fixed CGLBitmapFont::Create() which didn't specify transparent text
 *	background, resulting in texture space waste (loose glyph bounding boxes)
 *
 *	@date 2009-05-04
 *
 *	fixed mixed windows / linux line endings
 *
 *	@date 2009-05-23
 *
 *	removed all instances of std::vector::reserve and replaced them by stl_ut::Reserve_*
 *
 *	@date 2009-10-20
 *
 *	fixed some warnings when compiling under VC 2005, implemented "Security
 *	Enhancements in the CRT" for VC 2008. compare against MyProjects_2009-10-19_
 *
 *	@date 2009-10-26
 *
 *	removed construction and destruction functions from CGLFont (those should not
 *	be speciffied there, just implemented in inherited font classes)
 *
 *	@todo rename CGLFont::Zoom() and CGLFont::f_Zoom() to SetScale() and f_Scale(),
 *		respectively
 *	@todo add horizontal and vertical align flags (vertical is bottom, baseline, top,
 *		horizontal is left, center, right, justify)
 *	@todo add line height (so spacing can be inserted between the lines).
 *	@todo second render string function with line width and height parameters,
 *		may use "justify" horizontal align and automatically insert line breaks
 *		(even with left / right horizontal align - b_single_line flag)
 *	@todo use vertex arrays instead of immediate mode and display lists
 *
 *	@date 2012-06-19
 *
 *	Moved multiple inclusion guard before file documentation comment.
 */

/**
 *	@def BITMAP_FONT_USE_CLEARTYPE
 *
 *	Use cleartype font renderer (windows).
 *
 *	@note Result is converted to greyscale (alpha), but still it gives better results
 *	than antialiassed fonts and maybe even better results than cleartype on rotated LCD.
 */
#define BITMAP_FONT_USE_CLEARTYPE

#include "../Integer.h"
#include "FontTexture.h"

/**
 *	@brief generic OpenGL font renderer interface
 *
 *	Declares a simple interface to be used by applications for font rendering.
 *
 *	@note There are two kinds of length units involved. First, there are fontspace
 *		units, which describe distances in space individual glyphs are defined in.
 *		Fontspace units aren't affected by current font scale, multiplying them by
 *		scale gives screenspace units. Screenspace units are units in OpenGL viewport,
 *		(for example, positions of characters to be rendered are given in screenspace
 *		units, and in turn glTranslatef() gets values in screenspace units as well).
 */
class CGLFont {
public:
	/**
	 *	@brief destructor
	 */
	virtual ~CGLFont()
	{}

	/**
	 *	@brief changes font scale
	 *
	 *	Scales font to f_new_size (not times f_new_size).
	 *
	 *	@param[in] f_new_size is font size (default value is 1)
	 *
	 *	@note Font scale is implementation specific and relative, it doesn't
	 *		count in any unit. Setting pixel size as scale may result in
	 *		sub-pixel accurate filtering in some implementations (bitmap font)
	 *		and therefore, yields better readability.
	 *	@note Actual size of rendered glyphs also depends on current transformation
	 *		matrices.
	 */
	virtual void Zoom(float f_new_size = 1) = 0;

	/**
	 *	@brief returns current font scale
	 *
	 *	Returns current font scale, either set by calling Zoom(), or 1 in case
	 *	Zoom() hasn't been called yet.
	 *
	 *	@return Returns current font scale (default 1).
	 */
	virtual float f_Zoom() const = 0;

	/**
	 *	@brief renders a single character
	 *
	 *	Renders a single character with code n_char to position v_pos. In case n_char
	 *		is not valid character code, renders nothing.
	 *
	 *	@param[in] p_state is OpenGL state guard
	 *	@param[in] v_pos is position of bottom-left character corner
	 *	@param[in] n_char is chracter code
	 *
	 *	@note Character encoding is not specified here, most implementations will
	 *		assume some 8-bit encoding, but for example unicode may be used as well.
	 */
	virtual void Plot_Character(CGLState *p_state, Vector2f v_pos, char n_char) const = 0;

	/**
	 *	@brief renders string
	 *
	 *	Plots string from p_s_string, contaqining n_length characters to position
	 *	v_pos (in case n_length is -1, string is assumed to be null-terminated).
	 *	Characters with invalid (or unknown) codes should be rendered as spaces.
	 *
	 *	@param[in] p_state is OpenGL state guard
	 *	@param[in] v_pos is position of bottom-left character corner
	 *	@param[in] p_s_string is input string to be rendered
	 *	@param[in] n_length is number of characters to be displayed, or -1 in case
	 *		string is null-terminated
	 *
	 *	@note Even if length is supplied, null character before n_length characters
	 *		will be treated as the end of the string, and no more characters will
	 *		be drawn (so using zero as valid character code is impractical here).
	 *	@note This should be faster than calling Plot_Character() in a loop.
	 *	@note Character encoding is not specified here, most implementations will
	 *		assume some 8-bit encoding, but for example unicode may be used as well.
	 */
	virtual void Plot_String(CGLState *p_state, Vector2f v_pos,
		const char *p_s_string, int n_length = -1) const = 0;

	/**
	 *	@brief calculates width of string
	 *
	 *	Calculates width of string p_s_string (in case n_length is -1, string is
	 *		supposed to be null-terminated).
	 *
	 *	@param[in] p_s_string is input string
	 *	@param[in] n_length is number of characters to be displayed, or -1 in case
	 *		string is null-terminated
	 *
	 *	@return Returns width of specified string.
	 *
	 *	@note In case string contains multiple lines of text, length of the longest
	 *		line is returned.
	 *	@note Even if length is supplied, null character before n_length characters
	 *		will be treated as the end of the string, and no more characters will
	 *		be drawn (so using zero as valid character code is impractical here).
	 *	@note Character encoding is not specified here, most implementations will
	 *		assume some 8-bit encoding, but for example unicode may be used as well.
	 */
	virtual float f_StringWidth(const char *p_s_string, int n_length = -1) const = 0;

	/**
	 *	@brief returns line height
	 *
	 *	Returns complete height (in screenspace coordinates) of a single line of text,
	 *		including internal / external leading.
	 *
	 *	@return Returns line height.
	 *
	 *	@note This should be positive (and nonzero) number.
	 *	@note Result is affected by current font scale.
	 */
	virtual float f_LineHeight() const = 0;

	/**
	 *	@brief returns line descent
	 *
	 *	Returns line descent (in screenspace coordinates), that is height of
	 *		character parts under baseline (characters sucha as gjpqy).
	 *
	 *	@return Returns line descent.
	 *
	 *	@note This should be negative number (OpenGL coordinates).
	 *	@note Result is affected by current font scale.
	 */
	virtual float f_LineDescent() const = 0;

	/**
	 *	@brief returns internal leading
	 *
	 *	Returns internal leading (in screenspace coordinates), ie. height of
	 *		punctation marks (this is included in line height).
	 *
	 *	@return Returns internal leading.
	 *
	 *	@note This should be positive number.
	 *	@note Result is affected by current font scale.
	 */
	virtual float f_InternalLeading() const = 0;

	/**
	 *	@brief calculates screenspace offset of last character in a string
	 *
	 *	Calculates offset of n_length-th character from p_s_string (in case
	 *		n_length is -1, p_s_string is supposed to be null-terminated,
	 *		and offset of character next to the last one is returned).
	 *		This is typically used to display cursor in the text.
	 *
	 *	@param[in] p_s_string is input string
	 *	@param[in] n_length is number of characters to be displayed, or -1 in case
	 *		string is null-terminated
	 *
	 *	@return Returns screenspace offset of last character in p_s_string.
	 *
	 *	@todo This doesn't work with justify horizontal align, there must be
	 *		another version of this function, which gets the whole string and
	 *		index of character in it, along with line width and height.
	 *	@note Character offset is vector, pointing from origin after position
	 *		of the last character in the string (for strings, containing just
	 *		a single character, offset vector is Vector2f(character width, 0),
	 *		or, in case that single character is newline, then it's
	 *		Vector2f(0, -line height). for longer strings, character offset is
	 *		sum of character offsets for all characters in the string).
	 *	@note Even if length is supplied, null character before n_length characters
	 *		will be treated as the end of the string, and no more characters will
	 *		be drawn (so using zero as valid character code is impractical here).
	 *	@note Character encoding is not specified here, most implementations will
	 *		assume some 8-bit encoding, but for example unicode may be used as well.
	 */
	virtual Vector2f v_CharacterOffset(const char *p_s_string, int n_length = -1) const = 0;
};

#endif // !__FONTENG_INCLUDED

#ifndef __BITMAP_FONT_INCLUDED
#define __BITMAP_FONT_INCLUDED

/**
 *	@brief OpenGL bitmap font implementation
 *
 *	State-of-art bitmap font for OpenGL. Fonts are stored in bitmaps, containing both
 *	character images and their properties (positions, sizes, additional glyph info).
 *	Information "header" is stored in a small rectangle in bottom-right corner of the
 *	image, allowing for simple editing in any graphics editor, provided the area is
 *	not modified). The next advantage is bitmap font is just a single file, so bitmap
 *	and character properties can't be separated. It is better than storing character
 *	properties in metadata, because some graphical editors may discard metadata, when
 *	storing images (and some graphics formats may have no / limited metadata embedded).
 *
 *	Characters have some padding in texture, allowing use of mip-mapping without
 *	characters bleeding into each other. Part of padding can be rendered, so the
 *	characters may have glow / etc. added to them.
 *
 *	There's maximal texture size constraint, in case characters do not fit inside
 *	a single texture page, more textures are created. Characters are placed using
 *	space-efficient bin-packing algorithm.
 *
 *	In windows, bitmap fonts may be created runtime, by supplying desired font name,
 *	size / etc, and character range.
 *
 *	@note This is currently limited to 8-bit encodings, but implementing unicode
 *		shouldn't be too difficult.
 */
class CGLBitmapFont : public CGLFont {
protected:
	std::vector<TCharacterInfo> m_char_list; /**< list of glyph descriptions */
	std::vector<CGLTexture_2D*> m_texture_list; /**< list of texture pages */
	unsigned char m_n_first_char; /**< first character code */
	unsigned char m_n_char_num; /**< number of character codes */
	int m_n_space_width; /**< width of space (' ') character, in pixels */
	int m_n_newline_height; /**< height of character + internal leading, in pixels */
	int m_n_char_descent;  /**< character descent, in pixels */
	int m_n_int_leading; /**< internal leading, in pixels */
	float m_f_pixel_x /**< pixel width */, m_f_pixel_y; /**< pixel height */
		
	bool m_b_snap_to_pixels; /**< snap to pixels enable flag */

	struct TCharLookup {
		GLuint n_display_list; // draw geometry, shift modelview. no glBegin() or glBindTexture()  
		const TCharacterInfo *p_character;
		CGLTexture_2D *p_tex_page;
	};

	TCharLookup *m_p_char_lookup; /**< list of character lookups, used to render characters using OpenGL */
	float m_f_zoom; /**< current font scale */

	class CSetTextureFilters;
	class CSetTextureAniso;
	class CDeleteObjects;
	template <class CInnerObject> class CDeref;
	class CFindMin_Count;
	class CFillCharLookup;

public:
	/**
	 *	@brief default constructor
	 *
	 *	Initializes blank bitmap font (no characters are specified).
	 */
	CGLBitmapFont();

	/**
	 *	@brief destructor
	 */
	~CGLBitmapFont();

	/**
	 *	@brief enables snapping character positions to integer multiples of pixel size
	 *
	 *	When rendering sub-pixel accurate glyphs, character origins need to be at integer
	 *		multiples of pixel size (otherwise texture coordinates are shifted). While
	 *		this is easy to achieve in new code, it may be tedious to modify legacy code.
	 *		This function enables rounding character positions, passed to Plot_Character()
	 *		and Plot_String() to nearest integer multiple of pixel size.
	 *
	 *	@param[in] f_pixel_width is pixel width in screenspace coordinates
	 *	@param[in] f_pixel_height is pixel height in screenspace coordinates (usualy equals
	 *		to f_pixel_width, or to f_pixel_width times ratio)
	 *
	 *	@note It may be also required to set appropriate texture filtering, use
	 *		SetTextureFilters() function.
	 */
	void EnableSnapToPixels(float f_pixel_width, float f_pixel_height)
	{
		m_f_pixel_x = f_pixel_width;
		m_f_pixel_y = f_pixel_height;
		m_b_snap_to_pixels = true;
	}

	/**
	 *	@brief disables snapping character positions to integer multiples of pixel size
	 *
	 *	When rendering sub-pixel accurate glyphs, character origins need to be at integer
	 *		multiples of pixel size (otherwise texture coordinates are shifted). While
	 *		this is easy to achieve in new code, it may be tedious to modify legacy code.
	 *		This function disables rounding character positions, passed to Plot_Character()
	 *		and Plot_String() to nearest integer multiple of pixel size.
	 *
	 *	@note It may be also required to set appropriate texture filtering, use
	 *		SetTextureFilters() function.
	 */
	void DisableSnapToPixels()
	{
		m_b_snap_to_pixels = false;
	}

	/**
	 *	@brief loads font from a file
	 *
	 *	Loads font from p_s_font_name bitmap (or more bitmaps), images must currently
	 *		be in targa format. In case p_s_font_name ends with "_page00.tga", there
	 *		must me at least one more page with characters (ie. "_page01.tga").
	 *
	 *	@param[in] p_state is OpenGL state manager (new textures are created)
	 *	@param[in] p_s_font_name is filename of (the first) file, contaning bitmap
	 *		font page
	 *
	 *	@return Returns true on success, false on failure.
	 */
	virtual bool Load(CGLState *p_state, const char *p_s_font_name);

#ifdef FONT_TEXTURE_CREATE_FONTS

	/**
	 *	@brief creates bitmap font on the fly
	 *
	 *	Creates bitmap font at runtime. Old font is discarded.
	 *
	 *	@param[in] p_state is OpenGL state manager (new textures are created). In case
	 *		requested font is not found, default system font is used instead.
	 *	@param[in] p_s_font_face is name of font face (for example "Arial")
	 *	@param[in] n_font_size is font size in pixels (equals to height of characters
	 *		without descent)
	 *	@param[in] n_font_weight is font weight, 400 is "normal", 800 is "bold"
	 *	@param[in] b_italic is italic flag (setting it yields italic font)
	 *	@param[in] b_underline is underline flag (setting it yields underlined font)
	 *	@param[in] n_char_padding is size of character padding in pixels, should be at
	 *		least 1 to prevent bleeding of different characters into each other.
	 *	@param[in] n_geom_padding is additional padding, included in character quad
	 *		(rendered along with character). It has little sense using geometry padding
	 *		as it would only waste fillrate, unless using shader to render characters,
	 *
	 *	@return Returns true on success, false on failure.
	 *
	 *	@note This is only available under windows, would have to use complex
	 *		external libraries in linux (which is unacceptable in ÜberLame).
	 *		Linux users should be able to run bitmap font builder tool from wine
	 *		to obtain bitmap font images, which can be loaded in any OS.
	 */
	virtual bool Create(CGLState *p_state, const char *p_s_font_face, int n_font_size,
		int n_font_weight = 400, bool b_italic = false, bool b_underline = false,
		int n_char_padding = 4, int n_geom_padding = 0);

#endif // FONT_TEXTURE_CREATE_FONTS

	/**
	 *	@brief deletes font description
	 *
	 *	Deletes all character descriptions, font is in the same state, as after
	 *	constructor, and before calling Load() or Create(). (no characters are specified
	 *	and rendering will have no output)
	 */
	virtual void Free();

	/**
	 *	@brief sets texture filtering mode
	 *
	 *	Sets texture minification filter to n_min_filter and maginification filter to n_mag_filter.
	 *
	 *	@param[in] p_state is OpenGL state manager
	 *	@param[in] n_min_filter is minification filter name (one of GL_NEAREST, GL_LINEAR,
	 *		GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_NEAREST,
	 *		GL_LINEAR_MIPMAP_LINEAR)
	 *	@param[in] n_mag_filter is maginification filter name (GL_NEAREST or GL_LINEAR)
	 *
	 *	@note Useful for setting GL_NEAREST filtering for sub-pixel accurate font rendering.
	 */
	void SetTextureFilters(CGLState *p_state, GLenum n_min_filter = GL_LINEAR_MIPMAP_LINEAR,
		GLenum n_mag_filter = GL_LINEAR);

	/**
	 *	@brief sets anisotropic texture filtering mode
	 *
	 *	
	 *	@param[in] p_state is OpenGL state manager
	 *	@param[in] f_anisotropy is filter anisotropy (1 = disabled)
	 *
	 *	@note Useful when fonts are rendered in 3D environment and viewed under angle.
	 *	@note To determine maximal anisotropy available, use:
	 *@code
	 *	float f_max_aniso;
	 *	glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &f_max_aniso);
	 *	font.SetTextureAnisotropy(p_state, f_max_aniso);
	 *@endcode
	 *	You may want to check if @c GL_EXT_texture_filter_anisotropic extension
	 *	is supported by OpenGL (no errors are generated, but this function won't
	 *	have any effect if it isn't).
	 */
	void SetTextureAnisotropy(CGLState *p_state, float f_anisotropy);

	/**
	 *	@brief changes font scale
	 *
	 *	Scales font to f_new_size (not times f_new_size). Bitmap fonts fontspace sizes
	 *	are in pixels, converting it to OpenGL coordinates require proper scaling.
	 *	Setting screenspace pixel size as scale results in sub-pixel accurate rendering,
	 *	yielding better readability. Nearest texture filter (SetTextureFilters()) and
	 *	coordinate snap (EnableSnapToPixels()) might be needed as well.
	 *
	 *	@param[in] f_new_size is font size (default value is 1)
	 *
	 *	@note Default font scale of 1 is too large in normalized OpenGL coordinates,
	 *		most characters will not be visible when rendered like that (common error
	 *		when using CGLBitmapFont the first time).
	 *	@note Actual size of rendered glyphs also depends on current transformation
	 *		matrices.
	 */
	virtual void Zoom(float f_new_size = 1);

	/**
	 *	@brief returns current font scale
	 *
	 *	Returns current font scale, either set by calling Zoom(), or 1 in case
	 *	Zoom() hasn't been called yet.
	 *
	 *	@return Returns current font scale (default 1).
	 */
	virtual float f_Zoom() const;

	/**
	 *	@brief renders a single character
	 *
	 *	Renders a single character with code n_char to position v_pos. In case n_char
	 *		is not valid character code, renders nothing.
	 *
	 *	@param[in] p_state is OpenGL state guard
	 *	@param[in] v_pos is position of bottom-left character corner. In case snap to
	 *		pixels is enabled (using EnableSnapToPixels()), this position is modified
	 *		accordingly.
	 *	@param[in] n_char is chracter code
	 *
	 *	@note Character encoding is not specified here, most implementations will
	 *		assume some 8-bit encoding, but for example unicode may be used as well.
	 */
	virtual void Plot_Character(CGLState *p_state, Vector2f v_pos, char n_char) const;

	/**
	 *	@brief renders string
	 *
	 *	Plots string from p_s_string, contaqining n_length characters to position
	 *	v_pos (in case n_length is -1, string is assumed to be null-terminated).
	 *	Characters with invalid (or unknown) codes should be rendered as spaces.
	 *
	 *	@param[in] p_state is OpenGL state guard
	 *	@param[in] v_pos is position of bottom-left character corner. In case snap to
	 *		pixels is enabled (using EnableSnapToPixels()), this position is modified
	 *		accordingly.
	 *	@param[in] p_s_string is input string to be rendered
	 *	@param[in] n_length is number of characters to be displayed, or -1 in case
	 *		string is null-terminated
	 *
	 *	@note Even if length is supplied, null character before n_length characters
	 *		will be treated as the end of the string, and no more characters will
	 *		be drawn (so using zero as valid character code is impractical here).
	 *	@note This should be faster than calling Plot_Character() in a loop.
	 *	@note Character encoding is not specified here, most implementations will
	 *		assume some 8-bit encoding, but for example unicode may be used as well.
	 */
	virtual void Plot_String(CGLState *p_state, Vector2f v_pos,
		const char *p_s_string, int n_length = -1) const;

	/**
	 *	@brief calculates width of string
	 *
	 *	Calculates width of string p_s_string (in case n_length is -1, string is
	 *		supposed to be null-terminated).
	 *
	 *	@param[in] p_s_string is input string
	 *	@param[in] n_length is number of characters to be displayed, or -1 in case
	 *		string is null-terminated
	 *
	 *	@return Returns width of specified string.
	 *
	 *	@note In case string contains multiple lines of text, length of the longest
	 *		line is returned.
	 *	@note Even if length is supplied, null character before n_length characters
	 *		will be treated as the end of the string, and no more characters will
	 *		be drawn (so using zero as valid character code is impractical here).
	 *	@note Character encoding is not specified here, most implementations will
	 *		assume some 8-bit encoding, but for example unicode may be used as well.
	 */
	virtual float f_StringWidth(const char *p_s_string, int n_length = -1) const;

	/**
	 *	@brief returns line height
	 *
	 *	Returns complete height (in screenspace coordinates) of a single line of text,
	 *		including internal / external leading.
	 *
	 *	@return Returns line height.
	 *
	 *	@note This should be positive (and nonzero) number.
	 *	@note Result is affected by current font scale.
	 */
	virtual float f_LineHeight() const;

	/**
	 *	@brief returns line descent
	 *
	 *	Returns line descent (in screenspace coordinates), that is height of
	 *		character parts under baseline (characters sucha as gjpqy).
	 *
	 *	@return Returns line descent.
	 *
	 *	@note This should be negative number (OpenGL coordinates).
	 *	@note Result is affected by current font scale.
	 */
	virtual float f_LineDescent() const;

	/**
	 *	@brief returns internal leading
	 *
	 *	Returns internal leading (in screenspace coordinates), ie. height of
	 *		punctation marks (this is included in line height).
	 *
	 *	@return Returns internal leading.
	 *
	 *	@note This should be positive number.
	 *	@note Result is affected by current font scale.
	 */
	virtual float f_InternalLeading() const;

	/**
	 *	@brief calculates screenspace offset of last character in a string
	 *
	 *	Calculates offset of n_length-th character from p_s_string (in case
	 *		n_length is -1, p_s_string is supposed to be null-terminated,
	 *		and offset of character next to the last one is returned).
	 *		This is typically used to display cursor in the text.
	 *
	 *	@param[in] p_s_string is input string
	 *	@param[in] n_length is number of characters to be displayed, or -1 in case
	 *		string is null-terminated
	 *
	 *	@return Returns screenspace offset of last character in p_s_string.
	 *
	 *	@todo This doesn't work with justify horizontal align, there must be
	 *		another version of this function, which gets the whole string and
	 *		index of character in it, along with line width and height.
	 *	@note Character offset is vector, pointing from origin after position
	 *		of the last character in the string (for strings, containing just
	 *		a single character, offset vector is Vector2f(character width, 0),
	 *		or, in case that single character is newline, then it's
	 *		Vector2f(0, -line height). for longer strings, character offset is
	 *		sum of character offsets for all characters in the string).
	 *	@note Even if length is supplied, null character before n_length characters
	 *		will be treated as the end of the string, and no more characters will
	 *		be drawn (so using zero as valid character code is impractical here).
	 *	@note Character encoding is not specified here, most implementations will
	 *		assume some 8-bit encoding, but for example unicode may be used as well.
	 */
	virtual Vector2f v_CharacterOffset(const char *p_s_string, int n_length = -1) const;

protected:
	int n_Load_Page(const char *p_s_file_name, CGLState *p_state, int &r_n_geom_padding);
};

#endif // !__BITMAP_FONT_INCLUDED
