glbitmapfont.cpp

来自「ncbi源码」· C++ 代码 · 共 929 行 · 第 1/2 页

CPP
929
字号
/* * =========================================================================== * 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_SCOPEtypedef 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 inlineconst 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] ) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?