Skip to content

Instantly share code, notes, and snippets.

@lobingera
Created April 1, 2020 17:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lobingera/8f69839b1caf8968de075272fafdcf27 to your computer and use it in GitHub Desktop.
Save lobingera/8f69839b1caf8968de075272fafdcf27 to your computer and use it in GitHub Desktop.
CairoText example
module CairoText
using Cairo
using FreeType
mutable struct font_face_t
ptr::Ptr{Nothing}
function font_face_t(ptr::Ptr{Nothing})
#ccall((:cairo_font_face_reference,Cairo._jl_libcairo),
# Ptr{Void}, (Ptr{Void},), ptr)
self = new(ptr)
finalizer(self, destroy)
end
end
function destroy(ff::font_face_t)
if ff.ptr == C_NULL
return
end
ccall((:cairo_font_face_destroy,Cairo._jl_libcairo), Nothing, (Ptr{Nothing},), ff.ptr)
ff.ptr = C_NULL
nothing
end
# type CairoContext <: GraphicsContext
# ptr::Ptr{Void}
# surface::CairoSurface
# layout::Ptr{Void} # cache PangoLayout
# function CairoContext(surface::CairoSurface)
# ptr = ccall((:cairo_create,_jl_libcairo),
# Ptr{Void}, (Ptr{Void},), surface.ptr)
# layout = ccall((:pango_cairo_create_layout,_jl_libpangocairo),
# Ptr{Void}, (Ptr{Void},), ptr)
# self = new(ptr, surface, layout)
# finalizer(self, destroy)
# self
# end
# function CairoContext(ptr::Ptr{Void})
# ccall((:cairo_reference,_jl_libcairo),
# Ptr{Void}, (Ptr{Void},), ptr)
# surface_p = ccall((:cairo_get_target,_jl_libcairo),
# Ptr{Void}, (Ptr{Void},), ptr)
# surface = CairoSurface(surface_p)
# layout = ccall((:pango_cairo_create_layout,_jl_libpangocairo),
# Ptr{Void}, (Ptr{Void},), ptr)
# self = new(ptr,surface,layout)
# finalizer(self, destroy)
# self
# end
# end
# creategc(s::CairoSurface) = CairoContext(s)
# function destroy(ctx::CairoContext)
# if ctx.ptr == C_NULL
# return
# end
# ccall((:g_object_unref,_jl_libgobject), Void, (Ptr{Void},), ctx.layout)
# _destroy(ctx)
# ctx.ptr = C_NULL
# nothing
struct glyph_t
index::Clong
x::Cdouble
y::Cdouble
end
const FREE_FONT_LIBRARY = FT_Library[C_NULL]
function ft_init()
global FREE_FONT_LIBRARY
FREE_FONT_LIBRARY[1] != C_NULL && error("Freetype already initalized. init() called two times?")
err = FT_Init_FreeType(FREE_FONT_LIBRARY)
return err == 0
end
function ft_done()
global FREE_FONT_LIBRARY
FREE_FONT_LIBRARY[1] == C_NULL && error("Library == CNULL. FreeTypeAbstraction.done() called before init(), or done called two times?")
err = FT_Done_FreeType(FREE_FONT_LIBRARY[1])
FREE_FONT_LIBRARY[1] = C_NULL
return err == 0
end
function __init__()
ft_init()
atexit(ft_done)
end
function ft_done()
global FREE_FONT_LIBRARY
FREE_FONT_LIBRARY[1] == C_NULL && error("Library == CNULL. FreeTypeAbstraction.done() called before init(), or done called two times?")
err = FT_Done_FreeType(FREE_FONT_LIBRARY[1])
FREE_FONT_LIBRARY[1] = C_NULL
return err == 0
end
function __init__()
ft_init()
atexit(ft_done)
end
function open_font(fname::AbstractString)
if stat(fname).size == 0
return nothing
end
face = (FT_Face)[C_NULL]
err = FT_New_Face(FREE_FONT_LIBRARY[1], fname, Int32(0), face)
if err != 0
error("Couldn't load font $facename with error $err")
return nothing
end
#cairo_font_face_t *
#cairo_ft_font_face_create_for_ft_face (FT_Face face,
# int load_flags);
display(face)
ff = ccall((:cairo_ft_font_face_create_for_ft_face,Cairo._jl_libcairo),
font_face_t,(Ptr{Nothing},UInt32),face[1],0)
return(ff)
end
function set_font_face(cr::CairoContext,ff::font_face_t)
ccall((:cairo_set_font_face,Cairo._jl_libcairo),
Nothing,(Ptr{Nothing},Ptr{Nothing}),cr.ptr,ff.ptr)
end
#cairo_set_font_matrix (cairo_t *cr,
# const cairo_matrix_t *matrix);
#function set_matrix(ctx::CairoContext, m::CairoMatrix)
# ccall((:cairo_set_matrix, _jl_libcairo), Void, (Ptr{Void}, Ptr{Void}), ctx.ptr, [m])
#end
#cairo_set_font_matrix (cairo_t *cr,
# const cairo_matrix_t *matrix);
#function set_matrix(ctx::CairoContext, m::CairoMatrix)
# ccall((:cairo_set_matrix, _jl_libcairo), Void, (Ptr{Void}, Ptr{Void}), ctx.ptr, [m])
#end
function set_font_matrix(cr::CairoContext,cm::CairoMatrix)
ccall((:cairo_set_font_matrix, Cairo._jl_libcairo), Nothing, (Ptr{Nothing}, Ptr{Nothing}), cr.ptr, [cm])
end
function show_glyphs(cr::CairoContext,gf::Array{glyph_t,1})
#num = length(gf)
#c = Array{UInt32}(num*5)
#for k=1:num
# x = reinterpret(UInt64,gf[k].x)
# y = reinterpret(UInt64,gf[k].y)
# i = gf[k].index
# c[((k-1)*5)+1] = i
# c[((k-1)*5)+2] = x >> 32
# c[((k-1)*5)+3] = x & 0xffff
# c[((k-1)*5)+4] = y >> 32
# c[((k-1)*5)+5] = y & 0xffff
#end
display(pointer(gf))
#void
#cairo_show_glyphs (cairo_t *cr,
# const cairo_glyph_t *glyphs,
# int num_glyphs);
ccall((:cairo_show_glyphs, Cairo._jl_libcairo), Nothing, (Ptr{Nothing}, Ptr{Nothing},Cint), cr.ptr, gf, length(gf))
end
end # module
using CairoText
#fname = "Oswald-Regular.ttf"
fname = "SourceSerifPro-Regular.ttf"
#fname = "CharisSIL-5.000/CharisSIL-R.ttf"
ff = CairoText.open_font(fname)
using Cairo
s = CairoRGBSurface(960,960);
cr = CairoContext(s)
CairoText.set_font_face(cr,ff)
save(cr);
set_source_rgb(cr,0.8,0.8,0.8); # light gray
rectangle(cr,0.0,0.0,960.0,960.0); # background
fill(cr);
restore(cr);
cm = CairoMatrix(40.0,0.0,0.0,40.0,0.0,0.0)
CairoText.set_font_matrix(cr,cm)
y = 24*floor.((0:1599) ./ 40)
x = 24*float(((0:1599) .% 40))
#gf = Array{CairoText.glyph_t}(1600)
#c_offset = 0
#for k=1:1600
# gf[k] = CairoText.glyph_t(k+c_offset,x[k],y[k]+24)
#end
gf = [CairoText.glyph_t(267,40,60), CairoText.glyph_t(368,60,60)]
CairoText.show_glyphs(cr,gf)
Cairo.write_to_png(s,"a1.png")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment