add the method to measure the char's metrics
Some checks are pending
CI / Julia 1.6 - ubuntu-latest - x64 (push) Waiting to run
CI / Julia 1.7 - ubuntu-latest - x64 (push) Waiting to run
CI / Julia pre - ubuntu-latest - x64 (push) Waiting to run

This commit is contained in:
Tan, Kian-ting 2025-01-29 16:07:26 +08:00
parent 5b8bf872a2
commit eb3f1967aa
4 changed files with 109 additions and 32 deletions

View file

@ -1,5 +1,5 @@
{@lang|en}
{@def|@font|{@quote|FreeSans|AR PL Kaiti M}}
{@def|@font|{@quote|FreeSans|AR PL UKai TW}}
{@def|@fontsize|12}
therapy of communication and pronounciation123%comment

View file

@ -1,5 +1,10 @@
module Interp
using Match
using Fontconfig
include("pdfoperating.jl")
using .PDFOperating
u = Main.uahgi
c = Main.uahgi.Parsing.Passes.Classes
@ -25,8 +30,8 @@ function interp(ast, env, res_box, put_char=true)
c.SEQ([c.ELE([c.ID("def")]),
c.ELE([c.ID(id)]),val]) =>
begin
(val_evaled, env, res_box) = interp(val, env, res_box)
println("ID~~~", id, " VAL~~~", val_evaled)
(val_evaled, env, res_box) = interp(val, env, res_box, false)
#println("ID~~~", id, " VAL~~~", val_evaled)
env[id] = val_evaled
return (val_evaled, env, res_box)
end
@ -34,7 +39,7 @@ function interp(ast, env, res_box, put_char=true)
y...]) => begin
list = map(x -> x[1],
map(x -> interp(x, env, res_box), y))
println("QUOTE", list)
#println("QUOTE", list)
return (list, env, res_box)
end
@ -45,16 +50,41 @@ function interp(ast, env, res_box, put_char=true)
end
c.CHAR(ch) => begin
ret = ch
atomic_ch = ch[1]
if put_char == true
font_idx = 1
font_family = string(env["font"][font_idx])
font_family_length = length(font_family)
while !is_in_font(atomic_ch, font_family)
if font_idx <= font_family_length
font_idx += 1
font_family = string(env["font"][font_idx])
else
font_list = string(env["font"])
throw("the chars $atomic_ch is not contained in all the fonts
listed in listed fonts: $font_list")
end
end
font_path = get_font_path(font_family)
font_size = parse(Int, env["fontsize"])
glyph_metrics = PDFOperating.check_char_size(
atomic_ch, font_path, font_size)
push!(res_box.eles[end].eles,
#=TODO: check single-char size
env[""]
=#
u.ChBox(ch, "foo", 20, 1, 2, 3))
u.ChBox(ch,
font_path,
font_size,
glyph_metrics.ht,
glyph_metrics.dp,
glyph_metrics.wd))
end
return (ret, env, res_box)
end
return (ch, env, res_box)
end
c.NL(nl) => return (nl, env, res_box)
c.SPACE(sp) => return (sp, env, res_box)
@ -66,4 +96,54 @@ function interp(ast, env, res_box, put_char=true)
end
end
function get_font_path(font_family)
ptn = Fontconfig.Pattern(family=font_family)
matched = Fontconfig.match(ptn)
path = match(r"file=([^:]+)", string(matched))[1]
return path
end
"""
check if the glyph of a char is contained by `font_family`
"""
function is_in_font(char, font_family)
ptn = Fontconfig.Pattern(family=font_family)
matched = Fontconfig.match(ptn)
charset = match(r"charset=([^:]+)", string(matched))[1]
splitted1 = split(charset, " ")
splitted2 = map(x -> split(x, "-"), splitted1)
"""aux function"""
regex_aux(x) = map(y -> padding_zero(y), x)
x1 = map(x -> regex_aux(x), splitted2)
x2 = map(x -> length(x) == 1 ? "\\u" * x[1] : "\\u" * x[1] * "-\\u" * x[2] , x1)
regex_final = "[" * reduce((x,y)-> x*""*y, x2) * "]"
regex_final_wrapped = Regex(regex_final)
if match(regex_final_wrapped, string(char)) !== nothing
return true
else
return false
end
end
"""
padding zero for a hex-digit string `i` to make it a 4-digit.
- "27" -> "0027"
- "8af" -> "08af"
"""
function padding_zero(i)
if length(i) == 2
i="00"*i
end
if length(i)==3
i="0"*i
end
return i
end
end

View file

@ -9,14 +9,14 @@ using TeX-like metrics, in px
- depth
"""
struct CharMetrics
height::Float64
width::Float64
depth::Float64
ht::Float64
dp::Float64
wd::Float64
end
#the default path is Noto Serif CJK Regular
default_font_path = "src/thirdParty/fonts/noto/NotoSerifTC-Regular.ttf"
#default_font_path = "src/thirdParty/fonts/linuxLibertine/LinLibertine_Rah.ttf"
#default_font_path = "src/thirdParty/fonts/noto/NotoSerifTC-Regular.ttf"
default_font_path = "src/thirdParty/fonts/linuxLibertine/LinLibertine_Rah.ttf"
function createPDF()
#=returns pdf=#
@ -93,7 +93,7 @@ function check_char_size(char, font_path, font_size, font_index=0)
library = Vector{FT_Library}(undef, 1)
error = FT_Init_FreeType(library)
face = Ref{FT_Face}()
FT_New_Face(library[1], font_path, font_index, face);
FT_New_Face(library[1], string(font_path), 0, face)
glyph_index = FT_Get_Char_Index(face[], char)
FT_Load_Glyph(face[], glyph_index, FT_LOAD_NO_SCALE)
faceRec = unsafe_load(face[])
@ -107,11 +107,8 @@ function check_char_size(char, font_path, font_size, font_index=0)
#from baseline down to the bottom of the glyph
depth = metricToPx(metrics.height - metrics.horiBearingY, font_size)
println("width ", width, "px")
println("height ", height, "px")
println("depth ", depth, "px")
return CharMetrics(height, width, depth)
return CharMetrics(height, depth, width)
end
"""
@ -121,18 +118,18 @@ function metricToPx(metric, size_pt)
return metric * size_pt / 750
end
pdf = createPDF()
page = addPage(pdf)
font = load_font(pdf, default_font_path)
put_text(page, "上下abc", font, 15, 100, 200)
put_text(page, "天地人", font, 15, 200, 200)
#pdf = createPDF()
#page = addPage(pdf)
#font = load_font(pdf, default_font_path)
#put_text(page, "上下abc", font, 15, 100, 200)
#put_text(page, "天地人", font, 15, 200, 200)
save_pdf(pdf, "text.pdf")
#save_pdf(pdf, "text.pdf")
println("PDF generated.")
check_char_size(
'j',
default_font_path,
20)
#println("PDF generated.")
#check_char_size(
# '安',
# default_font_path,
# 20)
end

BIN
text.pdf

Binary file not shown.