119 log_err0(
"字体数加载超过上限!你可以修改 NUM_MAX_FONT值来支持更多。");
122 Buffer& buf =_vecBuffer[_vecFace.size()];
127 if (FT_New_Memory_Face(_library, (FT_Byte*)buf.
data(), (FT_Long)buf.
size(),
130 log_err(
"字体文件加载失败: {}", path_name);
133 assert(FT_IS_SCALABLE(face));
136 log_msg(
"成功加载一个字体:{},{}", _vecFace.size(), path_name);
137 log_(
"名称:{}", face->family_name);
138 log_(
"字形数:{}", face->num_glyphs);
142 _vecFace.push_back(face);
143 _vecProperty.push_back({});
144 return _vecFace.size() - 1;
150 auto fn_debug = [&](std::string_view str)
156 if (info.
_font >= _vecFace.size())
162 const char32_t& ch = info.
_ch;
163 const size_t& size = info.
_size;
164 const size_t& outline = info.
_outline;
166 FT_Face ft_face = _vecFace[info.
_font];
167 if (FT_Select_Charmap(ft_face, FT_ENCODING_UNICODE))
173 if (FT_Set_Char_Size(ft_face, FT_F26Dot6(size << 6), FT_F26Dot6(size << 6), 72, 72))
175 fn_debug(
"设置字体大小失败");
179 FT_UInt gindex = FT_Get_Char_Index(ft_face, ch);
180 if (FT_Load_Glyph(ft_face, gindex, FT_LOAD_NO_BITMAP))
185 if (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE)
191 std::vector<Span> spans;
192 RenderSpans(_library, &ft_face->glyph->outline, &spans);
195 std::vector<Span> spans_outline;
199 FT_Stroker_New(_library, &stroker);
200 FT_Stroker_Set(stroker,
202 FT_STROKER_LINECAP_ROUND,
203 FT_STROKER_LINEJOIN_ROUND,
207 if (FT_Get_Glyph(ft_face->glyph, &glyph))
213 FT_Glyph_StrokeBorder(&glyph, stroker, 0, 1);
214 if (glyph->format == FT_GLYPH_FORMAT_OUTLINE)
218 &
reinterpret_cast<FT_OutlineGlyph
>(glyph)->outline;
223 FT_Stroker_Done(stroker);
224 FT_Done_Glyph(glyph);
228 fn_debug(
"spans为空(或许打印了控制字符)");
233 float(spans.front()._x),
234 float(spans.front()._y),
235 float(spans.front()._x),
236 float(spans.front()._y));
237 for (
Span& s : spans)
240 rect.
Include(s._x + s._w - 1, s._y);
242 for (
Span& s : spans_outline)
245 rect.
Include(s._x + s._w - 1, s._y);
249 unsigned img_w = (unsigned)rect.
Width();
250 unsigned img_h = (unsigned)rect.
Height();
258 uint32_t* p_lock = img_outline->
GetData();
261 for (
Span& s : spans_outline)
263 for (
int w = 0; w < s._w; ++w)
265 size_t y = (size_t)(img_h - 1 - (s._y - rect.
_yMin));
266 size_t index = (size_t)(y * img_w + s._x - rect.
_xMin + w);
267 p_lock[index] = uint32_t(s._coverage) << 24 | 0x00ffffff;
271 p_lock = img->GetData();
272 for (
Span& s : spans)
274 for (
int w = 0; w < s._w; ++w)
276 size_t y = (size_t)(img_h - 1 - (s._y - rect.
_yMin));
277 size_t index = (size_t)(y * img_w + s._x - rect.
_xMin + w);
278 p_lock[index] = uint32_t(s._coverage) << 24 | 0x00ffffff;
282 float bearingX = float(ft_face->glyph->metrics.horiBearingX >> 6);
283 float bearingY = float(ft_face->glyph->metrics.horiBearingY >> 6);
284 float advance = float(ft_face->glyph->advance.x >> 6);
295 prop.
_ascent = float(ft_face->size->metrics.ascender >> 6);
296 prop.
_descent = float(ft_face->size->metrics.descender >> 6);