[refactor] 整理注释
This commit is contained in:
@@ -8,13 +8,7 @@ void pf_print_char(char c, SUINT32 basex, SUINT32 basey, EFI_GRAPHICS_OUTPUT_BLT
|
||||
for (SUINT32 y = 0; y < 16; y++) {
|
||||
SUINT8 data = hankaku_pixels[c][y];
|
||||
for (SSINT32 x = 7; x >= 0; x--) {
|
||||
// 解码Hankaku字体
|
||||
/*
|
||||
既然都在这了,就讲一下Hankaku字体是如何解码的
|
||||
比如一个
|
||||
{0x00, 0x82, 0x82, 0x44, 0x44, 0x44, 0x28, 0x28, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00}
|
||||
每一个Hex代表一行,比如0x82就是一行,转换成Bin得到10000010,1代表有像素,0代表没像素
|
||||
*/
|
||||
// Hankaku 字体解码:每个字节代表一行,低位在右
|
||||
SUINT32 current = data & 1;
|
||||
data >>= 1;
|
||||
if (current)
|
||||
@@ -26,6 +20,6 @@ void pf_print_char(char c, SUINT32 basex, SUINT32 basey, EFI_GRAPHICS_OUTPUT_BLT
|
||||
void pf_print(const char* text, SUINT32 basex, SUINT32 basey, EFI_GRAPHICS_OUTPUT_BLT_PIXEL color) {
|
||||
for (SUINT32 i = 0; i < str_len(text); i++) {
|
||||
char c = text[i];
|
||||
pf_print_char(c, basex + i * 8, basey, color); // 只要 字数 * 8 + basex 不爆hr就没事
|
||||
pf_print_char(c, basex + i * 8, basey, color);
|
||||
}
|
||||
}
|
||||
+3
-5
@@ -4,14 +4,12 @@
|
||||
#include <memory/heap.h>
|
||||
#include <serial.h>
|
||||
|
||||
// Per-glyph scratch — kept static to avoid stack pressure for big Chinese glyphs
|
||||
// 逐字形临时缓冲区 — 静态分配以避免大中文字形的栈压力
|
||||
static ttf_outline_t s_outline;
|
||||
static ttf_seg_t s_segs[4096];
|
||||
static SUINT8 s_coverage[256 * 256];
|
||||
|
||||
// Render one glyph bitmap at screen (px, py) where py is the glyph TOP
|
||||
// (already converted from baseline). (px, py) may be negative — caller
|
||||
// must have clipped into the visible region.
|
||||
// 在屏幕 (px, py) 处渲染单个字形位图,py 为字形顶部(已从基线转换)
|
||||
static void blit_glyph(SSINT32 px, SSINT32 py, SUINT32 w, SUINT32 h,
|
||||
const SUINT8* coverage, SUINT32 N,
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL color)
|
||||
@@ -31,7 +29,7 @@ static void blit_glyph(SSINT32 px, SSINT32 py, SUINT32 w, SUINT32 h,
|
||||
}
|
||||
}
|
||||
|
||||
// Render a single codepoint at (x, y) = baseline. Returns advance (26.6).
|
||||
// 在基线 (x, y) 处渲染单个码点,返回进宽(26.6 定点数)
|
||||
static f26_6 render_codepoint(ttf_face_t* face, SSINT32 cp,
|
||||
SSINT32 x, SSINT32 y, SUINT32 pixel_size,
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL color)
|
||||
|
||||
+35
-35
@@ -3,7 +3,7 @@
|
||||
#include <memory/heap.h>
|
||||
#include <serial.h>
|
||||
|
||||
// ---- Big-endian readers (TTF is big-endian) ----
|
||||
// 大端读取器(TTF 为大端格式)
|
||||
static inline SUINT16 rd16(const SUINT8* p) {
|
||||
return ((SUINT16)p[0] << 8) | p[1];
|
||||
}
|
||||
@@ -27,7 +27,7 @@ static const SUINT8* find_table(ttf_face_t* face, const char tag[4]) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// ---- UTF-8 ----
|
||||
// UTF-8 解码
|
||||
SSINT32 ttf_utf8_decode(const char** p) {
|
||||
const SUINT8* s = (const SUINT8*)*p;
|
||||
SUINT8 b0 = s[0];
|
||||
@@ -39,7 +39,7 @@ SSINT32 ttf_utf8_decode(const char** p) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// ---- cmap ----
|
||||
// cmap 子表查找
|
||||
static const SUINT8* find_cmap_subtable(ttf_face_t* face) {
|
||||
const SUINT8* cmap = face->cmap;
|
||||
SUINT16 num = rd16(cmap + 2);
|
||||
@@ -85,7 +85,7 @@ static SUINT16 cmap4_lookup(const SUINT8* sub, SSINT32 cp) {
|
||||
}
|
||||
|
||||
static SUINT16 cmap12_lookup(const SUINT8* sub, SSINT32 cp) {
|
||||
// Format 12 header: format(2) reserved(2) length(4) language(4) nGroups(4)
|
||||
// Format 12 头:format(2) reserved(2) length(4) language(4) nGroups(4)
|
||||
SUINT32 nGroups = rd32(sub + 12);
|
||||
const SUINT8* g = sub + 16;
|
||||
for (SUINT32 i = 0; i < nGroups; i++) {
|
||||
@@ -108,14 +108,14 @@ SUINT16 ttf_cmap_lookup(ttf_face_t* face, SSINT32 cp) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ---- Glyf decode ----
|
||||
// glyf 解码
|
||||
bool ttf_load_glyph(ttf_face_t* face, SUINT16 glyph_id,
|
||||
SUINT32 pixel_size_px, ttf_outline_t* out)
|
||||
{
|
||||
mem_set(out, 0, sizeof(*out));
|
||||
if (glyph_id >= face->num_glyphs) return false;
|
||||
|
||||
// Loca
|
||||
// Loca 索引
|
||||
SUINT32 off0, off1;
|
||||
if (face->index_to_loc_format == 0) {
|
||||
off0 = ((SUINT32)rd16(face->loca + glyph_id * 2)) * 2;
|
||||
@@ -126,7 +126,7 @@ bool ttf_load_glyph(ttf_face_t* face, SUINT16 glyph_id,
|
||||
}
|
||||
if (off0 >= face->glyf_len) return false;
|
||||
|
||||
// Advance width (always readable from hmtx regardless of glyf presence)
|
||||
// 进宽(始终从 hmtx 读取,无论 glyf 是否存在)
|
||||
{
|
||||
SUINT16 aw;
|
||||
if (glyph_id < face->num_long_hor_metrics) {
|
||||
@@ -138,21 +138,21 @@ bool ttf_load_glyph(ttf_face_t* face, SUINT16 glyph_id,
|
||||
}
|
||||
|
||||
if (off0 == off1) {
|
||||
// Empty glyph (e.g. space)
|
||||
// 空白字形(如空格)
|
||||
return true;
|
||||
}
|
||||
|
||||
const SUINT8* g = face->glyf + off0;
|
||||
SSINT16 numContours = rd16s(g + 0);
|
||||
if (numContours < 0) {
|
||||
// Composite glyph — parse component records and merge outlines
|
||||
// 复合字形 — 解析组件记录并合并轮廓
|
||||
const SUINT8* cp = g + 10;
|
||||
SSINT32 all_xmin = 0x7FFFFFFF, all_ymin = 0x7FFFFFFF;
|
||||
SSINT32 all_xmax = -0x7FFFFFFF, all_ymax = -0x7FFFFFFF;
|
||||
|
||||
// Composite glyph flags (OpenType spec):
|
||||
// 0x0001 = ARG_1_AND_2_ARE_WORDS (16-bit args; else 8-bit)
|
||||
// 0x0002 = ARGS_ARE_XY_VALUES (offsets; else point indices)
|
||||
// 复合字形标志(OpenType 规范):
|
||||
// 0x0001 = ARG_1_AND_2_ARE_WORDS(16 位参数;否则 8 位)
|
||||
// 0x0002 = ARGS_ARE_XY_VALUES(偏移量;否则点索引)
|
||||
// 0x0008 = WE_HAVE_A_SCALE
|
||||
// 0x0040 = WE_HAVE_A_2x2
|
||||
// 0x0080 = WE_HAVE_AN_X_AND_Y_SCALE
|
||||
@@ -162,41 +162,41 @@ bool ttf_load_glyph(ttf_face_t* face, SUINT16 glyph_id,
|
||||
SUINT16 comp_flags = rd16(cp); cp += 2;
|
||||
SUINT16 comp_glyph = rd16(cp); cp += 2;
|
||||
|
||||
// Read arguments (size depends on ARG_1_AND_2_ARE_WORDS)
|
||||
// 读取参数(大小取决于 ARG_1_AND_2_ARE_WORDS)
|
||||
SSINT32 arg1, arg2;
|
||||
if (comp_flags & 0x0001) {
|
||||
// 16-bit signed words
|
||||
// 16 位有符号字
|
||||
arg1 = rd16s(cp); cp += 2;
|
||||
arg2 = rd16s(cp); cp += 2;
|
||||
} else {
|
||||
// 8-bit signed bytes
|
||||
// 8 位有符号字节
|
||||
arg1 = (SSINT8)cp[0];
|
||||
arg2 = (SSINT8)cp[1];
|
||||
cp += 2;
|
||||
}
|
||||
|
||||
// Read transform scale if present
|
||||
// 如果存在则读取缩放比例
|
||||
f26_6 scale = F26_ONE;
|
||||
if (comp_flags & 0x0008) {
|
||||
// WE_HAVE_A_SCALE: 16.16 fixed-point
|
||||
// WE_HAVE_A_SCALE:16.16 定点数
|
||||
SSINT16 s16 = rd16s(cp); cp += 2;
|
||||
scale = (f26_6)s16; // already in f26.6 from 16.16
|
||||
}
|
||||
|
||||
// Read x/y scale if present
|
||||
// 如果存在则读取 x/y 缩放
|
||||
f26_6 scaleX = F26_ONE, scaleY = F26_ONE;
|
||||
if (comp_flags & 0x0080) {
|
||||
// WE_HAVE_AN_X_AND_Y_SCALE: two 16.16 values
|
||||
// WE_HAVE_AN_X_AND_Y_SCALE:两个 16.16 值
|
||||
SSINT16 sx16 = rd16s(cp); cp += 2;
|
||||
SSINT16 sy16 = rd16s(cp); cp += 2;
|
||||
scaleX = (f26_6)sx16;
|
||||
scaleY = (f26_6)sy16;
|
||||
}
|
||||
|
||||
// Read 2x2 matrix if present
|
||||
// 如果存在则读取 2x2 矩阵
|
||||
f26_6 m00 = F26_ONE, m01 = 0, m10 = 0, m11 = F26_ONE;
|
||||
if (comp_flags & 0x0040) {
|
||||
// WE_HAVE_A_2x2: four 2.14 values
|
||||
// WE_HAVE_A_2x2:四个 2.14 值
|
||||
SSINT16 a = rd16s(cp); cp += 2;
|
||||
SSINT16 b = rd16s(cp); cp += 2;
|
||||
SSINT16 c = rd16s(cp); cp += 2;
|
||||
@@ -207,36 +207,36 @@ bool ttf_load_glyph(ttf_face_t* face, SUINT16 glyph_id,
|
||||
m11 = (f26_6)(d >> 8);
|
||||
}
|
||||
|
||||
// Load component glyph
|
||||
// 加载组件字形
|
||||
ttf_outline_t comp;
|
||||
if (!ttf_load_glyph(face, comp_glyph, pixel_size_px, &comp))
|
||||
return false;
|
||||
|
||||
// Determine if args are offsets (XY values) or point indices
|
||||
// 判断参数是偏移量(XY 值)还是点索引
|
||||
SSINT32 offset_x = 0, offset_y = 0;
|
||||
if (comp_flags & 0x0002) {
|
||||
// ARGS_ARE_XY_VALUES: args are pixel offsets (already scaled)
|
||||
// Scale from font units to pixel space like simple glyphs
|
||||
// ARGS_ARE_XY_VALUES:参数是像素偏移量(已缩放)
|
||||
// 从字体单位缩放到像素空间
|
||||
offset_x = (SSINT32)(((SSINT64)arg1 * (SSINT64)pixel_size_px * 64 / face->units_per_em));
|
||||
offset_y = (SSINT32)(((SSINT64)arg2 * (SSINT64)pixel_size_px * 64 / face->units_per_em));
|
||||
}
|
||||
|
||||
// Transform and merge component points
|
||||
// 变换并合并组件点
|
||||
for (SUINT16 i = 0; i < comp.num_points; i++) {
|
||||
f26_6 fx = comp.x[i];
|
||||
f26_6 fy = comp.y[i];
|
||||
f26_6 tx, ty;
|
||||
|
||||
if (comp_flags & 0x0040) {
|
||||
// 2x2 matrix transform
|
||||
// 2x2 矩阵变换
|
||||
tx = f26_mul(m00, fx) + f26_mul(m01, fy);
|
||||
ty = f26_mul(m10, fx) + f26_mul(m11, fy);
|
||||
} else if (comp_flags & 0x0008) {
|
||||
// Uniform scale
|
||||
// 均匀缩放
|
||||
tx = f26_mul(scale, fx);
|
||||
ty = f26_mul(scale, fy);
|
||||
} else if (comp_flags & 0x0080) {
|
||||
// X/Y scale
|
||||
// x/y 独立缩放
|
||||
tx = f26_mul(scaleX, fx);
|
||||
ty = f26_mul(scaleY, fy);
|
||||
} else {
|
||||
@@ -295,7 +295,7 @@ bool ttf_load_glyph(ttf_face_t* face, SUINT16 glyph_id,
|
||||
SUINT16 instrLen = rd16(p); p += 2;
|
||||
p += instrLen;
|
||||
|
||||
// Decode flags (with REPEAT)
|
||||
// 解码标志(含 REPEAT)
|
||||
SUINT8 flags[1024];
|
||||
SUINT16 pi = 0;
|
||||
while (pi < numPoints) {
|
||||
@@ -308,7 +308,7 @@ bool ttf_load_glyph(ttf_face_t* face, SUINT16 glyph_id,
|
||||
}
|
||||
}
|
||||
|
||||
// Decode x-coords into x_raw[]
|
||||
// 解码 x 坐标到 x_raw[]
|
||||
SSINT32 x_raw[1024];
|
||||
{
|
||||
SSINT32 x = 0;
|
||||
@@ -324,7 +324,7 @@ bool ttf_load_glyph(ttf_face_t* face, SUINT16 glyph_id,
|
||||
x_raw[i] = x;
|
||||
}
|
||||
}
|
||||
// Decode y-coords into y_raw[]
|
||||
// 解码 y 坐标到 y_raw[]
|
||||
SSINT32 y_raw[1024];
|
||||
{
|
||||
SSINT32 y = 0;
|
||||
@@ -341,7 +341,7 @@ bool ttf_load_glyph(ttf_face_t* face, SUINT16 glyph_id,
|
||||
}
|
||||
}
|
||||
|
||||
// Scale to pixel space (f26_6)
|
||||
// 缩放到像素空间(f26_6)
|
||||
SUINT64 scale_num = (SUINT64)pixel_size_px * 64;
|
||||
for (SUINT16 i = 0; i < numPoints; i++) {
|
||||
out->x[i] = (f26_6)(((SSINT64)x_raw[i] * (SSINT64)scale_num) / face->units_per_em);
|
||||
@@ -365,7 +365,7 @@ bool ttf_load_glyph(ttf_face_t* face, SUINT16 glyph_id,
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---- Open / close ----
|
||||
// 打开 / 关闭
|
||||
ttf_face_t* ttf_open(const void* data, UINTN size) {
|
||||
if (!data || size < 12) return NULL;
|
||||
const SUINT8* d = (const SUINT8*)data;
|
||||
@@ -449,7 +449,7 @@ void ttf_close(ttf_face_t* face) {
|
||||
if (face) kfree(face);
|
||||
}
|
||||
|
||||
// ---- Metrics (scaled to pixel_size, returned as 26.6 fp) ----
|
||||
// 度量值(缩放到 pixel_size,返回 26.6 定点数)
|
||||
SSINT32 ttf_ascender (ttf_face_t* face, SUINT32 px) {
|
||||
return (SSINT32)(((SSINT64)face->os2_ascender * (SSINT64)px * 64) / face->units_per_em);
|
||||
}
|
||||
|
||||
+12
-13
@@ -1,13 +1,12 @@
|
||||
#include "ttf_internal.h"
|
||||
#include <string_utils.h>
|
||||
|
||||
// ---- Outline -> segments ----
|
||||
// 轮廓 → 线段转换
|
||||
//
|
||||
// TrueType contour walk: for each pair of consecutive points, emit either
|
||||
// a line or a quadratic bezier. Two consecutive off-curve points trigger
|
||||
// synthesis of an on-curve midpoint.
|
||||
// TrueType 轮廓遍历:对每对连续点,发射直线或二次贝塞尔曲线。
|
||||
// 两个连续的非曲线点会触发合成一个曲线中点。
|
||||
//
|
||||
// All coordinates remain in 26.6 fp throughout.
|
||||
// 所有坐标全程使用 26.6 定点数。
|
||||
void ttf_outline_to_segments(const ttf_outline_t* outline,
|
||||
ttf_seg_t* segs, SUINT32* num_segs)
|
||||
{
|
||||
@@ -92,7 +91,7 @@ void ttf_outline_to_segments(const ttf_outline_t* outline,
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Integer sqrt (Newton) ----
|
||||
// 整数平方根(牛顿法)
|
||||
static SUINT32 isqrt_u64(SUINT64 n) {
|
||||
if (n == 0) return 0;
|
||||
SUINT32 x = (n > 0xFFFFFFFFu) ? 0xFFFFu : (SUINT32)n;
|
||||
@@ -101,19 +100,19 @@ static SUINT32 isqrt_u64(SUINT64 n) {
|
||||
return x;
|
||||
}
|
||||
|
||||
// ---- Scanline fill with subpixel supersampling ----
|
||||
// 扫描线填充 + 子像素超采样
|
||||
//
|
||||
// For each output row, run N sub-scanlines at offsets (k+0.5)/N. For each
|
||||
// sub-scanline y, collect all x-intersections, sort, fill alternating
|
||||
// x-pairs. Sum over N subsamples yields per-pixel coverage in [0, N].
|
||||
// 对每个输出行,运行 N 条子扫描线,偏移为 (k+0.5)/N。
|
||||
// 对每条子扫描线 y,收集所有 x 交点,排序后交替填充 x 对。
|
||||
// 对 N 个子采样求和得到每个像素的覆盖率 [0, N]。
|
||||
void ttf_rasterize(const ttf_seg_t* segs, SUINT32 num_segs,
|
||||
SSINT32 x0, SSINT32 y0, SUINT32 w, SUINT32 h,
|
||||
SUINT8* coverage, SUINT32 N)
|
||||
{
|
||||
// Clear coverage
|
||||
// 清空覆盖率缓冲区
|
||||
for (SUINT32 i = 0; i < w * h; i++) coverage[i] = 0;
|
||||
|
||||
// Intersection x-buf (per scanline, max possible = num_segs)
|
||||
// 交点 x 缓冲区(每扫描线,最大可能数 = num_segs)
|
||||
f26_6 xs[2048];
|
||||
if (num_segs > 2048) num_segs = 2048;
|
||||
|
||||
@@ -222,6 +221,6 @@ void ttf_rasterize(const ttf_seg_t* segs, SUINT32 num_segs,
|
||||
}
|
||||
}
|
||||
}
|
||||
// (Alpha conversion happens at the caller via N.)
|
||||
// 覆盖率转换在调用端通过 N 完成
|
||||
(void)x0; (void)y0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user