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}
|
{@lang|en}
|
||||||
{@def|@font|{@quote|FreeSans|AR PL Kaiti M}}
|
{@def|@font|{@quote|FreeSans|AR PL UKai TW}}
|
||||||
{@def|@fontsize|12}
|
{@def|@fontsize|12}
|
||||||
therapy of communication and pronounciation123%comment
|
therapy of communication and pronounciation123%comment
|
||||||
|
|
||||||
|
|
100
src/interp.jl
100
src/interp.jl
|
@ -1,5 +1,10 @@
|
||||||
module Interp
|
module Interp
|
||||||
using Match
|
using Match
|
||||||
|
using Fontconfig
|
||||||
|
|
||||||
|
include("pdfoperating.jl")
|
||||||
|
using .PDFOperating
|
||||||
|
|
||||||
u = Main.uahgi
|
u = Main.uahgi
|
||||||
c = Main.uahgi.Parsing.Passes.Classes
|
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.SEQ([c.ELE([c.ID("def")]),
|
||||||
c.ELE([c.ID(id)]),val]) =>
|
c.ELE([c.ID(id)]),val]) =>
|
||||||
begin
|
begin
|
||||||
(val_evaled, env, res_box) = interp(val, env, res_box)
|
(val_evaled, env, res_box) = interp(val, env, res_box, false)
|
||||||
println("ID~~~", id, " VAL~~~", val_evaled)
|
#println("ID~~~", id, " VAL~~~", val_evaled)
|
||||||
env[id] = val_evaled
|
env[id] = val_evaled
|
||||||
return (val_evaled, env, res_box)
|
return (val_evaled, env, res_box)
|
||||||
end
|
end
|
||||||
|
@ -34,7 +39,7 @@ function interp(ast, env, res_box, put_char=true)
|
||||||
y...]) => begin
|
y...]) => begin
|
||||||
list = map(x -> x[1],
|
list = map(x -> x[1],
|
||||||
map(x -> interp(x, env, res_box), y))
|
map(x -> interp(x, env, res_box), y))
|
||||||
println("QUOTE", list)
|
#println("QUOTE", list)
|
||||||
return (list, env, res_box)
|
return (list, env, res_box)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -45,15 +50,40 @@ function interp(ast, env, res_box, put_char=true)
|
||||||
|
|
||||||
end
|
end
|
||||||
c.CHAR(ch) => begin
|
c.CHAR(ch) => begin
|
||||||
ret = ch
|
atomic_ch = ch[1]
|
||||||
|
|
||||||
if put_char == true
|
if put_char == true
|
||||||
push!(res_box.eles[end].eles,
|
|
||||||
#=TODO: check single-char size
|
font_idx = 1
|
||||||
env[""]
|
font_family = string(env["font"][font_idx])
|
||||||
=#
|
font_family_length = length(font_family)
|
||||||
u.ChBox(ch, "foo", 20, 1, 2, 3))
|
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
|
||||||
return (ret, env, res_box)
|
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,
|
||||||
|
u.ChBox(ch,
|
||||||
|
font_path,
|
||||||
|
font_size,
|
||||||
|
glyph_metrics.ht,
|
||||||
|
glyph_metrics.dp,
|
||||||
|
glyph_metrics.wd))
|
||||||
|
end
|
||||||
|
return (ch, env, res_box)
|
||||||
end
|
end
|
||||||
c.NL(nl) => return (nl, env, res_box)
|
c.NL(nl) => return (nl, env, res_box)
|
||||||
c.SPACE(sp) => return (sp, 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
|
||||||
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
|
end
|
|
@ -9,14 +9,14 @@ using TeX-like metrics, in px
|
||||||
- depth
|
- depth
|
||||||
"""
|
"""
|
||||||
struct CharMetrics
|
struct CharMetrics
|
||||||
height::Float64
|
ht::Float64
|
||||||
width::Float64
|
dp::Float64
|
||||||
depth::Float64
|
wd::Float64
|
||||||
end
|
end
|
||||||
|
|
||||||
#the default path is Noto Serif CJK Regular
|
#the default path is Noto Serif CJK Regular
|
||||||
default_font_path = "src/thirdParty/fonts/noto/NotoSerifTC-Regular.ttf"
|
#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/linuxLibertine/LinLibertine_Rah.ttf"
|
||||||
|
|
||||||
function createPDF()
|
function createPDF()
|
||||||
#=returns pdf=#
|
#=returns pdf=#
|
||||||
|
@ -93,7 +93,7 @@ function check_char_size(char, font_path, font_size, font_index=0)
|
||||||
library = Vector{FT_Library}(undef, 1)
|
library = Vector{FT_Library}(undef, 1)
|
||||||
error = FT_Init_FreeType(library)
|
error = FT_Init_FreeType(library)
|
||||||
face = Ref{FT_Face}()
|
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)
|
glyph_index = FT_Get_Char_Index(face[], char)
|
||||||
FT_Load_Glyph(face[], glyph_index, FT_LOAD_NO_SCALE)
|
FT_Load_Glyph(face[], glyph_index, FT_LOAD_NO_SCALE)
|
||||||
faceRec = unsafe_load(face[])
|
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
|
#from baseline down to the bottom of the glyph
|
||||||
depth = metricToPx(metrics.height - metrics.horiBearingY, font_size)
|
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
|
end
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -121,18 +118,18 @@ function metricToPx(metric, size_pt)
|
||||||
return metric * size_pt / 750
|
return metric * size_pt / 750
|
||||||
end
|
end
|
||||||
|
|
||||||
pdf = createPDF()
|
#pdf = createPDF()
|
||||||
page = addPage(pdf)
|
#page = addPage(pdf)
|
||||||
font = load_font(pdf, default_font_path)
|
#font = load_font(pdf, default_font_path)
|
||||||
put_text(page, "上下abc", font, 15, 100, 200)
|
#put_text(page, "上下abc", font, 15, 100, 200)
|
||||||
put_text(page, "天地人", font, 15, 200, 200)
|
#put_text(page, "天地人", font, 15, 200, 200)
|
||||||
|
|
||||||
save_pdf(pdf, "text.pdf")
|
#save_pdf(pdf, "text.pdf")
|
||||||
|
|
||||||
println("PDF generated.")
|
#println("PDF generated.")
|
||||||
check_char_size(
|
#check_char_size(
|
||||||
'j',
|
# '安',
|
||||||
default_font_path,
|
# default_font_path,
|
||||||
20)
|
# 20)
|
||||||
|
|
||||||
end
|
end
|
BIN
text.pdf
BIN
text.pdf
Binary file not shown.
Loading…
Reference in a new issue