Skip to content
Merged
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
4 changes: 2 additions & 2 deletions .github/workflows/Copier.yml_deactivate
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Copier Update

on:
schedule:
- cron: 0 7 1/7 * * # Every 7 days at 7:00 UTC
- cron: 0 7 1/7 * * # Every 7 days at 7:00 UTC
workflow_dispatch:

jobs:
Expand All @@ -24,7 +24,7 @@ jobs:
- name: Setup Python
uses: actions/setup-python@v5
with:
cache: 'pip'
cache: "pip"
python-version: "3.11"
- name: Hack for setup-python cache # https://github.com/actions/setup-python/issues/807
run: rm requirements.txt
Expand Down
254 changes: 142 additions & 112 deletions src/fontOnCurve.jl
Original file line number Diff line number Diff line change
@@ -1,125 +1,155 @@
"""
Code written mostly by Julius Krumbiegel with some modifications by Benedikt Ehinger
"""
struct TextOnPath
text::String
path::Makie.BezierPath
end

function Makie._get_glyphcollection_and_linesegments(top::TextOnPath, index, ts, f, fs, al, rot, jus, lh, col, scol, swi, www, offs)
gc = Makie.layout_text(top, ts, f, fs, al, rot, jus, lh, col, scol, swi)
gc, Point2f[], Float32[], RGBAf[], Int[]
struct TextOnPath
text::String
path::Makie.BezierPath
end

function Makie._get_glyphcollection_and_linesegments(
top::TextOnPath,
index,
ts,
f,
fs,
al,
rot,
jus,
lh,
col,
scol,
swi,
www,
offs,
)
gc = Makie.layout_text(top, ts, f, fs, al, rot, jus, lh, col, scol, swi)
gc, Point2f[], Float32[], RGBAf[], Int[]
end

"""
returns the attribute per character - if the length of the attribute does not equal to the length of the string, AND it equals to the number of points from the BezierPath - we will use the attribute per segment (until a MoveTo / NaN segment)

Note: currently only works for LineTo and MoveTo - not Curve, as Curve interpolates 30points per curve!
"""
attribute_per_char_or_segment(string, attr, lengthPoints) =
Makie.attribute_per_char(string, attr)
function attribute_per_char_or_segment(string, attr::AbstractVector, lengthPoints)

if (length(attr) !== length(string)) & (length(attr) == lengthPoints)
@assert all(isa.([MoveTo(1, 2), LineTo(1, 2)], Union{MoveTo,LineTo})) "Currently no support for BezierSegments other than MoveTo and LineTo"
return attr
else
return Makie.attribute_per_char(string, attr)

end

"""
returns the attribute per character - if the length of the attribute does not equal to the length of the string, AND it equals to the number of points from the BezierPath - we will use the attribute per segment (until a MoveTo / NaN segment)

Note: currently only works for LineTo and MoveTo - not Curve, as Curve interpolates 30points per curve!
"""
attribute_per_char_or_segment(string,attr,lengthPoints) = Makie.attribute_per_char(string,attr)
function attribute_per_char_or_segment(string,attr::AbstractVector,lengthPoints)

if (length(attr) !== length(string) ) & (length(attr) == lengthPoints)
@assert all(isa.([MoveTo(1,2),LineTo(1,2)],Union{MoveTo,LineTo})) "Currently no support for BezierSegments other than MoveTo and LineTo"
return attr
end
function Makie.layout_text(top::TextOnPath, ts, f, fs, al, rot, jus, lh, col, scol, swi)
points = only(Makie.convert_arguments(PointBased(), top.path))

ft_font = Makie.to_font(f)
rscale = Makie.to_fontsize(ts)


colors = attribute_per_char_or_segment(top.text, col, length(points))
strokecolors = attribute_per_char_or_segment(top.text, scol, length(points))
strokewidths = attribute_per_char_or_segment(top.text, swi, length(points))
fonts = attribute_per_char_or_segment(top.text, ft_font, length(points))
fontsizes = attribute_per_char_or_segment(top.text, rscale, length(points))

gc = glyph_collection_on_path(
points,
top.text,
fonts,
fontsizes,
colors,
strokecolors,
strokewidths,
)
end

function glyph_collection_on_path(
points,
text,
fonts,
fontsizes,
colors,
strokecolors,
strokewidths,
)
glyphinfos = Makie.GlyphInfo[]

seg = 1
at_fraction::Float64 = 0.0


get_attr(attr::Base.Generator, ix_char, seg) = collect(attr)[1]
get_attr(attr, ix_char, seg) = attr


function get_attr(attr::AbstractVector, ix_char, seg)

if length(attr) == length(text)
return attr[ix_char]
else
return Makie.attribute_per_char(string,attr)

return attr[seg]
end
end
function Makie.layout_text(top::TextOnPath, ts, f, fs, al, rot, jus, lh, col, scol, swi)
points = only(Makie.convert_arguments(PointBased(), top.path))

ft_font = Makie.to_font(f)
rscale = Makie.to_fontsize(ts)


