freetype提取路径,转svg显示
std::string FontPath::toSvg(const Segment &seg) const
{
if (seg.pts.empty())
return "";
std::ostringstream strStream;
for (const auto &pt : seg.pts) {
if (!strStream.view().empty())
strStream << "__";
strStream << pt.x;
strStream << ",";
strStream << pt.y;
}
return strStream.str();
}
std::string FontPath::toSvg() const
{
std::string svg;
for (const auto &seg : m_points) {
if (!svg.empty())
svg.append(",");
switch (seg.type) {
case Type::MOVE:
svg.append("M");
break;
case Type::LINE:
svg.append("L");
break;
case Type::QUAD:
svg.append("Q");
break;
case Type::CONIC:
svg.append("C");
break;
case Type::CUBIC:
svg.append("C");
break;
case Type::CLOSE:
svg.append("C");
break;
default:;
}
svg.append(" ");
svg.append(toSvg(seg));
}
return svg;
}
["M 31.23,79.50,C 31.23,35.59__77.57,0.00__134.73,0.00,C 191.89,0.00__188.73,35.59__188.73,79.50,C 188.73,123.41__226.89,221.50__169.73,221.50,C 141.98,221.50__35.81,200.32__8.73,171.50,C -19.96,140.96__31.23,102.09__31.23,79.50"]
freetype提取bitmap,控制台打印
void Draw_Bitmap(unsigned char *bitmap, int width, int height)
{
std::cout << std::endl;
if (bitmap == NULL)
return;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
int color = bitmap[i * width + j];
if (color == 0) {
std::cout << " ";
} else {
std::cout << "*";
}
}
std::cout << std::endl;
}
}
freetype提取bitmap,转纹理贴图
#include <iostream>
#include <map>
#include <string>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "ftest.h"
#include "fontParse.h"
#include "shader.h"
void framebuffer_size_callback(GLFWwindow *window, int width, int height);
void processInput(GLFWwindow *window);
void RenderText(Shader &shader, std::string text, float x, float y, float scale, glm::vec3 color);
// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
/// Holds all state information relevant to a character as loaded using FreeType
struct Character {
unsigned int TextureID; // ID handle of the glyph texture
glm::ivec2 Size; // Size of glyph
glm::ivec2 Bearing; // Offset from baseline to left/top of glyph
unsigned int Advance; // Horizontal offset to advance to next glyph
};
std::map<GLchar, Character> Characters;
unsigned int VAO, VBO;
TEST(Render, TextRender)
{
// glfw: initialize and configure
// ------------------------------
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
// glfw window creation
// --------------------
GLFWwindow *window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
if (window == NULL) {
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
// glad: load all OpenGL function pointers
// ---------------------------------------
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
std::cout << "Failed to initialize GLAD" << std::endl;
return;
}
// OpenGL state
// ------------
glEnable(GL_CULL_FACE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// compile and setup the shader
// ----------------------------
Shader shader("text.vs", "text.fs");
glm::mat4 projection = glm::ortho(0.0f, static_cast<float>(SCR_WIDTH), 0.0f, static_cast<float>(SCR_HEIGHT));
shader.use();
glUniformMatrix4fv(glGetUniformLocation(shader.ID, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
// disable byte-alignment restriction
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
const char *path = "D:\\fonts";
auto fontMap = createFontMap(path, FontMapType::FONT_MAP_TYPE_FT);
// load first 128 characters of ASCII set
for (unsigned char c = 0; c < 128; c++) {
// Load character glyph
auto image = getImage(fontMap, c);
// generate texture
unsigned int texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, image.pitch, image.rows, 0, GL_RED, GL_UNSIGNED_BYTE, image.bitmap);
// set texture options
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// now store character for later use
Character character = {texture,
glm::ivec2(image.width, image.rows),
glm::ivec2(image.x_bearing, image.y_bearing),
static_cast<unsigned int>(image.bound.width)};
Characters.insert(std::pair<char, Character>(c, character));
}
glBindTexture(GL_TEXTURE_2D, 0);
// configure VAO/VBO for texture quads
// -----------------------------------
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6 * 4, NULL, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
// render loop
// -----------
while (!glfwWindowShouldClose(window)) {
// input
// -----
processInput(window);
// render
// ------
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
RenderText(shader, "This is sample text", 25.0f, 25.0f, 1.0f, glm::vec3(0.5, 0.8f, 0.2f));
RenderText(shader, "(C) LearnOpenGL.com", 540.0f, 570.0f, 0.5f, glm::vec3(0.3, 0.7f, 0.9f));
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
// -------------------------------------------------------------------------------
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return;
}
// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow *window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
}
// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow *window, int width, int height)
{
// make sure the viewport matches the new window dimensions; note that width and
// height will be significantly larger than specified on retina displays.
glViewport(0, 0, width, height);
}
// render line of text
// -------------------
void RenderText(Shader &shader, std::string text, float x, float y, float scale, glm::vec3 color)
{
// activate corresponding render state
shader.use();
glUniform3f(glGetUniformLocation(shader.ID, "textColor"), color.x, color.y, color.z);
glActiveTexture(GL_TEXTURE0);
glBindVertexArray(VAO);
// iterate through all characters
std::string::const_iterator c;
for (c = text.begin(); c != text.end(); c++) {
Character ch = Characters[*c];
float xpos = x + ch.Bearing.x * scale;
float ypos = y - (ch.Size.y - ch.Bearing.y) * scale;
float w = ch.Size.x * scale;
float h = ch.Size.y * scale;
// update VBO for each character
float vertices[6][4] = {{xpos, ypos + h, 0.0f, 0.0f},
{xpos, ypos, 0.0f, 1.0f},
{xpos + w, ypos, 1.0f, 1.0f},
{xpos, ypos + h, 0.0f, 0.0f},
{xpos + w, ypos, 1.0f, 1.0f},
{xpos + w, ypos + h, 1.0f, 0.0f}};
// render glyph texture over quad
glBindTexture(GL_TEXTURE_2D, ch.TextureID);
// update content of VBO memory
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferSubData(GL_ARRAY_BUFFER,
0,
sizeof(vertices),
vertices); // be sure to use glBufferSubData and not glBufferData
glBindBuffer(GL_ARRAY_BUFFER, 0);
// render quad
glDrawArrays(GL_TRIANGLES, 0, 6);
// now advance cursors for next glyph (note that advance is number of 1/64 pixels)
x += (ch.Advance >> 6) * scale; // bitshift by 6 to get value in pixels (2^6 = 64 (divide amount of 1/64th pixels by
// 64 to get amount of pixels))
x += ch.Advance;
}
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
}
C/C++ 利用FreeType提取字体文件的字形_c++ 获取文字的轮廓path-CSDN博客
SVG 路径 | 菜鸟教程
https://blog.51cto.com/u_16124099/6327628
LearnOpenGL - Text Rendering
C++字体库开发之字体回退三-CSDN博客