2022-02-22 (Tu) [長年日記]
_ iPhone 13
36回払いに対応だそうで、乗り換えしやすくなったんだそうで?
そうなん?
例えば 10万だとしようか。
¥100,000 / 36 = ¥2,777
2700円を3年も払い続けるんか? 月額として決して安くはないと思うんだけど、 なんでそんなにいつまでも払わされにゃならんの?
まぁ、そっちを選ぶ人はいるんだろうけど、私の感覚ではよく解らん。
_ freetype2 文字幅問題
微妙に 半角:全角 = 1:2 にならない問題。
https://freetype.org/freetype2/docs/tutorial/step2.html
linearHoriAdvance っていうメンバがあるそうな。 16.16 fixed-point number って言うらしい。
今まで私が使ってたのは 26.6 らしい。
16.16 で試してみた。
#include <ft2build.h>
#include FT_FREETYPE_H
#include <freetype/ftimage.h>
#include <freetype/ftdriver.h>
#include <freetype/ftmodapi.h>
#include <math.h>
static unsigned int text[] = {
0x00003042, 0x00003044, 0x00003046, 0x00003048,
0x0000304a, 0x0000304b, 0x0000304d, 0x0000304f,
0x00003051, 0x00003053, 0x00003055, 0x00003057,
0x00003059, 0x0000305b, 0x0000305d, 0x0000305f,
0x00003061, 0x00003064, 0x00003066, 0x00003068,
#if 0
0x00003042, 0x00003044, 0x00003046, 0x00003048,
0x0000304a, 0x0000304b, 0x0000304d, 0x0000304f,
0x00003051, 0x00003053, 0x00003055, 0x00003057,
0x00003059, 0x0000305b, 0x0000305d, 0x0000305f,
0x00003061, 0x00003064, 0x00003066, 0x00003068,
#endif
0x0000000a,
0x00000061, 0x00000062, 0x00000063, 0x00000064,
0x00000065, 0x00000066, 0x00000067, 0x00000068,
0x00000069, 0x0000006a, 0x0000006b, 0x0000006c,
0x0000006d, 0x0000006e, 0x0000006f, 0x00000070,
0x00000071, 0x00000072, 0x00000073, 0x00000074,
0x00000075, 0x00000076, 0x00000077, 0x00000078,
0x00000079, 0x0000007a,
0x00000061, 0x00000062, 0x00000063, 0x00000064,
0x00000065, 0x00000066, 0x00000067, 0x00000068,
0x00000069, 0x0000006a, 0x0000006b, 0x0000006c,
0x0000006d, 0x0000006e,
#if 0
0x0000006f, 0x00000070,
0x00000071, 0x00000072, 0x00000073, 0x00000074,
0x00000075, 0x00000076, 0x00000077, 0x00000078,
0x00000079, 0x0000007a,
#endif
0x0000000a,
};
#define LEN (sizeof text / sizeof text[0])
#define WIDTH 1024
#define HEIGHT 256
#define LEFT 16
#define TOP 128
static unsigned char paper[HEIGHT][WIDTH];
static void draw(FT_Bitmap *bitmap, int x, int y)
{
for (int j = 0; j < bitmap->rows; j++) {
for (int i = 0; i < bitmap->width; i++) {
unsigned char c = bitmap->buffer[j * bitmap->pitch + i];
if (c) {
if (y + j >= 0 && y + j < HEIGHT) {
if (x + i >= 0 && x + i < WIDTH)
paper[y + j][x + i] = 255;
}
}
}
}
}
int main(void)
{
FT_Library library;
int error;
error = FT_Init_FreeType(&library);
if (error) {
fprintf(stderr, "ft init error\n");
exit(1);
}
FT_UInt hinting_engine = FT_HINTING_FREETYPE;
FT_Property_Set(library, "cff",
"hinting-engine", &hinting_engine);
FT_Face face;
error = FT_New_Face(
library,
"/usr/share/fonts/TTF/NasuM-Regular-20141215.ttf",
0,
&face);
if (error) {
fprintf(stderr, "new face error\n");
exit(1);
}
error = FT_Set_Char_Size(
face,
0,
8 * 64,
300,
300);
if (error) {
fprintf(stderr, "set size error\n");
exit(1);
}
#define GETA(x) ((x) << 16)
#define UGETA(x) ((x) >> 16)
FT_Vector pen;
pen.x = GETA(LEFT);
pen.y = GETA(TOP);
unsigned int idces[LEN];
for (int i = 0; i < LEN; i++) {
if (text[i] == '\n') {
fprintf(stderr, "%ld\n", pen.x);
pen.x = GETA(LEFT);
pen.y += GETA(24);
continue;
}
idces[i] = FT_Get_Char_Index(face, text[i]);
error = FT_Load_Glyph(
face,
idces[i],
0 |
FT_LOAD_DEFAULT | // x
// FT_LOAD_NO_HINTING | // o
// FT_LOAD_PEDANTIC | // x
// FT_LOAD_NO_AUTOHINT | // x
0);
if (error) {
fprintf(stderr, "no glyph error\n");
exit(1);
}
error = FT_Render_Glyph(
face->glyph,
FT_RENDER_MODE_NORMAL);
if (error) {
fprintf(stderr, "glyph render error\n");
exit(1);
}
draw(&face->glyph->bitmap,
UGETA(pen.x) + face->glyph->bitmap_left,
UGETA(pen.y) - face->glyph->bitmap_top);
pen.x += face->glyph->linearHoriAdvance;
}
fprintf(stderr, "\n");
printf("P3\n%d %d\n%d\n", WIDTH, HEIGHT, 255);
for (int y = 0; y < HEIGHT; y++) {
for (int x = 0; x < WIDTH; x++) {
if (paper[y][x]) {
printf("%d %d %d ", 255, 255, 255);
} else {
printf("%d %d %d ", 0, 0, 0);
}
printf("\n");
}
}
}
結果、
綺麗に横幅が一致! やほ〜〜い!!
26.6 だと正確に表現できなくて丸め誤差が蓄積していってたらしい。
でもこれを Emacs に載せるのは無理かなぁ。 各文字は pixel に align されてる前提なんだよね。
(/ 2184192 65536.0)
33.328125
(/ 1092096 65536.0)
16.6640625
↑これが文字幅。全角 33.3 px、半角 16.7 px。 両方切り上げれば合うのか?
んー合わない。
Emacs のフォント計算ってかなり面倒だよね… 文字をどこにでも表示できなきゃいけないし、 いろんな driver で各 metrics を同じ意味で 使えなきゃいけないし、 仕方ないんだろうなぁ。
[ツッコミを入れる]