colors = attribute_per_char_or_segment(top.text,col,length(points))
strokecolors = attribute_per_char_or_segment(top.text,scol,length(points))
strokewidths = attribute_per_char_or_segment(top.text,swi,length(points))
fonts = attribute_per_char_or_segment(top.text, ft_font,length(points))
fontsizes = attribute_per_char_or_segment(top.text, rscale,length(points))

gc = glyph_collection_on_path(points, top.text, fonts, fontsizes,colors,strokecolors,strokewidths)
end

function glyph_collection_on_path(points, text, fonts, fontsizes,colors,strokecolors,strokewidths)
glyphinfos = Makie.GlyphInfo[]

seg = 1
at_fraction::Float64 = 0.0


get_attr(attr::Base.Generator,ix_char,seg) = collect(attr)[1]
get_attr(attr,ix_char,seg) = attr


function get_attr(attr::AbstractVector,ix_char,seg)

if length(attr) == length(text)
return attr[ix_char]
else
return attr[seg]
for (ix_char, char) in enumerate(collect(text))

font = get_attr(fonts, ix_char, seg)
fontsize = get_attr(fontsizes, ix_char, seg)
strokecolor = get_attr(strokecolors, ix_char, seg)
strokewidth = get_attr(strokewidths, ix_char, seg)
color = get_attr(colors, ix_char, seg)

v = points[seg+1] - points[seg]
p = points[seg] + v * at_fraction

ext = Makie.GlyphExtent(font, char)
sz = Vec2f(fontsize, fontsize)

hadvance = ext.hadvance * sz[1]

# find next point
accumulated = 0.0
while true
if isnan(points[seg+1]) | isnan(points[seg])
seg += 1
continue
end
end
for (ix_char,char) in enumerate(collect(text))

font = get_attr(fonts,ix_char,seg)
fontsize = get_attr(fontsizes,ix_char,seg)
strokecolor = get_attr(strokecolors,ix_char,seg)
strokewidth = get_attr(strokewidths,ix_char,seg)
color = get_attr(colors,ix_char,seg)

v = points[seg+1] - points[seg]
p = points[seg] + v * at_fraction

ext = Makie.GlyphExtent(font, char)
sz = Vec2f(fontsize, fontsize)

hadvance = ext.hadvance * sz[1]

# find next point
accumulated = 0.0
while true
if isnan(points[seg+1]) | isnan(points[seg])

seglength = Makie.norm(points[seg+1] - points[seg])
remaining_this_seg = (1 - at_fraction) * seglength
to_go = hadvance - (accumulated + remaining_this_seg)
if to_go <= 0
at_fraction = 1 - (-to_go / seglength)
break
else
accumulated += remaining_this_seg
at_fraction = 0.0
if seg < length(points) - 1
seg += 1
continue
end

seglength = Makie.norm(points[seg+1] - points[seg])
remaining_this_seg = (1 - at_fraction) * seglength
to_go = hadvance - (accumulated + remaining_this_seg)
if to_go <= 0
at_fraction = 1 - (-to_go / seglength)
break
else
accumulated += remaining_this_seg
at_fraction = 0.0
if seg < length(points)-1
seg += 1
end
end
end

gi = Makie.GlyphInfo(
Makie.FreeTypeAbstraction.glyph_index(font, char),
font,
p,
ext,
sz,
Makie.to_rotation(reverse(v) .* (-1, 1)),
color,
strokecolor,
strokewidth,
)
push!(glyphinfos, gi)
if seg >= length(points)-1
@warn "Could not fit all characters on path, you could reduce the fontsize"
break
end
end
#@show seg, size(glyphinfos)
return Makie.GlyphCollection(glyphinfos)

gi = Makie.GlyphInfo(
Makie.FreeTypeAbstraction.glyph_index(font, char),
font,
p,
ext,
sz,
Makie.to_rotation(reverse(v) .* (-1, 1)),
color,
strokecolor,
strokewidth,
)
push!(glyphinfos, gi)
if seg >= length(points) - 1
@warn "Could not fit all characters on path, you could reduce the fontsize"
break
end
end


#@show seg, size(glyphinfos)
return Makie.GlyphCollection(glyphinfos)
end
14 changes: 7 additions & 7 deletions src/importpdf.jl
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
function getPDFText(src; pages=nothing)
function getPDFText(src; pages = nothing)
# handle that can be used for subsequence operations on the document.
doc = pdDocOpen(src)

# Metadata extracted from the PDF document.
# This value is retained and returned as the return from the function.
# Metadata extracted from the PDF document.
# This value is retained and returned as the return from the function.
docinfo = pdDocGetInfo(doc)
io = IOBuffer()

# Returns number of pages in ithe document
# Returns number of pages in ithe document
#
if isnothing(pages)

pages = 1:pdDocGetPageCount(doc)
end
for i = pages
for i in pages
@info "processing page $i"
try
# handle to the specific page given the number index.
# handle to the specific page given the number index.
page = pdDocGetPage(doc, i)

# Extract text from the page and write it to the output file.
Expand All @@ -26,7 +26,7 @@ function getPDFText(src; pages=nothing)
end
end

# Close the document handle.
# Close the document handle.
# The doc handle should not be used after this call
pdDocClose(doc)
return io
Expand Down
Loading
Loading