From 6190fb28b793f7fad40f2e78f3d21152f7165c55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Richard?= Date: Mon, 3 Oct 2022 18:27:29 +0200 Subject: [PATCH 1/4] Use MTX fonts directly --- Project.toml | 1 + src/latex.jl | 15 +++++++-------- src/text.jl | 7 +++++++ 3 files changed, 15 insertions(+), 8 deletions(-) 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..f4980a02 100644 --- a/src/latex.jl +++ b/src/latex.jl @@ -126,14 +126,13 @@ end 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)) +function _write_tex_element((texchar, pos, fscale), font_size) + setfont(texchar.font, font_size * fscale) + x = pos[1] * font_size + y = -pos[2] * font_size + Cairo.show_glyph( + get_current_cr(), + Cairo.CairoGlyph(texchar.glyph_id, x, y)) 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", From e859fcd47ce1ce944fbd3d51af711063caf574d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Richard?= Date: Thu, 6 Oct 2022 15:22:21 +0200 Subject: [PATCH 2/4] Remove unused font code --- src/latex.jl | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/src/latex.jl b/src/latex.jl index f4980a02..1e967783 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) From f778f21460b1518394fe25fe5946ee1010d9dfcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Richard?= Date: Thu, 6 Oct 2022 15:32:20 +0200 Subject: [PATCH 3/4] Fix fraction line --- src/latex.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/latex.jl b/src/latex.jl index 1e967783..088eab3c 100644 --- a/src/latex.jl +++ b/src/latex.jl @@ -208,7 +208,7 @@ function text(lstr::LaTeXString, pt::Point; _write_tex_element(texelement, font_size) elseif first(texelement) isa HLine hline = texelement[1] - spt = (Point(texelement[2]...) + (0, 0.25)) * font_size + spt = Point(texelement[2]...) * font_size fscale = last(texelement) linestart = spt * (fscale, -fscale) lineend = linestart + (hline.width * font_size, hline.thickness * font_size) From 0fbc5b4ddf9e38b4eb7799bf4bda9fb30c53adbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Richard?= Date: Sat, 8 Oct 2022 19:53:52 +0200 Subject: [PATCH 4/4] Clean up and add paths --- src/latex.jl | 119 +++++++++++++++++---------------------------------- 1 file changed, 40 insertions(+), 79 deletions(-) diff --git a/src/latex.jl b/src/latex.jl index 088eab3c..bb6772aa 100644 --- a/src/latex.jl +++ b/src/latex.jl @@ -85,40 +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((texchar, pos, fscale), font_size) +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 - Cairo.show_glyph( - get_current_cr(), - Cairo.CairoGlyph(texchar.glyph_id, x, y)) + cg = Cairo.CairoGlyph(texchar.glyph_id, x, y) + + @show paths + @show texchar + + if paths + newsubpath() + Cairo.glyph_path(get_current_cr(), cg) + do_action(:stroke) + else + Cairo.show_glyph(get_current_cr(), cg) + end end -""" - _write_tex_as_path(texchar, font_size) +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) -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]...) - - fontface(fontspec.fontfacename) - fontsize(font_size * fscale) - newsubpath() - Luxor.textoutlines(string(ch), - spt * font_size * (1, -1), - action = :path, - startnewpath = false) + if paths + box(linestart, lineend, :path) + newsubpath() + else + box(linestart, lineend, :fill) + end end """ @@ -156,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]...) * 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