glbitmapfont.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:28k
- /*
- * ===========================================================================
- * PRODUCTION $Log: glbitmapfont.cpp,v $
- * PRODUCTION Revision 1000.3 2004/06/01 20:50:25 gouriano
- * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.20
- * PRODUCTION
- * ===========================================================================
- */
- /* $Id: glbitmapfont.cpp,v 1000.3 2004/06/01 20:50:25 gouriano Exp $
- * ===========================================================================
- *
- * PUBLIC DOMAIN NOTICE
- * National Center for Biotechnology Information
- *
- * This software/database is a "United States Government Work" under the
- * terms of the United States Copyright Act. It was written as part of
- * the author's official duties as a United States Government employee and
- * thus cannot be copyrighted. This software/database is freely available
- * to the public for use. The National Library of Medicine and the U.S.
- * Government have not placed any restriction on its use or reproduction.
- *
- * Although all reasonable efforts have been taken to ensure the accuracy
- * and reliability of the software and data, the NLM and the U.S.
- * Government do not and cannot warrant the performance or results that
- * may be obtained by using this software or data. The NLM and the U.S.
- * Government disclaim all warranties, express or implied, including
- * warranties of performance, merchantability or fitness for any particular
- * purpose.
- *
- * Please cite the author in any work or product based on this material.
- *
- * ===========================================================================
- *
- * Authors: Mike DiCuccio
- *
- * File Description:
- *
- */
- #include <ncbi_pch.hpp>
- #include <gui/opengl/glbitmapfont.hpp>
- #include <gui/opengl/gldlist.hpp>
- #include "glutbitmap.h"
- #include <math.h>
- #include <stdio.h>
- #include <util/static_map.hpp>
- extern "C" {
- // clean fonts
- extern BitmapFontRec ncbi_clean_6;
- extern BitmapFontRec ncbi_clean_8;
- extern BitmapFontRec ncbi_clean_10;
- extern BitmapFontRec ncbi_clean_12;
- extern BitmapFontRec ncbi_clean_13;
- extern BitmapFontRec ncbi_clean_14;
- extern BitmapFontRec ncbi_clean_15;
- extern BitmapFontRec ncbi_clean_16;
- // courier fonts
- extern BitmapFontRec ncbi_courier_6;
- extern BitmapFontRec ncbi_courier_8;
- extern BitmapFontRec ncbi_courier_10;
- extern BitmapFontRec ncbi_courier_12;
- extern BitmapFontRec ncbi_courier_14;
- extern BitmapFontRec ncbi_courier_18;
- extern BitmapFontRec ncbi_courier_20;
- extern BitmapFontRec ncbi_courier_24;
- // fixed size fonts
- extern BitmapFontRec ncbi_fixed_6;
- extern BitmapFontRec ncbi_fixed_8;
- extern BitmapFontRec ncbi_fixed_10;
- extern BitmapFontRec ncbi_fixed_12;
- extern BitmapFontRec ncbi_fixed_14;
- extern BitmapFontRec ncbi_fixed_18;
- extern BitmapFontRec ncbi_fixed_20;
- extern BitmapFontRec ncbi_fixed_20;
- // helvetica fonts
- extern BitmapFontRec ncbi_helvetica_6;
- extern BitmapFontRec ncbi_helvetica_8;
- extern BitmapFontRec ncbi_helvetica_10;
- extern BitmapFontRec ncbi_helvetica_12;
- extern BitmapFontRec ncbi_helvetica_14;
- extern BitmapFontRec ncbi_helvetica_18;
- extern BitmapFontRec ncbi_helvetica_20;
- extern BitmapFontRec ncbi_helvetica_24;
- // ludica fonts
- extern BitmapFontRec ncbi_lucida_6;
- extern BitmapFontRec ncbi_lucida_8;
- extern BitmapFontRec ncbi_lucida_10;
- extern BitmapFontRec ncbi_lucida_12;
- extern BitmapFontRec ncbi_lucida_14;
- extern BitmapFontRec ncbi_lucida_18;
- extern BitmapFontRec ncbi_lucida_20;
- extern BitmapFontRec ncbi_lucida_24;
- // times fonts
- extern BitmapFontRec ncbi_times_6;
- extern BitmapFontRec ncbi_times_8;
- extern BitmapFontRec ncbi_times_10;
- extern BitmapFontRec ncbi_times_12;
- extern BitmapFontRec ncbi_times_14;
- extern BitmapFontRec ncbi_times_18;
- extern BitmapFontRec ncbi_times_20;
- extern BitmapFontRec ncbi_times_24;
- }
- BEGIN_NCBI_SCOPE
- typedef pair<CGlBitmapFont::EFont, BitmapFontPtr> TFontPair;
- static const TFontPair sc_Fonts[] = {
- TFontPair(CGlBitmapFont::eBitmap5x7, &ncbi_fixed_8),
- TFontPair(CGlBitmapFont::eBitmap8x13, &ncbi_fixed_12),
- TFontPair(CGlBitmapFont::eBitmap9x15, &ncbi_fixed_14),
- TFontPair(CGlBitmapFont::eBitmap10x20, &ncbi_fixed_18),
- TFontPair(CGlBitmapFont::eBitmap12x24, &ncbi_fixed_20),
- TFontPair(CGlBitmapFont::eHelvetica6, &ncbi_helvetica_6),
- TFontPair(CGlBitmapFont::eHelvetica8, &ncbi_helvetica_8),
- TFontPair(CGlBitmapFont::eHelvetica10, &ncbi_helvetica_10),
- TFontPair(CGlBitmapFont::eHelvetica12, &ncbi_helvetica_12),
- TFontPair(CGlBitmapFont::eHelvetica14, &ncbi_helvetica_14),
- TFontPair(CGlBitmapFont::eHelvetica18, &ncbi_helvetica_18),
- TFontPair(CGlBitmapFont::eHelvetica20, &ncbi_helvetica_20),
- TFontPair(CGlBitmapFont::eHelvetica24, &ncbi_helvetica_24),
- TFontPair(CGlBitmapFont::eLucida6, &ncbi_lucida_6),
- TFontPair(CGlBitmapFont::eLucida8, &ncbi_lucida_8),
- TFontPair(CGlBitmapFont::eLucida10, &ncbi_lucida_10),
- TFontPair(CGlBitmapFont::eLucida12, &ncbi_lucida_12),
- TFontPair(CGlBitmapFont::eLucida14, &ncbi_lucida_14),
- TFontPair(CGlBitmapFont::eLucida18, &ncbi_lucida_18),
- TFontPair(CGlBitmapFont::eLucida20, &ncbi_lucida_20),
- TFontPair(CGlBitmapFont::eLucida24, &ncbi_lucida_24),
- TFontPair(CGlBitmapFont::eCourier6, &ncbi_courier_6),
- TFontPair(CGlBitmapFont::eCourier8, &ncbi_courier_8),
- TFontPair(CGlBitmapFont::eCourier10, &ncbi_courier_10),
- TFontPair(CGlBitmapFont::eCourier12, &ncbi_courier_12),
- TFontPair(CGlBitmapFont::eCourier14, &ncbi_courier_14),
- TFontPair(CGlBitmapFont::eCourier18, &ncbi_courier_18),
- TFontPair(CGlBitmapFont::eCourier20, &ncbi_courier_20),
- TFontPair(CGlBitmapFont::eCourier24, &ncbi_courier_24),
- TFontPair(CGlBitmapFont::eClean6, &ncbi_clean_6),
- TFontPair(CGlBitmapFont::eClean8, &ncbi_clean_8),
- TFontPair(CGlBitmapFont::eClean10, &ncbi_clean_10),
- TFontPair(CGlBitmapFont::eClean12, &ncbi_clean_12),
- TFontPair(CGlBitmapFont::eClean14, &ncbi_clean_13),
- TFontPair(CGlBitmapFont::eClean18, &ncbi_clean_14),
- TFontPair(CGlBitmapFont::eClean20, &ncbi_clean_15),
- TFontPair(CGlBitmapFont::eClean24, &ncbi_clean_16),
- TFontPair(CGlBitmapFont::eFixed8, &ncbi_fixed_8),
- TFontPair(CGlBitmapFont::eFixed10, &ncbi_fixed_10),
- TFontPair(CGlBitmapFont::eFixed12, &ncbi_fixed_12),
- TFontPair(CGlBitmapFont::eFixed14, &ncbi_fixed_14),
- TFontPair(CGlBitmapFont::eFixed18, &ncbi_fixed_18),
- TFontPair(CGlBitmapFont::eFixed20, &ncbi_fixed_20),
- TFontPair(CGlBitmapFont::eTimesRoman6, &ncbi_times_6),
- TFontPair(CGlBitmapFont::eTimesRoman8, &ncbi_times_8),
- TFontPair(CGlBitmapFont::eTimesRoman10, &ncbi_times_10),
- TFontPair(CGlBitmapFont::eTimesRoman12, &ncbi_times_12),
- TFontPair(CGlBitmapFont::eTimesRoman14, &ncbi_times_14),
- TFontPair(CGlBitmapFont::eTimesRoman18, &ncbi_times_18),
- TFontPair(CGlBitmapFont::eTimesRoman20, &ncbi_times_20),
- TFontPair(CGlBitmapFont::eTimesRoman24, &ncbi_times_24)
- };
- typedef CStaticArrayMap<CGlBitmapFont::EFont, BitmapFontPtr> TFontMap;
- static const TFontMap sc_FontMap(sc_Fonts, sizeof (sc_Fonts));
- static inline
- const BitmapFontPtr s_GetFont(CGlBitmapFont::EFont font)
- {
- TFontMap::const_iterator iter = sc_FontMap.lower_bound(font);
- if (iter->first == font) {
- // exact match
- return iter->second;
- } else if (iter->first != font) {
- // probably off by size
- CGlBitmapFont::EFontFace face =
- static_cast<CGlBitmapFont::EFontFace>
- (font & 0xff);
- CGlBitmapFont::EFontFace this_face =
- static_cast<CGlBitmapFont::EFontFace>
- (iter->first & 0xff);
- if (this_face == face) {
- // faces match, return font
- return iter->second;
- } else {
- // faces don't match
- // we need to jump forward or back to get the right face
- TFontMap::const_iterator back = iter;
- TFontMap::const_iterator forward = iter;
- for ( ;
- back != sc_FontMap.begin() &&
- forward != sc_FontMap.end(); ) {
- if (back != sc_FontMap.begin()) {
- CGlBitmapFont::EFontFace this_face =
- static_cast<CGlBitmapFont::EFontFace>
- (back->first & 0xff);
- if (this_face == face) {
- return back->second;
- }
- --back;
- }
- if (forward != sc_FontMap.end()) {
- CGlBitmapFont::EFontFace this_face =
- static_cast<CGlBitmapFont::EFontFace>
- (forward->first & 0xff);
- if (this_face == face) {
- return forward->second;
- }
- ++forward;
- }
- }
- }
- }
- NCBI_THROW(CException, eUnknown, "gl font not found");
- }
- //
- // return the width of a single character
- // this is really the *advance* of a character
- //
- static float s_GetCharAdvance(char c, const BitmapFontRec* font_ptr)
- {
- if (c < font_ptr->first ||
- c >= font_ptr->first + font_ptr->num_chars) {
- return 0.0f;
- }
- const BitmapCharRec *ch = font_ptr->ch[c - font_ptr->first];
- if ( !ch ) {
- return 0.0f;
- }
- return ch->advance;
- }
- static float s_GetCharWidth(char c, const BitmapFontRec* font_ptr)
- {
- if (c < font_ptr->first ||
- c >= font_ptr->first + font_ptr->num_chars) {
- return 0.0f;
- }
- const BitmapCharRec *ch = font_ptr->ch[c - font_ptr->first];
- if ( !ch ) {
- return 0.0f;
- }
- return (float)ch->width;
- }
- CGlBitmapFont::CGlBitmapFont()
- : m_Font(eBitmap8x13)
- {
- SetFont(eBitmap8x13);
- }
- CGlBitmapFont::CGlBitmapFont(EFont font)
- : m_Font(font)
- {
- SetFont(font);
- }
- CGlBitmapFont::~CGlBitmapFont()
- {
- }
- void CGlBitmapFont::SetFontFace(EFontFace face)
- {
- EFont font = static_cast<EFont>((m_Font & 0xff) | face);
- SetFont(font);
- }
- void CGlBitmapFont::SetFontSize(EFontSize size)
- {
- EFont font = static_cast<EFont>((m_Font & ~0xff) | size);
- SetFont(font);
- }
- void CGlBitmapFont::SetFont(EFont font)
- {
- if (font != m_Font) {
- m_Font = font;
- // we must also invalidate all of our display lists
- // this may be expensive, as it forces regeneration of display
- // lists the next time we render any characters
- for (int i = 0; i < 256; ++i) {
- if (m_Chars[i]) {
- m_Chars[i]->Invalidate();
- }
- }
- }
- }
- template<class TOutputMethod>
- void DoTextOut(TOutputMethod& method)
- {
- // save a bunch of states
- GLint swapbytes;
- GLint lsbfirst;
- GLint rowlength;
- GLint skiprows;
- GLint skippixels;
- GLint alignment;
- glGetIntegerv(GL_UNPACK_SWAP_BYTES, &swapbytes);
- glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsbfirst);
- glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowlength);
- glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skiprows);
- glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skippixels);
- glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
- glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
- glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- // render our text
- method();
- // restore states
- glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes);
- glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels);
- glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
- }
- class CTextPrinter
- {
- public:
- CTextPrinter(const char* text, const BitmapFontPtr& font_ptr)
- : m_Text(text),
- m_FontPtr(font_ptr)
- {
- }
- void operator()()
- {
- for (const char* p = m_Text; p && *p; ++p) {
- if (*p < m_FontPtr->first ||
- *p >= m_FontPtr->first + m_FontPtr->num_chars) {
- continue;
- }
- const BitmapCharRec *ch = m_FontPtr->ch[*p - m_FontPtr->first];
- if (ch ) {
- glBitmap(ch->width, ch->height, ch->xorig, ch->yorig,
- ch->advance, 0, ch->bitmap);
- }
- }
- };
- protected:
- const char* m_Text;
- const BitmapFontPtr& m_FontPtr;
- };
- //
- // TextOut()
- // This version performs most of the low-level work. It simply
- // outputs text at a previously determined raster position
- //
- void CGlBitmapFont::TextOut(const char* text) const
- {
- GLint mode;
- glGetIntegerv(GL_RENDER_MODE, &mode);
- switch (mode) {
- case GL_FEEDBACK:
- {{
- GLfloat pos[4];
- GLfloat col[4];
- glGetFloatv(GL_CURRENT_RASTER_POSITION, pos);
- glGetFloatv(GL_CURRENT_RASTER_COLOR, col);
- const CGlColor c(col, 4);
- typedef vector<float> TFList;
- TFList vectext =
- CGlFeedbackFont::EncodeText(pos, c, text, strlen(text));
- ITERATE (TFList, it, vectext) {
- glPassThrough(*it);
- }
- }}
- break;
- default:
- {{
- // first, retrieve our OpenGL font
- const BitmapFontPtr font_ptr = s_GetFont(m_Font);
- CTextPrinter printer(text, font_ptr);
- DoTextOut(printer);
- }}
- break;
- }
- }
- class CTextArrayPrinter
- {
- public:
- CTextArrayPrinter(const char* text,
- float x, float y, float dx, float dy,
- float scale_x, float scale_y,
- const BitmapFontPtr& font_ptr)
- : m_Text(text),
- m_X(x),
- m_Y(y),
- m_dX(dx),
- m_dY(dy),
- m_ScaleX(scale_x),
- m_ScaleY(scale_y),
- m_FontPtr(font_ptr)
- {
- }
- void operator()()
- {
- float k_x = m_ScaleX / 2;
- float k_y = m_ScaleY / 2;
- for (const char* p = m_Text; p && *p; ++p) {
- if (*p < m_FontPtr->first ||
- *p >= m_FontPtr->first + m_FontPtr->num_chars) {
- continue;
- }
- const BitmapCharRec *ch = m_FontPtr->ch[*p - m_FontPtr->first];
- if (ch ) {
- int ind = p - m_Text;
- float pos_x = m_X + ind * m_dX;
- float pos_y = m_Y + ind * m_dY;
- float off_x = ch->width * k_x; // to current coord system
- float off_y = ch->height * k_y; // to current coord system
-
- glRasterPos2f(pos_x - off_x, pos_y - off_y);
- glBitmap(ch->width, ch->height, ch->xorig, ch->yorig,
- 0, 0, ch->bitmap);
- /**
- if ( !m_Chars[*p] ) {
- m_Chars[*p].Reset(new CGlDisplayList());
- }
- if (m_Chars[*p]->IsValid()) {
- m_Chars[*p]->Call();
- } else {
- CGlDisplayListCompile COMPILE(*m_Chars[*p],
- GL_COMPILE_AND_EXECUTE);
- glBitmap(ch->width, ch->height, ch->xorig, ch->yorig,
- ch->advance, 0, ch->bitmap);
- }
- **/
- }
- }
- };
- protected:
- const char* m_Text;
- float m_X, m_Y;
- float m_dX, m_dY;
- float m_ScaleX, m_ScaleY;
- const BitmapFontPtr& m_FontPtr;
- };
- void CGlBitmapFont::ArrayTextOut(float x, float y, float dx, float dy, const char* text,
- float scale_x, float scale_y) const
- {
- GLint mode;
- glGetIntegerv(GL_RENDER_MODE, &mode);
- switch (mode) {
- case GL_FEEDBACK:
- {{
- _ASSERT(false); // not implemented yet
- }}
- break;
- default:
- {{
- // first, retrieve our OpenGL font
- const BitmapFontPtr font_ptr = s_GetFont(m_Font);
- CTextArrayPrinter printer(text, x, y, dx, dy, scale_x, scale_y, font_ptr);
- DoTextOut(printer);
- }}
- break;
- }
- }
- //
- // TextOut()
- // This version performs some label alignment in the specified box
- //
- void CGlBitmapFont::TextOut(float x, float y, float w, float h,
- const char* text, int align,
- ETruncate trunc) const
- {
- string str;
- switch (trunc) {
- case eTruncate_None:
- str = text;
- break;
- case eTruncate_Empty:
- case eTruncate_Ellipsis:
- x_Truncate(text, w, trunc, &str);
- break;
- }
-
- float ras_x, ras_y;
- // FL_ALIGN_RIGHT or FL_ALIGN_CENTER are applied to horz position only if
- // FL_ALIGN_LEFT is not specifed
- if(align & FL_ALIGN_LEFT) {
- ras_x = x;
- } else if (align & FL_ALIGN_RIGHT) { // right justify
- float text_wid = TextWidth(str.c_str());
- ras_x = x + (w - text_wid);
- } else { // center
- float text_wid = TextWidth(str.c_str());
- ras_x = x + (w - text_wid) * 0.5f;
- }
- if (align & FL_ALIGN_BOTTOM) {
- ras_y = y;
- } else if (align & FL_ALIGN_TOP) { // skip down enough to keep our text inside
- float text_ht = TextHeight();
- ras_y = y + h - text_ht;
- } else { // if nothing given or FL_ALIGN_CENTER is specified - center vertically
- float text_ht = TextHeight();
- ras_y = y + (h - text_ht) * 0.5f;
- }
-
- TextOut(ras_x, ras_y, str.c_str());
- }
- void CGlBitmapFont::TextOut(float x, float y, const char* text) const
- {
- glRasterPos2f(x, y);
- TextOut(text);
- }
- //
- // compute the width of a string of characters
- // this will count out at most n characters, stopping on a null
- // note that the comparison function used for 'n' is 0 or non-zero -
- // so passing '-1' for 'n' means 'compute until a null character is found'
- // This allows us to avoid calling strlen()
- //
- float CGlBitmapFont::TextWidth(const char* text, int n) const
- {
- return GetMetric(eMetric_TextWidth, text, n);
- }
- //
- // compute the length of a null-terminated string
- //
- float CGlBitmapFont::TextWidth(const char* text) const
- {
- return GetMetric(eMetric_TextWidth, text);
- }
- //
- // compute the height of a string
- //
- float CGlBitmapFont::TextHeight(void) const
- {
- return GetMetric(eMetric_CharHeight);
- }
- //
- // generic text metric retrieval
- //
- float CGlBitmapFont::GetMetric(EMetric metric,
- const char* text, int text_len) const
- {
- // first, retrieve our OpenGL font
- const BitmapFontRec* font_ptr = s_GetFont(m_Font);
- switch (metric) {
- case eMetric_CharHeight:
- //
- // return the height of a capital letter
- //
- {{
- // we first scan the capital letters
- // this gives us the height of the text without descents but with
- // ascents
- static const char* sc_caps = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- GLsizei max_ht = 0;
- for (const char* p = sc_caps; p && *p; ++p) {
- const BitmapCharRec *ch = font_ptr->ch[*p - font_ptr->first];
- if ( !ch ) {
- continue;
- }
- GLsizei ht = GLsizei(ch->height - ch->yorig);
- max_ht = max(max_ht, ht);
- }
- return (float)max_ht;
- }}
- case eMetric_FullCharHeight:
- //
- // return the maximal height of all available characters
- //
- {{
- // we first scan the capital letters
- // this gives us the height of the text without descents but with
- // ascents
- GLsizei max_ht = 0;
- for (int i = font_ptr->first; i < font_ptr->num_chars; ++i) {
- const BitmapCharRec *ch = font_ptr->ch[i];
- if ( !ch ) {
- continue;
- }
- GLsizei ht = GLsizei(ch->height - ch->yorig);
- max_ht = max(max_ht, ht);
- }
- return (float)max_ht;
- }}
- case eMetric_AvgCharWidth:
- //
- // return the maximal height of all available characters
- //
- {{
- // we first scan the capital letters
- // this gives us the height of the text without descents but with
- // ascents
- GLfloat wid = 0;
- GLsizei count = 0;
- for (int i = font_ptr->first; i < font_ptr->num_chars; ++i) {
- const BitmapCharRec *ch = font_ptr->ch[i];
- if ( !ch ) {
- continue;
- }
- wid += ch->advance;
- ++count;
- }
- return wid / float(count);
- }}
- case eMetric_MaxCharWidth:
- //
- // return the maximal height of all available characters
- //
- {{
- // we first scan the capital letters
- // this gives us the height of the text without descents but with
- // ascents
- GLfloat wid = 0;
- GLsizei count = 0;
- for (int i = font_ptr->first; i < font_ptr->num_chars; ++i) {
- const BitmapCharRec *ch = font_ptr->ch[i];
- if ( !ch ) {
- continue;
- }
- wid = max(ch->advance, wid);
- ++count;
- }
- return wid;
- }}
- case eMetric_TextWidth:
- case eMetric_FullTextWidth:
- //
- // return the width of the text with or without the final advance
- //
- if (text) {
- float sum = 0.0f;
- // iterate over our text
- const char* p = text;
- for ( ; text_len && p && *p; ++p, --text_len) {
- sum += s_GetCharAdvance(*p, font_ptr);
- }
- // adjust for the trailing character
- if (p && metric == eMetric_TextWidth) {
- --p;
- sum -= s_GetCharAdvance(*p, font_ptr);
- sum += s_GetCharWidth(*p, font_ptr);
- }
- return sum;
- }
- break;
- default:
- break;
- }
- return 0.0f;
- }
- string CGlBitmapFont::Truncate(const char* text, float w, ETruncate trunc) const
- {
- string res;
- x_Truncate(text, w, trunc, &res);
- return res;
- }
- string CGlBitmapFont::Truncate(const string& str, float w, ETruncate trunc) const
- {
- string res;
- x_Truncate(str.c_str(), w, trunc, &res);
- return res;
- }
- // Truncate a string for display. This version will return the maximum
- // number of characters that can fit into the given width
- int CGlBitmapFont::x_Truncate(const char* text, float w, ETruncate trunc,
- string* str) const
- {
- // first, retrieve our OpenGL font
- const BitmapFontRec* font_ptr = s_GetFont(m_Font);
- static const char* sc_ellipsis = "...";
- const char* ellip = NULL;
- const char* end_pos = text;
- switch (trunc) {
- case eTruncate_None:
- end_pos = text + strlen(text);
- break;
- case eTruncate_Ellipsis:
- {{
- // first, do a blunt cut
- int pos = x_Truncate(text, w, eTruncate_Empty);
- end_pos = text + pos;
- if ( !*end_pos ) {
- // we can fit the whole thing
- break;
- }
- // adjust for the ellipsis
- float e_wid = TextWidth(sc_ellipsis);
- while (e_wid > 0) {
- ellip = sc_ellipsis;
- e_wid -= s_GetCharWidth(*end_pos, font_ptr);
- if (end_pos > text) {
- --end_pos;
- } else {
- break;
- }
- }
- }}
- break;
- case eTruncate_Empty:
- for ( ; end_pos && *end_pos && w >= 0; ++end_pos) {
- float wid = s_GetCharAdvance(*end_pos, font_ptr);
- if (w - wid < 0) {
- wid = s_GetCharWidth(*end_pos, font_ptr);
- }
- w -= wid;
- }
- if (w < 0) {
- --end_pos;
- }
- break;
- }
- if (end_pos < text) {
- end_pos = text;
- }
- if (str) {
- str->assign(text, end_pos);
- if (ellip) {
- *str += ellip;
- }
- }
- return end_pos - text;
- }
- static const char* kPostfixes[] = { "", " K", " M", " G" };
- string CTextUtils::FormatSeparatedNumber(int Number, bool b_postfix)
- {
- bool bNegative = Number < 0;
- Number = abs(Number);
- string s_number, s_postfix;
- char cSep = ',';
- int i_postfix = 0;
- if(Number != 0 && b_postfix) {
- int Rest = Number % 1000;
- for( i_postfix = 0; Rest == 0; i_postfix++) {
- Number = Number / 1000;
- Rest = Number % 1000;
- }
- _ASSERT(i_postfix < 4);
- s_postfix = kPostfixes[i_postfix];
- }
- char sTemplGroup[] = " %.3d";
- sTemplGroup[0] = cSep;
- char sTemplLast[] = "%d";
- char S[20];
- do {
- int Rest = Number % 1000;
- Number = Number / 1000;
- sprintf(S, Number ? sTemplGroup : sTemplLast, Rest);
- s_number = string(S) + s_number;
- } while(Number);
- s_number += s_postfix;
- if(bNegative) {
- s_number = "-" + s_number;
- }
- return s_number;
- }
- int CTextUtils::GetCharsCount(int Number)
- {
- int MaxDigits = (int) ceil( log10((double) Number)); // decimal digist in number
- int nSep = (MaxDigits - 1) / 3; // number of separators between groups
- return MaxDigits + nSep;
- }
- END_NCBI_SCOPE
- /*
- * ===========================================================================
- * $Log: glbitmapfont.cpp,v $
- * Revision 1000.3 2004/06/01 20:50:25 gouriano
- * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.20
- *
- * Revision 1.20 2004/05/21 22:27:44 gorelenk
- * Added PCH ncbi_pch.hpp
- *
- * Revision 1.19 2004/05/21 12:44:12 dicuccio
- * Clean-up of font handling. Extended available font faces; added new font faces
- * (clean, fixed)
- *
- * Revision 1.18 2004/05/03 13:03:15 dicuccio
- * Fixed compiler warnings on MSVC7
- *
- * Revision 1.17 2004/03/12 15:29:19 dicuccio
- * Use CStaticArrayMap<> to manage font lookups
- *
- * Revision 1.16 2004/03/11 17:37:21 dicuccio
- * Split font face and font size from font specification
- *
- * Revision 1.15 2004/03/03 15:06:21 yazhuk
- * Changed labels alignment algorithm
- *
- * Revision 1.14 2003/12/10 21:32:07 ucko
- * +<stdio.h> for sprintf()
- *
- * Revision 1.13 2003/11/18 17:45:47 dicuccio
- * Formatting changes
- *
- * Revision 1.12 2003/11/17 21:03:39 yazhuk
- * Refactored Truncate() and TextOut() functions, added ArrayTextOut(),
- * renamed GetDigitsCount() to GetCharsCount()
- *
- * Revision 1.11 2003/10/29 22:27:06 yazhuk
- * Added CTextUtils class
- *
- * Revision 1.10 2003/10/09 17:58:39 lebedev
- * Trancate method made public
- *
- * Revision 1.9 2003/10/07 19:38:53 dicuccio
- * Temporarily disable display list inside of font - restores letters after window hide
- *
- * Revision 1.8 2003/09/29 15:34:45 dicuccio
- * Reworked TextHeight() and TextWidth() as forwarding functions. Expanded
- * GetMetric() to handle all cases
- *
- * Revision 1.7 2003/09/25 17:48:19 dicuccio
- * Added API for checking font metrics (only height is supported)
- *
- * Revision 1.6 2003/09/24 15:59:39 rsmith
- * in CGlBitmapFont::SetFont use GLsizei consistently to prevent max template from complaining about being passed arguments with different types.
- *
- * Revision 1.5 2003/09/17 16:25:12 dicuccio
- * Added new functions to handle automatic alignment, trimming of text. Optimized
- * and correctly implemented TextHeight()
- *
- * Revision 1.4 2003/08/28 19:27:54 dicuccio
- * TextOut() functions are now const
- *
- * Revision 1.3 2003/08/22 15:47:12 dicuccio
- * Added display lists to CGlBitmapFont
- *
- * Revision 1.2 2003/08/19 10:32:29 dicuccio
- * Fix compilation error - max<T>() needs to be passed two valuesof the same type
- *
- * Revision 1.1 2003/08/18 19:24:12 dicuccio
- * Initial revision of new bitmap fonts
- *
- * ===========================================================================
- */