add the method to measure the char's metrics
This commit is contained in:
parent
5b8bf872a2
commit
eb3f1967aa
4 changed files with 109 additions and 32 deletions
|
@ -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
|
||||
|
||||
|
|
100
src/interp.jl
100
src/interp.jl
|
@ -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
|
|
@ -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
BIN
text.pdf
Binary file not shown.
Loading…
Reference in a new issue