diff --git a/Project.toml b/Project.toml index 5e6fd6fb..9578ffe1 100644 --- a/Project.toml +++ b/Project.toml @@ -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" diff --git a/src/latex.jl b/src/latex.jl index f9e92df9..bb6772aa 100644 --- a/src/latex.jl +++ b/src/latex.jl @@ -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) @@ -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 """ @@ -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 diff --git a/src/text.jl b/src/text.jl index 422accd2..341776e9 100644 --- a/src/text.jl +++ b/src/text.jl @@ -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",