问题描述
如果我将FreeType头文件移到FontRasterization.hpp
头文件中,我会得到Fatal error C1083: Cannot open include file: 'ft2build.h': No such file or directory
为什么?
我必须做一个怪异的解决方法,涉及void*
才能将FreeType对象存储在头文件中,并将其转换为源文件。
我只想正常使用FreeType,已经指定了FreeType的标头位置,库位置,freetype.lib和freetype.dll。
所有这些都是带有预编译头的静态库。
按照注释的完整源代码中的要求: FontRasterization.hpp
#pragma once
#include "FileIO.hpp"
#include "TextureAtlas.hpp"
namespace nui {
class Characteratlas;
struct Character {
uint32_t unicode;
int32_t bitmap_left;
int32_t bitmap_top;
int32_t hori_bearing_X;
int32_t hori_bearing_Y;
int32_t advance_X;
int32_t advance_Y;
AtlasRegion* zone;
uint32_t vertex_start_idx; // location in the vertex buffer where to find vertices
uint32_t index_start_idx; // location in the index buffer where to find indexes
};
struct FontSize {
uint32_t size;
uint32_t ascender;
uint32_t descender;
uint32_t line_spacing;
std::vector<Character> chars;
};
class Font {
public:
Characteratlas* atlas;
std::vector<uint8_t> ttf_file;
void* face_ft;
// cache
std::vector<uint8_t> bitmap;
// props
std::string family_name;
std::string style_name;
std::vector<FontSize> sizes;
public:
ErrStack addSize(uint32_t size);
};
class Characteratlas {
public:
TextureAtlas atlas;
void* free_type_ft = nullptr;
std::vector<Font> fonts;
public:
ErrStack addFont(FilePath& path,Font*& r_font);
ErrStack addFont(FilePath& path,std::vector<uint32_t>& sizes,Font*& r_font);
};
}
FontRasterization.cpp
#include "pch.h"
// Header
#include "FontRasterization.hpp"
// FreeType
#include <ft2build.h>
#include <freetype\freetype.h>
using namespace nui;
ErrStack Font::addSize(uint32_t size)
{
ErrStack err_stack;
FT_Error err;
uint32_t first_unicode = '!';
uint32_t last_unicode = '~';
uint32_t unicode_count = last_unicode - first_unicode + 1;
FT_Face face = (FT_Face)face_ft;
err = FT_Set_Pixel_Sizes(face,size);
if (err) {
return ErrStack(code_location,"Failed to set font face size");
}
FontSize& font_size = sizes.emplace_back();
font_size.size = size;
FT_Size_Metrics& metrics = face->size->metrics;
font_size.ascender = metrics.ascender / 64;
font_size.descender = (-metrics.descender) / 64;
font_size.line_spacing = metrics.height / 64;
font_size.chars.resize(unicode_count + 1);
uint32_t i = 0;
for (uint32_t unicode = first_unicode; unicode <= last_unicode; unicode++) {
uint32_t glyph_idx = FT_Get_Char_Index(face,unicode);
err = FT_Load_Glyph(face,glyph_idx,FT_LOAD_RENDER);
if (err) {
return ErrStack(code_location,"Failed to load and render glyph");
}
auto& glyph = face->glyph;
Character& chara = font_size.chars[i++];
chara.unicode = unicode;
chara.bitmap_left = glyph->bitmap_left;
chara.bitmap_top = glyph->bitmap_top;
chara.hori_bearing_X = glyph->metrics.horibearingX / 64;
chara.hori_bearing_Y = glyph->metrics.horibearingY / 64;
chara.advance_X = glyph->advance.x / 64;
chara.advance_Y = glyph->advance.y / 64;
bitmap.resize(glyph->bitmap.width * glyph->bitmap.rows);
std::memcpy(bitmap.data(),glyph->bitmap.buffer,bitmap.size());
TextureAtlas& tex_atlas = atlas->atlas;
if (!tex_atlas.addBitmap(bitmap,glyph->bitmap.width,glyph->bitmap.rows,chara.zone)) {
return ErrStack(code_location,"Failed to find space to store character in atlas");
}
}
// White Space
{
uint32_t space_unicode = 0x0020;
uint32_t glyph_idx = FT_Get_Char_Index(face,space_unicode);
err = FT_Load_Glyph(face,"Failed to load and render glyph");
}
auto& glyph = face->glyph;
Character& chara = font_size.chars[i];
chara.unicode = space_unicode;
chara.bitmap_left = glyph->bitmap_left;
chara.bitmap_top = glyph->bitmap_top;
chara.hori_bearing_X = glyph->metrics.horibearingX / 64;
chara.hori_bearing_Y = glyph->metrics.horibearingY / 64;
chara.advance_X = glyph->advance.x / 64;
chara.advance_Y = glyph->advance.y / 64;
chara.zone = nullptr;
}
return err_stack;
}
ErrStack Characteratlas::addFont(FilePath& path,Font*& r_font)
{
ErrStack err_stack;
FT_Error err;
FT_Library free_type = (FT_Library)free_type_ft;
if (free_type == nullptr) {
err = FT_Init_FreeType(&free_type);
if (err) {
return ErrStack(code_location,"Failed to initialize FreeType library");
}
}
Font& font = this->fonts.emplace_back();
font.atlas = this;
checkErrStack(path.read(font.ttf_file),"Failed to read font file");
FT_Face face = (FT_Face)font.face_ft;
err = FT_New_Memory_Face(free_type,font.ttf_file.data(),(uint32_t)font.ttf_file.size(),&face);
if (err) {
return ErrStack(code_location,"Failed to create font face");
}
font.family_name = face->family_name;
font.style_name = face->style_name;
r_font = &font;
return err_stack;
}
ErrStack Characteratlas::addFont(FilePath& path,Font*& r_font)
{
ErrStack err_stack;
FT_Library free_type = (FT_Library)free_type_ft;
FT_Error err = FT_Init_FreeType(&free_type);
if (err) {
return ErrStack(code_location,"Failed to initialize FreeType library");
}
FT_Face face;
std::vector<uint8_t> ttf_file;
checkErrStack(path.read(ttf_file),"Failed to read font file");
err = FT_New_Memory_Face(free_type,ttf_file.data(),(uint32_t)ttf_file.size(),"Failed to create font face");
}
Font& font = this->fonts.emplace_back();
font.family_name = face->family_name;
font.style_name = face->style_name;
uint32_t first_unicode = '!';
uint32_t last_unicode = '~';
uint32_t unicode_count = last_unicode - first_unicode + 1;
std::vector<uint8_t> bitmap;
for (auto size : sizes) {
err = FT_Set_Pixel_Sizes(face,size);
if (err) {
return ErrStack(code_location,"Failed to set font face size");
}
FontSize& font_size = font.sizes.emplace_back();
font_size.size = size;
font_size.ascender = face->size->metrics.ascender / 64;
font_size.descender = (-face->size->metrics.descender) / 64;
font_size.line_spacing = face->size->metrics.height / 64;
font_size.chars.resize(unicode_count + 1);
if (!atlas.colors.size()) {
atlas.create(2048);
}
uint32_t i = 0;
for (uint32_t unicode = first_unicode; unicode <= last_unicode; unicode++) {
uint32_t glyph_idx = FT_Get_Char_Index(face,unicode);
err = FT_Load_Glyph(face,FT_LOAD_RENDER);
if (err) {
return ErrStack(code_location,"Failed to load and render glyph");
}
auto& glyph = face->glyph;
Character& chara = font_size.chars[i++];
chara.unicode = unicode;
chara.bitmap_left = glyph->bitmap_left;
chara.bitmap_top = glyph->bitmap_top;
chara.hori_bearing_X = glyph->metrics.horibearingX / 64;
chara.hori_bearing_Y = glyph->metrics.horibearingY / 64;
chara.advance_X = glyph->advance.x / 64;
chara.advance_Y = glyph->advance.y / 64;
bitmap.resize(glyph->bitmap.width * glyph->bitmap.rows);
std::memcpy(bitmap.data(),bitmap.size());
if (!atlas.addBitmap(bitmap,chara.zone)) {
return ErrStack(code_location,"Failed to find space to store character in atlas");
}
}
// White Space
uint32_t space_unicode = 0x0020;
uint32_t glyph_idx = FT_Get_Char_Index(face,"Failed to load and render glyph");
}
auto& glyph = face->glyph;
Character& chara = font_size.chars[i];
chara.unicode = space_unicode;
chara.bitmap_left = glyph->bitmap_left;
chara.bitmap_top = glyph->bitmap_top;
chara.hori_bearing_X = glyph->metrics.horibearingX / 64;
chara.hori_bearing_Y = glyph->metrics.horibearingY / 64;
chara.advance_X = glyph->advance.x / 64;
chara.advance_Y = glyph->advance.y / 64;
chara.zone = nullptr;
}
r_font = &font;
return ErrStack();
}
代码库中尚未使用方法ErrStack Font::addSize(uint32_t size)
和ErrStack Characteratlas::addFont(FilePath& path,Font*& r_font)
。
预编译的头文件
#pragma once
// Windows
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
// Windows undefs
#undef min
#undef max
// DirectX 11
#include <d3d11_4.h>
#include <dxgi1_6.h>
#pragma comment(lib,"D3D11.lib")
#pragma comment(lib,"dxgi.lib")
// Standard
#include <string>
#include <vector>
#include <array>
#include <list>
#include <variant>
#include <cmath>
// GLM
#include <glm\vec2.hpp>
#include <glm\vec4.hpp>
// mine
#include "ErrorStack.hpp"
解决方法
根据C1083 error,请在Project Properties \ C / C ++ \ General中检查您的“其他包含目录”是否正确。如果目录是相对路径,请尝试将其切换为绝对路径。
此外,您还可以尝试使用双引号而不是尖括号将其包括在内。
#include "ft2build.h"
#include "freetype\freetype.h"
如果它们不起作用,则可以尝试使用vcpkg tool,这可以帮助您自动管理Visual Studio的C ++库。我已经对它进行了测试,“ ft2build.h”将正常包含在头文件中。
步骤:
- 打开Git CMD
- 下载vcpkg工具:> git clone https://github.com/microsoft/vcpkg
- 安装工具:>。\ vcpkg \ bootstrap-vcpkg.bat
- 在Visual Studio中使用vcpkg:>。\ vcpkg \ vcpkg集成安装
- 安装freetype库:>。\ vcpkg \ vcpkg安装freetype:x86-windows
- 卸载项目,然后重新加载项目