juliagraphics / freetypeabstraction.jl Goto Github PK
View Code? Open in Web Editor NEWA Julian abstraction layer over FreeType.jl
License: Other
A Julian abstraction layer over FreeType.jl
License: Other
The example code in README.md has x0 before y0 in renderstring!, but the function accepts y0 before x0.
I've been trying to figure out how to obtain the height and the width of a char, but after reading the code, it's not clear to me how to do this.
Consider the following char and font:
'X': ASCII/Unicode U+0058 (category Lu: Letter, uppercase)
FTFont (family = cmex10, style = Regular)
I've tried using height_insensitive_boundingbox()
to get the dimensions. But it only worked with the width, and not the height.
FWIW,
https://github.com/JuliaGraphics/FreeTypeAbstraction.jl/blob/v0.6.0/Project.toml
claims FreeType = "2, 3"
, but is using FreeType.LibFreeType
on line
https://github.com/JuliaGraphics/FreeTypeAbstraction.jl/blob/v0.6.0/src/types.jl#L152
That is only available in FreeType v3 since
https://github.com/JuliaGraphics/FreeType.jl/blob/v3.0.0/src/FreeType.jl#L4
says using .LibFreeType
.
Some characters in some fonts have multiple glyph that can represent them. Typically the integral sign in math font has one version for inline math and one one for block equations.
Currently, it looks like the alternate glyph can be retrieved as follow:
julia> font = FTFont("assets/fonts/NewCMMath-Regular.otf")
FTFont(Ptr{FreeType.__JL_FT_FaceRec_} @0x000000001e67a810, true, Dict{Char, FontExtent{Float32}}())
julia> glyph_id = FT_Get_Name_Index(font, "integral.v1")
0x0000172a
julia> res = FT_Load_Glyph(font, glyph_id, FT_LOAD_NO_SCALE)
0
So I guess that adding methods to get_extent
, get_extent_internal
and load_char
to load from a glyph name may do the trick.
Ideally it would be good to retrieve the information on whether a char has alternate glyphs directly from the font, but I am no sure FreeType support that.
a version of julia should be specified. shall we say 0.5?
also, is FixedSizeArrays really a dependency? i see no reference to it.
findfont
works well, but takes several seconds - which may be considered fast, considering - here (openSUSE Leap-15.3),
but led to the significant system-dependent overhead found in cesaraustralia/DynamicGrids.jl#194 (comment).
findfont
is always scanning all fonts, opening them
to get their name and properties and find the best one.
The issue is that on my system there were over 10_000 fonts installed, most quick to load (median about 7.5 µs),
but some taking much longer (see the diagnosis histogram), so the average is about 270 µs.
using FreeTypeAbstraction: fontpaths, try_load, match_font
font_folders = copy(fontpaths())
t1_ = Float64[]
path_ = String[]
@time for folder in font_folders
for font in readdir(folder)
fpath = joinpath(folder, font)
t1 = @elapsed face = try_load(fpath)
push!(t1_, t1)
push!(path_, fpath)
face === nothing && continue
finalize(face)
end
end
2.855721 seconds (159.18 k allocations: 23.692 MiB)
julia> sum(t1_)
2.832251035
julia> using UnicodePlots
julia> histogram(t1_)
┌ ┐
[0.0 , 0.001) ┤█████████████████████████████████ 10063
[0.001, 0.002) ┤▌ 151
[0.002, 0.003) ┤▍ 83
[0.003, 0.004) ┤▎ 32
[0.004, 0.005) ┤▏ 4
[0.005, 0.006) ┤▏ 14
[0.006, 0.007) ┤▏ 7
[0.007, 0.008) ┤▏ 15
[0.008, 0.009) ┤▏ 9
[0.009, 0.01 ) ┤▏ 1
[0.01 , 0.011) ┤▏ 3
[0.011, 0.012) ┤ 0
[0.012, 0.013) ┤▏ 7
[0.013, 0.014) ┤▏ 1
[0.014, 0.015) ┤▏ 1
└ ┘
Frequency
julia> using Statistics
julia> mean(t1_)
0.00027256770618804736
julia> median(t1_)
7.4702e-5
There are several solutions on the other side (e.g. removing slow fonts, using FTFont(font_path)
to load the specific font directly).
But it might be nice to have a kind of cache so that findfont(font_name)
would be even faster on subsequent calls ?
I was recently thinking of trying something other than a cache to speed up findfont
(it takes ~1.5s on my machine), but in the process noticed that it seems to be picking the wrong font??
julia> FreeTypeAbstraction.findfont("ibm plex sans bold italic")
FTFont (family = AlegreyaSans-BoldItalic, style = Bold)
julia> ibm_psbi = FreeTypeAbstraction.try_load("/home/tec/.local/share/fonts/IBMPlexSans-BoldItalic.otf")
FTFont (family = IBM Plex Sans, style = Bold Italic)
julia> FreeTypeAbstraction.match_font(ibm_psbi, ["ibm", "plex", "sans", "bold", "italic"])
(11, 10, false, -24)
julia> alegreya_tex_sbi = FreeTypeAbstraction.try_load("/usr/share/fonts/texlive-alegreya/AlegreyaSans-BoldItalic.pfb")
FTFont (family = AlegreyaSans-BoldItalic, style = Bold)
julia> FreeTypeAbstraction.match_font(alegreya_tex_sbi, ["ibm", "plex", "sans", "bold", "italic"])
(14, 0, false, -27)
I tried using GLMakie on windows 10 with Julia 1.4 RC 01
And tests on this package are not working.
I came here from trying to track down a bug in AbstractPlotting.jl
My environment is:
(@v1.4) pkg> st
Status `C:\Users\Argel Ramírez Reyes\.julia\environments\v1.4\Project.toml`
[537997a7] AbstractPlotting v0.9.17 [`C:\Users\Argel Ramírez Reyes\.julia\dev\AbstractPlotting`]
[c52e3926] Atom v0.11.3
[663a7486] FreeTypeAbstraction v0.5.0 [`C:\Users\Argel Ramírez Reyes\.julia\dev\FreeTypeAbstraction`]
[e9467ef8] GLMakie v0.0.13
[e5e0dc1b] Juno v0.7.2
[295af30f] Revise v2.5.0
(@v1.4) pkg> test FreeTypeAbstraction
Testing FreeTypeAbstraction
Status `C:\Users\Argel Ramírez Reyes\AppData\Local\Temp\jl_I65PUQ\Manifest.toml`
...
ERROR: LoadError: Couldn't load font C:\Users\Argel Ramírez Reyes\.julia\dev\FreeTypeAbstraction\test\hack_regular.ttf with error 1
Stacktrace:
[1] newface(::String, ::Int64, ::Array{Ptr{Nothing},1}) at C:\Users\Argel Ramírez Reyes\.julia\dev\FreeTypeAbstraction\src\functions.jl:79
[2] newface(::String) at C:\Users\Argel Ramírez Reyes\.julia\dev\FreeTypeAbstraction\src\functions.jl:76
[3] top-level scope at C:\Users\Argel Ramírez Reyes\.julia\dev\FreeTypeAbstraction\test\runtests.jl:5
[4] top-level scope at none:6
in expression starting at C:\Users\Argel Ramírez Reyes\.julia\dev\FreeTypeAbstraction\test\runtests.jl:5
ERROR: Package FreeTypeAbstraction errored during testing
Hello it is probably some simple mistake that I make But I get low quality of displayed text (mainly irregular thickenings..) as one see below
I get this image by
1)using render string with Uint8 matrix of zeros # zeros(2000,2000) I use font from example posted in this repo
2)passing this data to integer texture
3)in fragment shader defining that all above 0 is black and all below is white
4) rendering on a quad
In order to obtain multiple lines as seen I combine multiple matricies
I will gratly appriciate any help
Consider the following dependency tree:
julia> using PkgDependency
julia> PkgDependency.tree("FreeTypeAbstraction")
FreeTypeAbstraction v0.10.0
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
│
├── FreeType v4.0.0
│ ├── CEnum v0.4.2
│ └── FreeType2_jll v2.10.4+0
│ ├── JLLWrappers v1.4.1
│ │ └── Preferences v1.3.0
│ │ └── TOML v1.0.0
│ ├── Pkg v1.8.0
│ │ ├── Downloads v1.6.0
│ │ │ ├── LibCURL v0.6.3
│ │ │ │ ├── MozillaCACerts_jll v2022.2.1
│ │ │ │ └── LibCURL_jll v7.84.0+0
│ │ │ │ ├── LibSSH2_jll v1.10.2+0
│ │ │ │ │ └── MbedTLS_jll v2.28.0+0
│ │ │ │ ├── MbedTLS_jll v2.28.0+0 (*)
│ │ │ │ ├── nghttp2_jll v1.48.0+0
│ │ │ │ └── Zlib_jll v1.2.12+3
│ │ │ ├── NetworkOptions v1.2.0
│ │ │ └── ArgTools v1.1.1
│ │ ├── Tar v1.10.0
│ │ │ ├── SHA v0.7.0
│ │ │ └── ArgTools v1.1.1 (*)
│ │ ├── SHA v0.7.0 (*)
│ │ ├── p7zip_jll v17.4.0+0
│ │ └── TOML v1.0.0 (*)
│ ├── Bzip2_jll v1.0.8+0
│ │ ├── JLLWrappers v1.4.1 (*)
│ │ └── Pkg v1.8.0 (*)
│ └── Zlib_jll v1.2.12+3 (*)
├── ColorVectorSpace v0.9.9
│ ├── ColorTypes v0.11.4
│ │ └── FixedPointNumbers v0.8.4
│ ├── TensorCore v0.1.1
│ ├── SpecialFunctions v2.1.7
│ │ ├── IrrationalConstants v0.1.1
│ │ ├── ChainRulesCore v1.15.5
│ │ │ └── Compat v3.46.0
│ │ │ ├── Pkg v1.8.0 (*)
│ │ │ └── SHA v0.7.0 (*)
│ │ ├── LogExpFunctions v0.3.18
│ │ │ ├── IrrationalConstants v0.1.1 (*)
│ │ │ ├── ChainRulesCore v1.15.5 (*)
│ │ │ ├── ChangesOfVariables v0.1.4
│ │ │ │ └── ChainRulesCore v1.15.5 (*)
│ │ │ ├── DocStringExtensions v0.8.6
│ │ │ └── InverseFunctions v0.1.7
│ │ ├── OpenLibm_jll v0.8.1+0
│ │ └── OpenSpecFun_jll v0.5.5+0
│ │ ├── JLLWrappers v1.4.1 (*)
│ │ ├── Pkg v1.8.0 (*)
│ │ └── CompilerSupportLibraries_jll v0.5.2+0
│ └── FixedPointNumbers v0.8.4 (*)
├── Colors v0.12.8
│ ├── ColorTypes v0.11.4 (*)
│ ├── Reexport v1.2.2
│ └── FixedPointNumbers v0.8.4 (*)
└── GeometryBasics v0.4.3
├── IterTools v1.4.0
├── StaticArrays v1.5.6
│ └── StaticArraysCore v1.3.0
├── Tables v1.7.0
│ ├── DataAPI v1.10.0
│ ├── OrderedCollections v1.4.1
│ ├── IteratorInterfaceExtensions v1.0.0
│ ├── DataValueInterfaces v1.0.0
│ └── TableTraits v1.0.1
│ └── IteratorInterfaceExtensions v1.0.0 (*)
├── EarCut_jll v2.2.3+0
│ ├── JLLWrappers v1.4.1 (*)
│ └── Pkg v1.8.0 (*)
├── StructArrays v0.6.12
│ ├── DataAPI v1.10.0 (*)
│ ├── StaticArraysCore v1.3.0 (*)
│ ├── Tables v1.7.0 (*)
│ └── Adapt v3.4.0
└── GeoInterface v1.0.1
└── Extents v0.1.1
From the previous tree, a consequent dependency is GeometryBasics
(with induced artifacts e.g. EarCut_jll
, Tables
, StructArrays
, ...), which seems an overkill for the usage of a few Vec
, Vec2f
, Rect2f
in FreeTypeAbstraction
.
Would you consider a PR in order to remove the GeometryBasics
dependency here, or as an alternative splitting GeometryBasics
into a low dependencies GeometryBasicsCore
(or GeometryBasicsTypes
) and the full GeometryBasics
?
Currently, it looks like FreeTypeAbstraction only searches the first face in each file, as can be seen here.
FreeTypeAbstraction.jl/src/findfonts.jl
Line 143 in b7d6d65
try_load
only loads the face at index 0 - we should load all faces, and loop through them internally.
We can get the number of faces in a file by this operation.
I tried the examples in the readme but the face = newface("hack_regular.ttf")
return type is Ptr{FreeType.LibFreeType.FT_FaceRec_}
and it's not compatible with renderface/renderstring!
, which needs ::FreeTypeAbstraction.FTFont
.
As workaround I used face = FreeTypeAbstraction.FTFont(newface("DroidSansMono.ttf"))
currently renderstring!
returns the img that is input. more useful i think would be to return the bounding box of the rendered text. if that makes sense, i could create a PR. let me know.
I'm trying to render a string over an existing image using a transparent bcolor
. But renderstring
seems to replace the existing values instead of blending them.
Would it be useful to blend RGBA
values? Or at least have a kwarg to control if that happens?
FreeType
is registered, but not FreeTypeAbstraction
. would it make sense to do so now that it's in JuliaGraphics
?
This issue is used to trigger TagBot; feel free to unsubscribe.
If you haven't already, you should update your TagBot.yml
to include issue comment triggers.
Please see this post on Discourse for instructions and more details.
If you'd like for me to do this for you, comment TagBot fix
on this issue.
I'll open a PR within a few hours, please be patient!
This is with FreeTypeAbstraction v0.10.1, Julia v1.10.1 on Windows.
I set Julia depot path with
$Env:JULIA_DEPOT_PATH="C:\Users\jaakkor2\MyTemp\depå
then
julia> using Makie
Precompiling Makie
Info Given Makie was explicitly requested, output will be shown live
ERROR: LoadError: Could not load font file "C:\Users\jaakkor2\MyTemp\depå\packages\Makie\z2T2o\assets\fonts\TeXGyreHerosMakie-Regular.otf"
Stacktrace:
[1] error(s::String)
@ Base .\error.jl:35
[2] load_font
@ C:\Users\jaakkor2\MyTemp\depå\packages\Makie\z2T2o\src\conversions.jl:1105 [inlined]
[3] (::Makie.var"#266#268"{String})()
@ Makie C:\Users\jaakkor2\MyTemp\depå\packages\Makie\z2T2o\src\conversions.jl:1123
[4] get!(default::Makie.var"#266#268"{String}, h::Dict{String, FreeTypeAbstraction.FTFont}, key::String)
@ Base .\dict.jl:479
[5] (::Makie.var"#265#267"{String})()
@ Makie C:\Users\jaakkor2\MyTemp\depå\packages\Makie\z2T2o\src\conversions.jl:1120
[6] lock(f::Makie.var"#265#267"{String}, l::ReentrantLock)
@ Base .\lock.jl:229
[7] to_font(str::String)
@ Makie C:\Users\jaakkor2\MyTemp\depå\packages\Makie\z2T2o\src\conversions.jl:1119
[8] to_font(fonts::MakieCore.Attributes, s::Symbol)
@ Makie C:\Users\jaakkor2\MyTemp\depå\packages\Makie\z2T2o\src\conversions.jl:1155
[9] (::Makie.var"#2208#2211"{Base.RefValue{Vector{Int64}}, Observables.Observable{Vector{ColorTypes.RGBA{Float32}}}, Observables.Observable{Vector{Float32}}, Observables.Observable{Vector{GeometryBasics.Point{2, Float32}}}, Observables.Observable{Vector{Makie.GlyphCollection}}})(str::String, ts::Float64, f::Symbol, fs::MakieCore.Attributes, al::Tuple{Symbol, Symbol}, rot::Float32, jus::MakieCore.Automatic, lh::Float64, col::ColorTypes.RGBA{Float32}, scol::Tuple{Symbol, Float64}, swi::Int64, www::Int64, offs::Tuple{Float64, Float64})
@ Makie C:\Users\jaakkor2\MyTemp\depå\packages\Makie\z2T2o\src\basic_recipes\text.jl:22
....
The file does exist since
isfile(raw"C:\Users\jaakkor2\MyTemp\depå\packages\Makie\z2T2o\assets\fonts\TeXGyreHerosMakie-Regular.otf")
return true
.
FreeTypeAbstraction.try_load(raw"C:\Users\jaakkor2\MyTemp\depå\packages\Makie\z2T2o\assets\fonts\TeXGyreHerosMakie-Regular.otf")
returns nothing
.
FreeTypeAbstraction.newface(raw"C:\Users\jaakkor2\MyTemp\depå\packages\Makie\z2T2o\assets\fonts\TeXGyreHerosMakie-Regular.otf")
errors
ERROR: Couldn't load font C:\Users\jaakkor2\MyTemp\depå\packages\Makie\z2T2o\assets\fonts\TeXGyreHerosMakie-Regular.otf with error: 1
Stacktrace:
[1] error(s::String)
@ Base .\error.jl:35
[2] newface(facename::String)
@ FreeTypeAbstraction C:\Users\jaakkor2\MyTemp\depå\packages\FreeTypeAbstraction\lopoc\src\types.jl:22
[3] top-level scope
@ REPL[11]:1
Ends up erroring in https://github.com/JuliaGraphics/FreeTypeAbstraction.jl/blob/v0.10.1/src/types.jl#L23
Note that my standard depot path works fine
FreeTypeAbstraction.newface(raw"C:\Users\jaakkor2\.julia\packages\Makie\z2T2o\assets\fonts\TeXGyreHerosMakie-Regular.otf")
returns Ptr{FreeType.__JL_FT_FaceRec_} @0x0000016f654688b0
.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.