Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compat with MathTeXEngine v0.5 #244

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
FreeTypeAbstraction = "663a7486-cb36-511b-a19d-713bb74d65c9"
Juno = "e5e0dc1b-0480-54bc-9374-aad01c23163d"
LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
MathTeXEngine = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
Rsvg = "c4c386cf-5103-5370-be45-f3a111cca3b8"
Expand Down
162 changes: 43 additions & 119 deletions src/latex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,6 @@ import .MathTeXEngine:
generate_tex_elements, inkwidth, inkheight, bottominkbound, TeXChar, HLine
using .LaTeXStrings

# the fonts we're using
mutable struct FontSpec
setfontname::String
fontfacename::String
vshift::Float64
end

mathbook = Luxor.FontSpec("NewComputerModern Math", "NewCMMath-Book", -0.05)
mathreg = Luxor.FontSpec("NewComputerModern Math", "NewCMMath-Regular", -0.05)
italic10 = Luxor.FontSpec("NewComputerModern Italic", "NewCM10-Italic", 0.0)
bold10 = Luxor.FontSpec("NewComputerModern Bold", "NewCM10-Bold", 0.0)
italic12 = Luxor.FontSpec("NewComputerModern Bold Italic", "NewCM10-BoldItalic", 0.0)
regular = Luxor.FontSpec("NewComputerModern Regular", "NewCM10-Regular", 0.0)

"""
_findlatexfont(t::FTFont)

Given the FreeTypeAbstraction.FTFont in `ftf`, return a suitable FontSpec.
"""
function _findlatexfont(ftf::FTFont)
if ftf.style_name == "Regular" && ftf.family_name == "NewComputerModern Math"
f = mathbook
elseif ftf.style_name == "10 Italic" && ftf.family_name == "NewComputerModern"
f = italic10
elseif ftf.style_name == "12 Italic" && ftf.family_name == "NewComputerModern"
f = italic12
elseif ftf.style_name == "Bold"
f = bold10
elseif ftf.style_name == "BoldItalic"
f = italic12
else
f = regular
end
return f
end

"""
texalign(halign, valign, bottom_pt, top_pt, font_size)

Expand Down Expand Up @@ -121,41 +85,40 @@ function latextextsize(lstr::LaTeXString)
end

"""
_write_tex_element(texchar, font_size)
_write_tex_element(texelement, font_size)

Draw the texchar as text. This uses the
Pro text API: `setfont()` and `settext()`
"""
function _write_tex_element(texelement, font_size)
texchar = first(texelement)
fontspec = _findlatexfont(texchar.font)
ch = texchar.represented_char
fscale = last(texelement)
spt = Point(texelement[2]...)
setfont(fontspec.setfontname, font_size * fscale)
Luxor.settext(string(ch), spt * font_size * (1, -1) + (0, fontspec.vshift * font_size))
end
function _write_tex_element(texchar::TeXChar, pos, fscale, font_size ; paths=false)
setfont(texchar.font, font_size * fscale)
x = pos[1] * font_size
y = -pos[2] * font_size
cg = Cairo.CairoGlyph(texchar.glyph_id, x, y)

"""
_write_tex_as_path(texchar, font_size)
@show paths
@show texchar

Add the texchar to the current path. This
uses the Toy text API: `fontface()` and `fontsize()`.
"""
function _write_tex_as_path(texelement, font_size)
texchar = first(texelement)
fontspec = _findlatexfont(texchar.font)
ch = texchar.represented_char
fscale = last(texelement)
spt = Point(texelement[2]...)
if paths
newsubpath()
Cairo.glyph_path(get_current_cr(), cg)
do_action(:stroke)
else
Cairo.show_glyph(get_current_cr(), cg)
end
end

fontface(fontspec.fontfacename)
fontsize(font_size * fscale)
newsubpath()
Luxor.textoutlines(string(ch),
spt * font_size * (1, -1),
action = :path,
startnewpath = false)
function _write_tex_element(hline::HLine, pos, fscale, font_size ; paths=false)
spt = Point(pos...) * font_size
linestart = spt * (fscale, -fscale)
lineend = linestart + (hline.width * font_size, hline.thickness * font_size)

if paths
box(linestart, lineend, :path)
newsubpath()
else
box(linestart, lineend, :fill)
end
end

"""
Expand Down Expand Up @@ -193,67 +156,28 @@ function text(lstr::LaTeXString, pt::Point;
rotationfixed = false,
paths = false,
kwargs...)
@show lstr
@show paths
# with MathTexEngine.generate_tex_elements
sentence = Luxor.generate_tex_elements(lstr)
# get current font size
font_size = get_fontsize()
textw, texth = Luxor.latextextsize(lstr)
bottom_pt, top_pt = Luxor.rawlatexboundingbox(lstr)
translate_x, translate_y = Luxor.texalign(halign, valign, bottom_pt, top_pt, font_size)
if paths == true
# TODO reduce repeated code ...
for texelement in sentence
@layer begin
translate(pt)
if !rotationfixed
rotate(angle)
translate(translate_x, translate_y)
else
l_pt, r_pt = Luxor.latexboundingbox(lstr, halign = halign, valign = valign)
translate((l_pt + r_pt) / 2)
rotate(angle)
translate(Point(translate_x, translate_y) - (l_pt + r_pt) / 2)
end
if first(texelement) isa TeXChar
_write_tex_as_path(texelement, font_size)
elseif first(texelement) isa HLine
hline = texelement[1]
spt = Point(texelement[2]...)
linestart = spt * font_size * (1, -1)
lineend = linestart + (hline.width * font_size, hline.thickness * font_size)
box(linestart, lineend, :path)
newsubpath()
elseif first(texelement) isa VLine
# todo
end
end # layer
end # for
else
for texelement in sentence
@layer begin
translate(pt)
if !rotationfixed
rotate(angle)
translate(translate_x, translate_y)
else
l_pt, r_pt = Luxor.latexboundingbox(lstr, halign = halign, valign = valign)
translate((l_pt + r_pt) / 2)
rotate(angle)
translate(Point(translate_x, translate_y) - (l_pt + r_pt) / 2)
end
if first(texelement) isa TeXChar
_write_tex_element(texelement, font_size)
elseif first(texelement) isa HLine
hline = texelement[1]
spt = (Point(texelement[2]...) + (0, 0.25)) * font_size
fscale = last(texelement)
linestart = spt * (fscale, -fscale)
lineend = linestart + (hline.width * font_size, hline.thickness * font_size)
box(linestart, lineend, :fill)
elseif first(texelement) isa VLine
# todo
end
end # layer

for (texelement, pos, scale) in sentence
@layer begin
translate(pt)
if !rotationfixed
rotate(angle)
translate(translate_x, translate_y)
else
l_pt, r_pt = Luxor.latexboundingbox(lstr, halign = halign, valign = valign)
translate((l_pt + r_pt) / 2)
rotate(angle)
translate(Point(translate_x, translate_y) - (l_pt + r_pt) / 2)
end
_write_tex_element(texelement, pos, scale, font_size ; paths)
end
end
end
Expand Down
7 changes: 7 additions & 0 deletions src/text.jl
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,13 @@ function setfont(family::T where T <: AbstractString, fontsize)
set_font_face(get_current_cr(), string(family, " ", fsize))
end

function setfont(ftfont::FTFont, fontsize)
fsize = fontsize * 72/96
set_font_size(get_current_cr(), fsize)
set_font_face(get_current_cr(), ftfont)
end


"""
settext(text, pos;
halign = "left",
Expand Down