Files
CM95/docs/外部参考/OpenCPN源码基线_f7211b4e/上游源码/libs/s52plib/src/DepthFont.cpp
2026-09-20 17:40:34 +08:00

180 lines
5.1 KiB
C++
Executable File

/***************************************************************************
*
* Project: OpenCPN
* Purpose: texture OpenGL text rendering built from wxFont
* Author: Sean D'Epagnier
*
***************************************************************************
* Copyright (C) 2014 Sean D'Epagnier *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
**************************************************************************/
#include <wx/wx.h>
#include "s52plibGL.h"
#include "DepthFont.h"
#include "s52_plib_utils.h"
DepthFont::DepthFont() {
texobj = 0;
m_built = false;
m_scaleFactor = 0;
m_ContentScaleFactor = 1.0;
}
DepthFont::~DepthFont() { Delete(); }
void DepthFont::Build(wxFont *font, double scale, double dip_factor) {
/* avoid rebuilding if the parameters are the same */
if (m_built && (*font == m_font)) return;
m_font = *font;
m_scaleFactor = scale;
m_dip_factor = dip_factor;
m_maxglyphw = 0;
m_maxglyphh = 0;
double scaler = m_ContentScaleFactor * dip_factor;
wxFont *scaled_font = GetS52Utils()->GetFont(font, scaler);
wxScreenDC sdc;
sdc.SetFont(*scaled_font);
for (int i = 0; i < 10; i++) {
wxCoord gw, gh;
wxString text;
text = wxString::Format(_T("%d"), i);
wxCoord descent, exlead;
sdc.GetTextExtent(text, &gw, &gh, &descent, &exlead,
scaled_font); // measure the text
tgi[i].width = gw;
tgi[i].height = gh; // - descent;
tgi[i].advance = gw;
tgi[i].advance *= dip_factor;
if (i == 1)
m_width_one = gw;
m_maxglyphw = wxMax(tgi[i].width + tgi[i].advance, m_maxglyphw);
m_maxglyphh = wxMax(tgi[i].height, m_maxglyphh);
}
int w = 10 * m_maxglyphw;
int h = m_maxglyphh;
/* make power of 2 */
for (tex_w = 1; tex_w < w; tex_w *= 2)
;
for (tex_h = 1; tex_h < h; tex_h *= 2)
;
wxBitmap tbmp(tex_w, tex_h);
wxMemoryDC dc;
dc.SelectObject(tbmp);
dc.SetFont(*scaled_font);
/* fill bitmap with black */
dc.SetBackground(wxBrush(wxColour(0, 0, 0)));
dc.Clear();
/* draw the text white */
dc.SetTextForeground(wxColour(255, 255, 255));
/* wxPen pen(wxColour( 255, 255, 255 ));
wxBrush brush(wxColour( 255, 255, 255 ), wxTRANSPARENT);
dc.SetPen(pen);
dc.SetBrush(brush);
*/
int row = 0, col = 0;
for (int i = 0; i < 10; i++) {
tgi[i].x = col * m_maxglyphw;
tgi[i].y = row * m_maxglyphh;
wxString text;
text = wxString::Format(_T("%d"), i);
dc.DrawText(text, tgi[i].x, tgi[i].y);
col++;
}
dc.SelectObject(wxNullBitmap);
wxImage image = tbmp.ConvertToImage();
GLuint format, internalformat;
int stride;
format = GL_ALPHA;
internalformat = format;
stride = 1;
unsigned char *imgdata = image.GetData();
if (imgdata) {
unsigned char *teximage = (unsigned char *)malloc(stride * tex_w * tex_h);
for (int j = 0; j < tex_w * tex_h; j++)
for (int k = 0; k < stride; k++)
teximage[j * stride + k] = imgdata[3 * j];
glGenTextures(1, &texobj);
glBindTexture(GL_TEXTURE_2D, texobj);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, internalformat, tex_w, tex_h, 0, format,
GL_UNSIGNED_BYTE, teximage);
free(teximage);
}
m_built = true;
}
void DepthFont::Delete() {
if (texobj) {
glDeleteTextures(1, &texobj);
texobj = 0;
}
m_built = false;
m_scaleFactor = 0;
}
bool DepthFont::GetGLTextureRect(wxRect &texrect, int symIndex) {
if (symIndex < 10) {
texrect.x = tgi[symIndex].x;
texrect.y = tgi[symIndex].y;
texrect.width = tgi[symIndex].width + (m_width_one / 10);
texrect.height = tgi[symIndex].height;
return true;
} else {
texrect.x = tgi[0].x;
texrect.y = tgi[0].y;
texrect.width = tgi[0].width;
texrect.height = tgi[0].height;
return false;
}
}