From 235b2c9a97e6269cf27bc308d8cbfd2598a72bda Mon Sep 17 00:00:00 2001 From: Tamas Nagy Date: Wed, 4 Apr 2018 12:26:41 -0700 Subject: [PATCH 1/8] replace nullables with union types this is a follow up to #279 temp hack for missing load_cache_path on 0.7 See https://github.com/JuliaLang/Compat.jl/issues/527 for details replace more voids that slipped past the first round more deprecation fixes prelim work on adding optional runtime backend loading use Compat's @info so we don't break v0.6 --- REQUIRE | 1 + src/Compose.jl | 77 ++++++++++++++++--------------------------- src/batch.jl | 11 +++---- src/cairo_backends.jl | 50 ++++++++++++++-------------- src/container.jl | 36 ++++++++++---------- src/fontfallback.jl | 12 ++++--- src/measure.jl | 34 +++++++++---------- src/misc.jl | 2 +- src/pango.jl | 42 +++++++++++------------ src/pgf_backend.jl | 38 ++++++++++----------- src/svg.jl | 21 ++++++------ src/table.jl | 4 +-- test/immerse.jl | 3 +- test/misc.jl | 3 +- 14 files changed, 157 insertions(+), 177 deletions(-) diff --git a/REQUIRE b/REQUIRE index f6d0f51a..2030ed9f 100644 --- a/REQUIRE +++ b/REQUIRE @@ -5,3 +5,4 @@ DataStructures IterTools JSON Measures +Requires diff --git a/src/Compose.jl b/src/Compose.jl index 926b40f1..14272eec 100644 --- a/src/Compose.jl +++ b/src/Compose.jl @@ -1,4 +1,4 @@ -VERSION >= v"0.4.0-dev+6521" && __precompile__() +__precompile__() module Compose @@ -7,6 +7,7 @@ using IterTools using DataStructures using Compat using Measures +using Requires import JSON import Base: length, start, next, done, isempty, getindex, setindex!, @@ -15,7 +16,6 @@ import Base: length, start, next, done, isempty, getindex, setindex!, using Compat.Dates using Compat.Printf -using Compat.Pkg import Measures: resolve, w, h @@ -31,25 +31,6 @@ export compose, compose!, Context, UnitBox, AbsoluteBoundingBox, Rotation, Mirro CAIROSURFACE, introspect, set_default_graphic_size, set_default_jsmode, boundingbox, Patchable -function isinstalled(pkg, ge=v"0.0.0-") - try - # Pkg.installed might throw an error, - # we need to account for it to be able to precompile - ver = Pkg.installed(pkg) - ver == nothing && try - # Assume the version is new enough if the package is in LOAD_PATH - ex = Expr(:import, Symbol(pkg)) - @eval $ex - return true - catch - return false - end - return ver >= ge - catch - return false - end -end - abstract type Backend end """ @@ -151,46 +132,46 @@ macro missing_cairo_error(backend) Pkg.add("Fontconfig") """ msg2 = """ - You also have to delete $(joinpath(Base.LOAD_CACHE_PATH[1], "Compose.ji")) - and restart your REPL session afterwards. + You also have to delete ~/.julia/lib/v0.6/Compose.ji and restart your + REPL session afterwards. """ string(msg1, msg2) end -if isinstalled("Cairo") - include("cairo_backends.jl") - include("immerse_backend.jl") -else - global PNG - global PS - global PDF - - PNG(args...) = error(@missing_cairo_error "PNG") - PS(args...) = error(@missing_cairo_error "PS") - PDF(args...) = error(@missing_cairo_error "PDF") -end +global PDF +PNG(args...) = error(@missing_cairo_error "PNG") +PS(args...) = error(@missing_cairo_error "PS") +PDF(args...) = error(@missing_cairo_error "PDF") + include("svg.jl") include("pgf_backend.jl") # If available, pango and fontconfig are used to compute text extents and match # fonts. Otherwise a simplistic pure-julia fallback is used. -if isinstalled("Fontconfig") +include("fontfallback.jl") + +function link_fontconfig() pango_cairo_ctx = C_NULL include("pango.jl") - function __init__() - global pango_cairo_ctx - global pangolayout - ccall((:g_type_init, Cairo._jl_libgobject), Void, ()) - pango_cairo_fm = ccall((:pango_cairo_font_map_new, libpangocairo), - Ptr{Void}, ()) - pango_cairo_ctx = ccall((:pango_font_map_create_context, libpango), - Ptr{Void}, (Ptr{Void},), pango_cairo_fm) - pangolayout = PangoLayout() - end -else - include("fontfallback.jl") + ccall((:g_type_init, Cairo._jl_libgobject), Cvoid, ()) + pango_cairo_fm = ccall((:pango_cairo_font_map_new, libpangocairo), + Ptr{Cvoid}, ()) + pango_cairo_ctx = ccall((:pango_font_map_create_context, libpango), + Ptr{Cvoid}, (Ptr{Cvoid},), pango_cairo_fm) + pangolayout = PangoLayout() +end + +function link_cairo() + Compat.@info "Loading Cairo backend into Compose.jl" + include("cairo_backends.jl") + include("immerse_backend.jl") +end + +function __init__() + @require Cairo="159f3aea-2a34-519c-b102-8c37f9878175" link_cairo() + @require Fontconfig="186bb1d3-e1f7-5a2c-a377-96d770f13627" link_fontconfig() end show(io::IO, m::MIME"text/html", ctx::Context) = diff --git a/src/batch.jl b/src/batch.jl index 247ec782..fe0129cb 100644 --- a/src/batch.jl +++ b/src/batch.jl @@ -16,11 +16,10 @@ struct FormBatch{P <: FormPrimitive} end """ -Attempt to batch a form. Return a Nullable{FormBatch} which is null if the Form -could not be batched, and non-null if the original form can be replaced with teh -resulting FormBatch. +Attempt to batch a form. Return a Nothing singleton if the Form could not be +batched, and FormBatch object if the original form can be replaced. """ -batch(form::Form{P}) where P = Nullable{FormBatch{P}}() +batch(form::Form{P}) where P = nothing # Note: in tests using random data, this optimization wasn't worth it. I'm # keeping it around out of hopes I find a more clever version that is @@ -54,7 +53,7 @@ function batch{T <: CirclePrimitive}(form::Form{T}) r = form.primitives[1].radius n = length(form.primitives) for i in 2:n - form.primitives[i].radius == r || return Nullable{FormBatch{CirclePrimitive}}() + form.primitives[i].radius == r || return @compat Nothing end prim = CirclePrimitive((0mm, 0mm), r) @@ -63,7 +62,7 @@ function batch{T <: CirclePrimitive}(form::Form{T}) offsets[i] = form.primitives[i].center end - return Nullable(FormBatch(prim, offsets)) + return FormBatch(prim, offsets) end =# diff --git a/src/cairo_backends.jl b/src/cairo_backends.jl index 821752c1..c53a98f8 100644 --- a/src/cairo_backends.jl +++ b/src/cairo_backends.jl @@ -26,7 +26,7 @@ mutable struct ImagePropertyState linewidth::AbsoluteLength fontsize::AbsoluteLength font::AbstractString - clip::Nullable{ClipPrimitive} + clip::Union{ClipPrimitive, Nothing} end mutable struct ImagePropertyFrame @@ -57,12 +57,12 @@ mutable struct Image{B<:ImageBackend} <: Backend linewidth::AbsoluteLength fontsize::AbsoluteLength font::AbstractString - clip::Nullable{ClipPrimitive} + clip::Union{ClipPrimitive, Nothing} # Keep track of property state_stack::Vector{ImagePropertyState} property_stack::Vector{ImagePropertyFrame} - vector_properties::Dict{Type, Nullable{Property}} + vector_properties::Dict{Type, Union{Property, Nothing}} # Close the surface when finished owns_surface::Bool @@ -71,7 +71,7 @@ mutable struct Image{B<:ImageBackend} <: Backend ownedfile::Bool # Filename when ownedfile is true - filename::Union{AbstractString, (Void)} + filename::Union{AbstractString, Nothing} # True when finish has been called and no more drawing should occur finished::Bool @@ -83,8 +83,8 @@ mutable struct Image{B<:ImageBackend} <: Backend ppmm::Float64 # For use with the t/T and s/S commands in SVG-style paths - last_ctrl1_point::Nullable{AbsoluteVec2} - last_ctrl2_point::Nullable{AbsoluteVec2} + last_ctrl1_point::Union{AbsoluteVec2, Nothing} + last_ctrl2_point::Union{AbsoluteVec2, Nothing} end function Image{B}(surface::CairoSurface, @@ -104,18 +104,18 @@ function Image{B}(surface::CairoSurface, linewidth = default_line_width, fontsize = default_font_size, font = default_font_family, - clip = Nullable{ClipPrimitive}(), + clip = nothing, state_stack = Array{ImagePropertyState}(0), property_stack = Array{ImagePropertyFrame}(0), - vector_properties = Dict{Type, Nullable{Property}}(), + vector_properties = Dict{Type, Union{Property, Nothing}}(), owns_surface = false, ownedfile = false, filename = nothing, finished = false, emit_on_finish = false, ppmm = 72 / 25.4, - last_ctrl1_point = Nullable{AbsoluteVec2}(), - last_ctrl2_point = Nullable{AbsoluteVec2}()) where B<:ImageBackend + last_ctrl1_point = nothing, + last_ctrl2_point = nothing) where B<:ImageBackend Image{B}(out, surface, @@ -196,7 +196,7 @@ end function canbatch(img::Image) for vp in values(img.vector_properties) - isnull(vp) || return false + (vp === nothing) || return false end return true end @@ -314,7 +314,7 @@ function pop_property_frame(img::Image) frame.has_scalar_properties && restore_property_state(img) for (propertytype, property) in frame.vector_properties - img.vector_properties[propertytype] = Nullable{Property}() + img.vector_properties[propertytype] = Union{Property, Nothing}() for i in length(img.property_stack):-1:1 if haskey(img.property_stack[i].vector_properties, propertytype) img.vector_properties[propertytype] = @@ -369,8 +369,8 @@ end function push_vector_properties(img::Image, idx::Int) save_property_state(img) for (propertytype, property) in img.vector_properties - isnull(property) && continue - primitives = get(property).primitives + (property === nothing) && continue + primitives = property.primitives idx > length(primitives) && error("Vector form and vector property differ in length. Can't distribute.") apply_property(img, primitives[idx]) @@ -405,13 +405,13 @@ function apply_property(img::Image, property::FontPrimitive) img.font = property.family font_desc = ccall((:pango_layout_get_font_description, Cairo._jl_libpango), - Ptr{Void}, (Ptr{Void},), img.ctx.layout) + Ptr{Cvoid}, (Ptr{Cvoid},), img.ctx.layout) if font_desc == C_NULL size = absolute_native_units(img, default_font_size.value) else size = ccall((:pango_font_description_get_size, Cairo._jl_libpango), - Cint, (Ptr{Void},), font_desc) + Cint, (Ptr{Cvoid},), font_desc) end Cairo.set_font_face(img.ctx, @@ -422,13 +422,13 @@ function apply_property(img::Image, property::FontSizePrimitive) img.fontsize = property.value font_desc = ccall((:pango_layout_get_font_description, Cairo._jl_libpango), - Ptr{Void}, (Ptr{Void},), img.ctx.layout) + Ptr{Cvoid}, (Ptr{Cvoid},), img.ctx.layout) if font_desc == C_NULL family = "sans" else family = ccall((:pango_font_description_get_family, Cairo._jl_libpango), - Ptr{UInt8}, (Ptr{Void},), font_desc) + Ptr{UInt8}, (Ptr{Cvoid},), font_desc) family = unsafe_string(family) end @@ -462,8 +462,8 @@ apply_property(img::Image, property::SVGAttributePrimitive) = nothing function current_point(img::Image) x = Array{Float64}(1) y = Array{Float64}(1) - ccall((:cairo_get_current_point, Cairo._jl_libcairo), Void, - (Ptr{Void}, Ptr{Float64}, Ptr{Float64}), img.ctx.ptr, x, y) + ccall((:cairo_get_current_point, Cairo._jl_libcairo), Cvoid, + (Ptr{Cvoid}, Ptr{Float64}, Ptr{Float64}), img.ctx.ptr, x, y) return ((x[1] / img.ppmm)*mm, (x[2] / img.ppmm)*mm) end @@ -596,8 +596,8 @@ function draw(img::Image, form::Form) else for (idx, primitive) in enumerate(form.primitives) for (propertytype, property) in img.vector_properties - isnull(property) && continue - primitives = get(property).primitives + (property === nothing) && continue + primitives = property.primitives idx > length(primitives) && error("Vector form and vector property differ in length. Can't distribute.") apply_property(img, primitives[idx]) @@ -840,7 +840,7 @@ function draw_path_op(img::Image, op::QuadCurveShortAbsPathOp) x2, y2 = op.to[1].value, op.to[2].value ctrl1 = img.last_ctrl1_point - if isnull(img.last_ctrl1_point) + if img.last_ctrl1_point === nothing ctrl1 = xy else ctrl1 = (Measure(abs=2*x1 - ctrl1[1].value), @@ -969,8 +969,8 @@ function draw(img::Image, batch::FormBatch) Cairo.restore(img.ctx) # reapply the clipping region we just reset - if !isnull(img.clip) - apply_property(img, get(img.clip)) + if img.clip !== nothing + apply_property(img, img.clip) end Cairo.set_antialias(img.ctx, Cairo.ANTIALIAS_NONE) diff --git a/src/container.jl b/src/container.jl index bc921a32..ad885cf9 100644 --- a/src/container.jl +++ b/src/container.jl @@ -9,13 +9,13 @@ mutable struct Context <: Container box::BoundingBox # Context coordinates used for children - units::Nullable{UnitBox} + units::Union{UnitBox, Nothing} # Rotation is degrees of - rot::Nullable{Rotation} + rot::Union{Rotation, Nothing} # Maybe mirror about a line, after rotation - mir::Nullable{Mirror} + mir::Union{Mirror, Nothing} # Container children container_children::List{Container} @@ -69,9 +69,9 @@ mutable struct Context <: Container end Context(x0=0.0w, y0=0.0h, width=1.0w, height=1.0h; - units=Nullable{UnitBox}(), - rotation=Nullable{Rotation}(), - mirror=Nullable{Mirror}(), + units=Union{UnitBox, Nothing}(), + rotation=Union{Rotation, Nothing}(), + mirror=Union{Mirror, Nothing}(), order=0, clip=false, withjs=false, @@ -91,8 +91,8 @@ Context(ctx::Context) = Context(ctx.box, ctx.units, ctx.rot, ctx.mir, ctx.minwidth, ctx.minheight, ctx.penalty, ctx.tag) context(x0=0.0w, y0=0.0h, width=1.0w, height=1.0h; - units=NullUnitBox(), - rotation=Nullable{Rotation}(), + units=nothing, + rotation=nothing, mirror=nothing, order=0, clip=false, @@ -104,9 +104,7 @@ context(x0=0.0w, y0=0.0h, width=1.0w, height=1.0h; penalty=0.0, tag=empty_tag) = Context(BoundingBox(x_measure(x0), y_measure(y0), x_measure(width), y_measure(height)), - isa(units, Nullable) ? units : Nullable{UnitBox}(units), - isa(rotation, Nullable) ? rotation : Nullable{Rotation}(rotation), - mirror, + units, rotation, mirror, ListNull{Container}(), ListNull{Form}(), ListNull{Property}(), order, clip, withjs, withoutjs, raster, minwidth, minheight, penalty, tag) @@ -370,13 +368,13 @@ function drawpart(backend::Backend, container::Container, box = resolve(parent_box, units, parent_transform, ctx.box) transform = parent_transform - if !isnull(ctx.rot) - rot = resolve(box, units, parent_transform, get(ctx.rot)) + if ctx.rot !== nothing + rot = resolve(box, units, parent_transform, ctx.rot) transform = combine(convert(Transform, rot), transform) end - if !isnull(ctx.mir) - mir = resolve(box, units, parent_transform, get(ctx.mir)) + if ctx.mir !== nothing + mir = resolve(box, units, parent_transform, ctx.mir) transform = combine(convert(Transform, mir), transform) end @@ -395,8 +393,8 @@ function drawpart(backend::Backend, container::Container, return end - if !isnull(ctx.units) - units = resolve(box, units, transform, get(ctx.units)) + if ctx.units !== nothing + units = resolve(box, units, transform, ctx.units) end has_properties = false @@ -436,8 +434,8 @@ function drawpart(backend::Backend, container::Container, if trybatch b = batch(form) - if !isnull(b) - draw(backend, get(b)) + if b !== nothing + draw(backend, b) child = child.tail continue end diff --git a/src/fontfallback.jl b/src/fontfallback.jl index a73132ba..46b9779d 100644 --- a/src/fontfallback.jl +++ b/src/fontfallback.jl @@ -1,10 +1,12 @@ +using Compat + # Font handling when pango and fontconfig are not available. # Define this even if we're not calling pango, since cairo needs it. const PANGO_SCALE = 1024.0 # Serialized glyph sizes for commont fonts. -const glyphsizes = open(fd -> JSON.parse(readstring(fd)), +const glyphsizes = open(fd -> JSON.parse(Compat.read(fd, String)), joinpath(dirname(@__FILE__), "..", "data", "glyphsize.json")) # It's better to overestimate text extents than to underestimes, since the later @@ -16,8 +18,8 @@ const text_extents_scale_y = 1.0 # Normalized Levenshtein distance between two strings. function levenshtein(a::AbstractString, b::AbstractString) - a = replace(lowercase(a), r"\s+", "") - b = replace(lowercase(b), r"\s+", "") + a = Compat.replace(lowercase(a), r"\s+"=>"") + b = Compat.replace(lowercase(b), r"\s+"=>"") n = length(a) m = length(b) D = zeros(UInt, n + 1, m + 1) @@ -72,7 +74,7 @@ end # Approximate text width in millimeters. # function text_width(widths::Dict, text::AbstractString, size::Float64) - stripped_text = replace(text, r"<[^>]*>", "") + stripped_text = Compat.replace(text, r"<[^>]*>"=>"") width = 0 for c in stripped_text width += get(widths, string(c), widths["w"]) @@ -118,7 +120,7 @@ function text_extents(font_family::AbstractString, size::Measure, texts::Abstrac glyphwidths = glyphsizes[font_family]["widths"] fontsize = size/pt - extents = Array{Tuple{Measure, Measure}}(length(texts)) + extents = Array{Tuple{Measure, Measure}}(undef, length(texts)) for (i, text) in enumerate(texts) chunkwidths = Float64[] textheight = 0.0 diff --git a/src/measure.jl b/src/measure.jl index 0d4abdd1..14707315 100644 --- a/src/measure.jl +++ b/src/measure.jl @@ -130,26 +130,24 @@ end UnitBox() = UnitBox(0.0, 0.0, 1.0, 1.0) -const NullUnitBox = Nullable{UnitBox} - # copy with substitution UnitBox(units::UnitBox; - x0=Nullable{Measure}(), - y0=Nullable{Measure}(), - width=Nullable{Measure}(), - height=Nullable{Measure}(), - leftpad=Nullable{AbsoluteLength}(), - rightpad=Nullable{AbsoluteLength}(), - toppad=Nullable{AbsoluteLength}(), - bottompad=Nullable{AbsoluteLength}()) = - UnitBox(ifelse(isa(x0, Nullable) && isnull(x0), units.x0, x0), - ifelse(isa(y0, Nullable) && isnull(y0), units.y0, y0), - ifelse(isa(width, Nullable) && isnull(width), units.width, width), - ifelse(isa(height, Nullable) && isnull(height), units.height, height), - leftpad = ifelse(isa(leftpad, Nullable) && isnull(leftpad), units.leftpad, leftpad), - rightpad = ifelse(isa(rightpad, Nullable) && isnull(rightpad), units.rightpad, rightpad), - toppad = ifelse(isa(toppad, Nullable) && isnull(toppad), units.toppad, toppad), - bottompad = ifelse(isa(bottompad, Nullable) && isnull(bottompad), units.bottompad, bottompad)) + x0=nothing, + y0=nothing, + width=nothing, + height=nothing, + leftpad=nothing, + rightpad=nothing, + toppad=nothing, + bottompad=nothing) = + UnitBox(ifelse(x0 === nothing, units.x0, x0), + ifelse(y0 === nothing, units.y0, y0), + ifelse(width === nothing, units.width, width), + ifelse(height === nothing, units.height, height), + leftpad = ifelse(leftpad === nothing, units.leftpad, leftpad), + rightpad = ifelse(rightpad === nothing, units.rightpad, rightpad), + toppad = ifelse(toppad === nothing, units.toppad, toppad), + bottompad = ifelse(bottompad === nothing, units.bottompad, bottompad)) Measures.width(units::UnitBox) = units.width Measures.height(units::UnitBox) = units.height diff --git a/src/misc.jl b/src/misc.jl index 0a1ea9f7..1f71c0de 100644 --- a/src/misc.jl +++ b/src/misc.jl @@ -70,7 +70,7 @@ macro makeform(args...) prim1 = $(constructor) T = typeof(prim1) - primitives = Array{T}(n) + primitives = Array{T}(undef, n) primitives[1] = prim1 for i in 2:n $(iter_ex) diff --git a/src/pango.jl b/src/pango.jl index 8de82a46..15b7e105 100644 --- a/src/pango.jl +++ b/src/pango.jl @@ -46,19 +46,19 @@ let available_font_families = Set{AbstractString}() end family = Fontconfig.format(match(Fontconfig.Pattern(family=family)), "%{family}") desc = @sprintf("%s %fpx", family, size) - fd = ccall((:pango_font_description_from_string, libpango), Ptr{Void}, (Ptr{UInt8},), desc) + fd = ccall((:pango_font_description_from_string, libpango), Ptr{Cvoid}, (Ptr{UInt8},), desc) return fd end end # Thin wrapper for a pango_layout object. mutable struct PangoLayout - layout::Ptr{Void} + layout::Ptr{Cvoid} end function PangoLayout() layout = ccall((:pango_layout_new, libpango), - Ptr{Void}, (Ptr{Void},), pango_cairo_ctx) + Ptr{Cvoid}, (Ptr{Cvoid},), pango_cairo_ctx) # TODO: finalizer? PangoLayout(layout) @@ -68,7 +68,7 @@ end function pango_set_font(pangolayout::PangoLayout, family::AbstractString, pts::Number) fd = match_font(family, pts) ccall((:pango_layout_set_font_description, libpango), - Void, (Ptr{Void}, Ptr{Void}), pangolayout.layout, fd) + Cvoid, (Ptr{Cvoid}, Ptr{Cvoid}), pangolayout.layout, fd) end # Find the width and height of a string. @@ -83,12 +83,12 @@ end function pango_text_extents(pangolayout::PangoLayout, text::AbstractString) textarray = convert(Vector{UInt8}, convert(Compat.String, text)) ccall((:pango_layout_set_markup, libpango), - Void, (Ptr{Void}, Ptr{UInt8}, Int32), + Cvoid, (Ptr{Cvoid}, Ptr{UInt8}, Int32), pangolayout.layout, textarray, length(textarray)) extents = Array{Int32}(4) ccall((:pango_layout_get_extents, libpango), - Void, (Ptr{Void}, Ptr{Int32}, Ptr{Int32}), + Cvoid, (Ptr{Cvoid}, Ptr{Int32}, Ptr{Int32}), pangolayout.layout, extents, C_NULL) width, height = (extents[3] / PANGO_SCALE)pt, (extents[4] / PANGO_SCALE)pt @@ -222,12 +222,12 @@ end # Returns: # A tuple of the form (start_idx, end_idx, value) # -function unpack_pango_attr(ptr::Ptr{Void}, t::Symbol) - ptr += sizeof(Ptr{Void}) # skip `klass` pointer +function unpack_pango_attr(ptr::Ptr{Cvoid}, t::Symbol) + ptr += sizeof(Ptr{Cvoid}) # skip `klass` pointer ptr = convert(Ptr{UInt32}, ptr) idx = unsafe_wrap(Array, ptr, (2,), false) ptr += 2 * sizeof(UInt32) - ptr = convert(Ptr{Void}, ptr) + ptr = convert(Ptr{Cvoid}, ptr) if t == :PangoAttrInt value = unpack_pango_int(ptr) @@ -247,10 +247,10 @@ end # # Returns: # And int value. -unpack_pango_int(ptr::Ptr{Void}) = unsafe_wrap(Array, convert(Ptr{Int32}, ptr), (1,), false)[1] -unpack_pango_float(ptr::Ptr{Void}) = unsafe_wrap(Array, convert(Ptr{Float64}, ptr), (1,), false)[1] +unpack_pango_int(ptr::Ptr{Cvoid}) = unsafe_wrap(Array, convert(Ptr{Int32}, ptr), (1,), false)[1] +unpack_pango_float(ptr::Ptr{Cvoid}) = unsafe_wrap(Array, convert(Ptr{Float64}, ptr), (1,), false)[1] -#function unpack_pango_size(ptr::Ptr{Void}) +#function unpack_pango_size(ptr::Ptr{Cvoid}) #ptr = convert(Ptr{Int32}, ptr) #size = point_to_array(ptr, (1,))[1] #ptr = convert(Ptr{UInt32}, ptr) @@ -272,23 +272,23 @@ unpack_pango_float(ptr::Ptr{Void}) = unsafe_wrap(Array, convert(Ptr{Float64}, pt # values are increasing and the attribute is a set of attributes that # should be applied starting at that position. # -function unpack_pango_attr_list(ptr::Ptr{Void}) +function unpack_pango_attr_list(ptr::Ptr{Cvoid}) attr_it = ccall((:pango_attr_list_get_iterator, libpango), - Ptr{Void}, (Ptr{Void},), ptr) + Ptr{Cvoid}, (Ptr{Cvoid},), ptr) # Alias some ugly C calls. attr_it_next = () -> ccall((:pango_attr_iterator_next, libpango), - Int32, (Ptr{Void},), attr_it) + Int32, (Ptr{Cvoid},), attr_it) attr_it_get = attr_name -> ccall((:pango_attr_iterator_get, libpango), - Ptr{Void}, (Ptr{Void}, Int32), + Ptr{Cvoid}, (Ptr{Cvoid}, Int32), attr_it, eval(attr_name)) attr_it_range = () -> begin start_idx = Array{Int32}(1) end_idx = Array{Int32}(1) ccall((:pango_attr_iterator_range, libpango), - Void, (Ptr{Void}, Ptr{Int32}, Ptr{Int32}), + Cvoid, (Ptr{Cvoid}, Ptr{Int32}, Ptr{Int32}), attr_it, start_idx, end_idx) (start_idx[1], end_idx[1]) end @@ -314,7 +314,7 @@ function unpack_pango_attr_list(ptr::Ptr{Void}) end ccall((:pango_attr_iterator_destroy, libpango), - Void, (Ptr{Void},), attr_it) + Cvoid, (Ptr{Cvoid},), attr_it) attrs end @@ -322,11 +322,11 @@ end function pango_to_svg(text::AbstractString) c_stripped_text = Ref{Ptr{UInt8}}() - c_attr_list = Ref{Ptr{Void}}() + c_attr_list = Ref{Ptr{Cvoid}}() ret = ccall((:pango_parse_markup, libpango), - Int32, (Cstring, Int32, UInt32, Ptr{Ptr{Void}}, - Ptr{Ptr{UInt8}}, Ptr{UInt32}, Ptr{Void}), + Int32, (Cstring, Int32, UInt32, Ptr{Ptr{Cvoid}}, + Ptr{Ptr{UInt8}}, Ptr{UInt32}, Ptr{Cvoid}), text, -1, 0, c_attr_list, c_stripped_text, C_NULL, C_NULL) diff --git a/src/pgf_backend.jl b/src/pgf_backend.jl index c30521ae..9db4b4b0 100644 --- a/src/pgf_backend.jl +++ b/src/pgf_backend.jl @@ -20,13 +20,13 @@ mutable struct PGF <: Backend # Fill properties cannot be "cleanly" applied to # multiple form primitives. It must be applied # each time an object is drawn - fill::Nullable{Color} + fill::Union{Color, Nothing} fill_opacity::Float64 - stroke::Nullable{Color} + stroke::Union{Color, Nothing} stroke_opacity::Float64 - fontfamily::Nullable{AbstractString} + fontfamily::Union{AbstractString, Nothing} fontsize::Float64 # Current level of indentation. @@ -50,11 +50,11 @@ mutable struct PGF <: Backend # SVG forbids defining the same property twice, so we have to keep track # of which vector property of which type is in effect. If two properties of # the same type are in effect, the one higher on the stack takes precedence. - vector_properties::Dict{Type, Nullable{Property}} + vector_properties::Dict{Type, Union{Property, Nothing}} # Clip-paths that need to be defined at the end of the document. # Not quite sure how to deal with clip paths yet - clippath::Nullable{ClipPrimitive} + clippath::Union{ClipPrimitive, Nothing} # clippaths::Dict{ClipPrimitive, String} # True when finish has been called and no more drawing should occur @@ -64,7 +64,7 @@ mutable struct PGF <: Backend ownedfile::Bool # Filename when ownedfile is true - filename::Nullable{AbstractString} + filename::Union{AbstractString, Nothing} # Emit the graphic on finish when writing to a buffer. emit_on_finish::Bool @@ -94,7 +94,7 @@ function PGF(out::IO, visible = true, color_set = Set{Color}([colorant"black"]), property_stack = Array{PGFPropertyFrame}(0), - vector_properties = Dict{Type, Nullable{Property}}(), + vector_properties = Dict{Type, Union{Property, Nothing}}(), clippath = nothing, finished = false, ownedfile = false, @@ -231,21 +231,21 @@ function get_vector_properties(img::PGF, idx::Int) props_str = Compat.String[] modifiers = Compat.String[] for (propertytype, property) in img.vector_properties - isnull(property) && continue - primitives = get(property).primitives + (property === nothing) && continue + primitives = property.primitives idx > length(primitives) && error("Vector form and vector property differ in length. Can't distribute.") push_property!(props_str, img, primitives[idx]) end - if !isnull(img.fill) - push!(props_str, string("fill=mycolor",hex(get(img.fill)))) + if img.fill !== nothing + push!(props_str, string("fill=mycolor",hex(img.fill))) img.fill_opacity < 1.0 && push!(props_str, string("fill opacity=",svg_fmt_float(img.fill_opacity))) end - if !isnull(img.stroke) - push!(props_str, string("draw=mycolor",hex(get(img.stroke)))) + if img.stroke !== nothing + push!(props_str, string("draw=mycolor",hex(img.stroke))) img.stroke_opacity < 1.0 && push!(props_str, string("draw opacity=",svg_fmt_float(img.stroke_opacity))) end @@ -267,7 +267,7 @@ function push_property!(props_str, img::PGF, property::StrokePrimitive) img.stroke = property.color end - isnull(img.stroke) || push!(img.color_set, convert(RGB, property.color)) + (img.stroke === nothing) || push!(img.color_set, convert(RGB, property.color)) end function push_property!(props_str, img::PGF, property::FillPrimitive) @@ -278,7 +278,7 @@ function push_property!(props_str, img::PGF, property::FillPrimitive) img.fill = property.color end - isnull(img.fill) || push!(img.color_set, convert(RGB, property.color)) + (img.fill === nothing) || push!(img.color_set, convert(RGB, property.color)) end push_property!(props_str, img::PGF, property::VisiblePrimitive) = @@ -482,13 +482,13 @@ function push_property_frame(img::PGF, properties::Vector{Property}) if length(prop_str) > 0 @printf(img.buf, "[%s]\n", join(prop_str, ",")) end - if !isnull(img.clippath) + if img.clippath !== nothing write(img.buf, "\\clip ") - print_pgf_path(img.buf, get(img.clippath).points) + print_pgf_path(img.buf, img.clippath.points) write(img.buf, ";\n") end - if (!img.texfonts && !isnull(img.fontfamily)) - @printf(img.buf, "\\fontspec{%s}\n", get(img.fontfamily)) + if (!img.texfonts && (img.fontfamily !== nothing)) + @printf(img.buf, "\\fontspec{%s}\n", img.fontfamily) end end diff --git a/src/svg.jl b/src/svg.jl index 7e82f4da..11503507 100644 --- a/src/svg.jl +++ b/src/svg.jl @@ -6,11 +6,12 @@ const snapsvgjs = joinpath(dirname(@__FILE__), "..", "data", "snap.svg-min.js") # SVG. const xmlns = Dict() +# All svg (in our use) coordinates are in millimeters. This number gives the +# largest deviation from the true position allowed in millimeters. +const eps = 0.01 + # Format a floating point number into a decimal string of reasonable precision. function svg_fmt_float(x::Fractional) - # All svg (in our use) coordinates are in millimeters. This number gives the - # largest deviation from the true position allowed in millimeters. - const eps = 0.01 a = @sprintf("%0.8f", round(x / eps) * eps) n = length(a) @@ -28,9 +29,7 @@ end # A much faster version of svg_fmt_float. This does not allocate any # temporary buffers, because it writes directly to the output. function svg_print_float(io::IO, x::AbstractFloat) - const ndig = 2 - const eps = 0.01 - #const eps = 1.0/10^ndig + ndig = 2 if isfinite(x) if x < 0 @@ -83,7 +82,7 @@ end # Format a color for SVG. svg_fmt_color(c::Color) = string("#", hex(c)) -svg_fmt_color(c::(Void)) = "none" +svg_fmt_color(c::Nothing) = "none" # Replace newlines in a string with the appropriate SVG tspan tags. function svg_newlines(input::AbstractString, x::Float64) @@ -147,7 +146,7 @@ mutable struct SVG <: Backend out::IO # Save output from IOBuffers to allow multiple calls to writemime - cached_out::Union{AbstractString, (Void)} + cached_out::Union{AbstractString, Nothing} # Unique ID for the figure. id::AbstractString @@ -161,7 +160,7 @@ mutable struct SVG <: Backend # SVG forbids defining the same property twice, so we have to keep track # of which vector property of which type is in effect. If two properties of # the same type are in effect, the one higher on the stack takes precedence. - vector_properties::Dict{Type, Union{(Void), Property}} + vector_properties::Dict{Type, Union{Property, Nothing}} # Clip-paths that need to be defined at the end of the document. clippaths::OrderedDict{ClipPrimitive, Compat.String} @@ -180,7 +179,7 @@ mutable struct SVG <: Backend ownedfile::Bool # Filename when ownedfile is true - filename::Union{AbstractString, (Void)} + filename::Union{AbstractString, Nothing} # Emit the graphic on finish when writing to a buffer. emit_on_finish::Bool @@ -227,7 +226,7 @@ function SVG(out::IO, id = string("img-", string(Base.Random.uuid4())[1:8]), indentation = 0, property_stack = Array{SVGPropertyFrame}(0), - vector_properties = Dict{Type, Union{(Void), Property}}(), + vector_properties = Dict{Type, Union{Property, Nothing}}(), clippaths = OrderedDict{ClipPrimitive, Compat.String}(), batches = Array{Tuple{FormPrimitive, Compat.String}}(0), embobj = Set{AbstractString}(), diff --git a/src/table.jl b/src/table.jl index 779ac0e2..04c63159 100644 --- a/src/table.jl +++ b/src/table.jl @@ -24,7 +24,7 @@ mutable struct Table <: ContainerPromise fixed_configs::Vector # Coordinate system used for children - units::Nullable{UnitBox} + units::Union{UnitBox, Nothing} # Z-order of this context relative to its siblings. order::Int @@ -40,7 +40,7 @@ end function Table(m::Integer, n::Integer, y_focus::UnitRange{Int}, x_focus::UnitRange{Int}; y_prop=nothing, x_prop=nothing, aspect_ratio=nothing, - units=NullUnitBox(), order=0, withjs=false, withoutjs=false, + units=nothing, order=0, withjs=false, withoutjs=false, fixed_configs=Any[]) if x_prop != nothing diff --git a/test/immerse.jl b/test/immerse.jl index bb960f67..a57e43b8 100644 --- a/test/immerse.jl +++ b/test/immerse.jl @@ -2,7 +2,8 @@ # need to edit these tests to make them pass, that's fine, but please # submit the corresponding fix to Immerse. -using Compose, Base.Test +using Test +using Compose import Cairo ### The Immerse backend diff --git a/test/misc.jl b/test/misc.jl index 7af1f290..90df3e3e 100644 --- a/test/misc.jl +++ b/test/misc.jl @@ -1,4 +1,5 @@ -using Colors, Base.Test +using Test, Random +using Colors # showcompact tomato_bisque = compose(context(), From 999a68876106f7e9264986cd1372f9f9eaf5cc97 Mon Sep 17 00:00:00 2001 From: "Ralph A. Smith" Date: Sun, 12 Aug 2018 18:31:53 -0400 Subject: [PATCH 2/8] fix up use of Requires for Julia v0.7 This version works if callers of PNG etc. import Cairo themselves. --- src/Compose.jl | 22 +++++++++++++++++----- src/cairo_backends.jl | 31 +++++++++++++++++++++---------- src/pango.jl | 7 ++++++- src/svg.jl | 7 ++++++- test/immerse.jl | 1 + 5 files changed, 51 insertions(+), 17 deletions(-) diff --git a/src/Compose.jl b/src/Compose.jl index 14272eec..056b0807 100644 --- a/src/Compose.jl +++ b/src/Compose.jl @@ -125,6 +125,7 @@ default_stroke_color = nothing default_fill_color = colorant"black" # Use cairo for the PNG, PS, PDF if it's installed. +if VERSION < v"0.7-" macro missing_cairo_error(backend) msg1 = """ Cairo and Fontconfig are necessary for the $(backend) backend. Run: @@ -137,11 +138,22 @@ macro missing_cairo_error(backend) """ string(msg1, msg2) end +else +macro missing_cairo_error(backend) + msg1 = """ + The Cairo and Fontconfig packages are necessary for the $(backend) backend. + Add them with the package manager if necessary, then run: + import Cairo, Fontconfig + before invoking $(backend). + """ + string(msg1) +end +end -global PDF -PNG(args...) = error(@missing_cairo_error "PNG") -PS(args...) = error(@missing_cairo_error "PS") -PDF(args...) = error(@missing_cairo_error "PDF") +#global PDF +PNG(::Any, args...) = error(@missing_cairo_error "PNG") +PS(::Any, args...) = error(@missing_cairo_error "PS") +PDF(::Any, args...) = error(@missing_cairo_error "PDF") include("svg.jl") include("pgf_backend.jl") @@ -155,7 +167,7 @@ function link_fontconfig() pango_cairo_ctx = C_NULL include("pango.jl") - ccall((:g_type_init, Cairo._jl_libgobject), Cvoid, ()) + ccall((:g_type_init, libgobject), Cvoid, ()) pango_cairo_fm = ccall((:pango_cairo_font_map_new, libpangocairo), Ptr{Cvoid}, ()) pango_cairo_ctx = ccall((:pango_font_map_create_context, libpango), diff --git a/src/cairo_backends.jl b/src/cairo_backends.jl index c53a98f8..bcdb9455 100644 --- a/src/cairo_backends.jl +++ b/src/cairo_backends.jl @@ -1,11 +1,16 @@ using Compat # Cairo backend for compose -import Cairo +if VERSION < v"0.7-" + import Cairo +end +# in later versions, Requires does the import for us, but resolution is tricky -using Cairo: CairoContext, CairoSurface, CairoARGBSurface, - CairoEPSSurface, CairoPDFSurface, CairoSVGSurface, - CairoImageSurface +for name in (:CairoContext, :CairoSurface, :CairoARGBSurface, :CairoEPSSurface, + :CairoPDFSurface, :CairoSVGSurface, :CairoImageSurface) + val = getfield(Cairo,name) + @eval const $name = $val +end abstract type ImageBackend end abstract type PNGBackend <: ImageBackend end @@ -185,9 +190,15 @@ Image{B}(width::MeasureOrNumber=default_graphic_width, dpi = (B==PNGBackend ? 96 : 72)) where {B<:ImageBackend} = Image{B}(IOBuffer(), width, height, emit_on_finish, dpi=dpi) -const PNG = Image{PNGBackend} -const PDF = Image{PDFBackend} -const PS = Image{PSBackend} +PNG(x::Union{CairoSurface,IO,AbstractString,MeasureOrNumber}, args...) = + Image{PNGBackend}(x, args...) + +PDF(x::Union{CairoSurface,IO,AbstractString,MeasureOrNumber}, args...) = + Image{PDFBackend}(x, args...) + +PS(x::Union{CairoSurface,IO,AbstractString,MeasureOrNumber}, args...) = + Image{PSBackend}(x, args...) + const CAIROSURFACE = Image{CairoBackend} function (img::Image)(x) @@ -274,9 +285,9 @@ isfinished(img::Image) = img.finished root_box(img::Image) = BoundingBox(width(img), height(img)) -show(io::IO, ::MIME"image/png", img::PNG) = write(io, String(take!(img.out))) -show(io::IO, ::MIME"application/pdf", img::PDF) = write(io, String(take!(img.out))) -show(io::IO, ::MIME"application/postscript", img::PS) = write(io, String(take!(img.out))) +show(io::IO, ::MIME"image/png", img::Image{PNGBackend}) = write(io, String(take!(img.out))) +show(io::IO, ::MIME"application/pdf", img::Image{PDFBackend}) = write(io, String(take!(img.out))) +show(io::IO, ::MIME"application/postscript", img::Image{PSBackend}) = write(io, String(take!(img.out))) # Applying Properties diff --git a/src/pango.jl b/src/pango.jl index 15b7e105..2473d680 100644 --- a/src/pango.jl +++ b/src/pango.jl @@ -1,9 +1,14 @@ # Estimation of text extents using pango. -import Fontconfig +if VERSION < v"0.7-" + import Fontconfig +end +# In later versions, Requires does the import for us. +# Qualified uses of Fontconfig and Cairo entities are not problematic. const libpangocairo = Cairo._jl_libpangocairo const libpango = Cairo._jl_libpango +const libgobject = Cairo._jl_libgobject # Cairo text backend const CAIRO_FONT_TYPE_TOY = 0 diff --git a/src/svg.jl b/src/svg.jl index 11503507..0fd59761 100644 --- a/src/svg.jl +++ b/src/svg.jl @@ -1,4 +1,9 @@ using Compat +if VERSION < v"0.7-" + import Base.Random.uuid4 +else + import UUIDs: uuid4 +end const snapsvgjs = joinpath(dirname(@__FILE__), "..", "data", "snap.svg-min.js") @@ -223,7 +228,7 @@ function SVG(out::IO, jsmode::Symbol=:none; cached_out = nothing, - id = string("img-", string(Base.Random.uuid4())[1:8]), + id = string("img-", string(uuid4())[1:8]), indentation = 0, property_stack = Array{SVGPropertyFrame}(0), vector_properties = Dict{Type, Union{Property, Nothing}}(), diff --git a/test/immerse.jl b/test/immerse.jl index a57e43b8..71df0e13 100644 --- a/test/immerse.jl +++ b/test/immerse.jl @@ -5,6 +5,7 @@ using Test using Compose import Cairo +import Measures ### The Immerse backend srf = Cairo.CairoImageSurface(10, 10, Cairo.FORMAT_RGB24) From 0a051ac9e99827b6778f4ce2ca09cb08c11d586c Mon Sep 17 00:00:00 2001 From: Tamas Date: Thu, 16 Aug 2018 16:49:26 -0700 Subject: [PATCH 3/8] more fixes for 0.7 update ci and doc gen; drop support for julia v0.6 allow failures on nightly --- .travis.yml | 13 ++--- README.md | 6 +-- REQUIRE | 2 +- docs/Manifest.toml | 104 +++++++++++++++++++++++++++++++++++++++ docs/Project.toml | 2 + docs/make.jl | 2 +- examples/golden_rect.jl | 1 + src/Compose.jl | 1 + src/cairo_backends.jl | 14 +++--- src/container.jl | 6 +-- src/fontfallback.jl | 8 +-- src/form.jl | 4 +- src/list.jl | 6 +-- src/misc.jl | 4 +- src/pango.jl | 10 ++-- src/pgf_backend.jl | 8 +-- src/property.jl | 8 +-- src/svg.jl | 25 +++++----- src/table-jump.jl | 2 +- src/table.jl | 12 ++--- test/compare_examples.jl | 6 +-- test/misc.jl | 2 +- test/runtests.jl | 5 +- 23 files changed, 179 insertions(+), 72 deletions(-) create mode 100644 docs/Manifest.toml create mode 100644 docs/Project.toml diff --git a/.travis.yml b/.travis.yml index 30f4eaff..ea070a70 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,9 +4,12 @@ os: sudo: required dist: trusty julia: - - 0.6 + - 0.7 - 1.0 - nightly +matrix: + allow_failures: + - julia: nightly notifications: email: false before_install: @@ -14,9 +17,7 @@ before_install: sudo apt-get update -qq -y; sudo apt-get install -y libcairo2 libfontconfig1 libpango1.0-0 libpng12-0 libpng12-dev libpixman-1-0 gettext; fi -script: - - if [[ -a .git/shallow ]]; then git fetch --unshallow; fi - - julia -e 'Pkg.clone(pwd()); Pkg.build("Compose"); Pkg.test("Compose"; coverage=true)' after_success: - - julia -e 'cd(Pkg.dir("Compose")); Pkg.add("Coverage"); using Coverage; Codecov.submit(process_folder())' - - julia -e 'cd(Pkg.dir("Compose")); map(x -> Pkg.add(strip(x)), readlines(open(joinpath("docs", "REQUIRE")))); include(joinpath("docs", "make.jl"))' + - julia --project=docs -e 'using Pkg; Pkg.instantiate()' + - julia --project=docs docs/make.jl + - julia -e 'cd("test"); include("coverage.jl")' \ No newline at end of file diff --git a/README.md b/README.md index 5711915c..03fabbab 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Compose! -[![][docs-latest-img]][docs-latest-url] [![][pkg-0.6-img]][pkg-0.6-url] [![][pkg-1.0-img]][pkg-1.0-url] [![][travis-img]][travis-url] [![][codecov-img]][codecov-url] +[![][docs-latest-img]][docs-latest-url] [![][pkg-0.7-img]][pkg-0.7-url] [![][pkg-1.0-img]][pkg-1.0-url] [![][travis-img]][travis-url] [![][codecov-img]][codecov-url] Compose is a vector graphics library for Julia. It forms the basis for the statistical graphics system @@ -24,8 +24,8 @@ consistent and powerful means of building vector graphics. [docs-latest-img]: https://img.shields.io/badge/docs-latest-blue.svg [docs-latest-url]: https://giovineitalia.github.io/Compose.jl/latest -[pkg-0.6-img]: http://pkg.julialang.org/badges/Compose_0.6.svg -[pkg-0.6-url]: http://pkg.julialang.org/?pkg=Compose +[pkg-0.7-img]: http://pkg.julialang.org/badges/Compose_0.7.svg +[pkg-0.7-url]: http://pkg.julialang.org/?pkg=Compose [pkg-1.0-img]: http://pkg.julialang.org/badges/Compose_1.0.svg [pkg-1.0-url]: http://pkg.julialang.org/?pkg=Compose diff --git a/REQUIRE b/REQUIRE index 2030ed9f..d352a0e1 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,6 +1,6 @@ julia 0.6 Colors -Compat 0.52.0 +Compat 0.69.0 DataStructures IterTools JSON diff --git a/docs/Manifest.toml b/docs/Manifest.toml new file mode 100644 index 00000000..d2325670 --- /dev/null +++ b/docs/Manifest.toml @@ -0,0 +1,104 @@ +[[Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[Compat]] +deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] +git-tree-sha1 = "277d3807440d9793421354b6680911fc95d91a84" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "1.0.1" + +[[Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[DelimitedFiles]] +deps = ["Mmap"] +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" + +[[Distributed]] +deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[DocStringExtensions]] +deps = ["Compat"] +git-tree-sha1 = "a2ab006ff561a57eb858cee5314445b16c2fd2dd" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.4.6" + +[[Documenter]] +deps = ["Compat", "DocStringExtensions", "Logging", "REPL"] +git-tree-sha1 = "c39d51ac14e9423334c595ff47e9a68dda01409b" +uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +version = "0.19.5" + +[[InteractiveUtils]] +deps = ["LinearAlgebra", "Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[LibGit2]] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[LinearAlgebra]] +deps = ["Libdl"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[Pkg]] +deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" + +[[Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[Random]] +deps = ["Serialization"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" + +[[Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[SparseArrays]] +deps = ["LinearAlgebra", "Random"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[Test]] +deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[UUIDs]] +deps = ["Random"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" diff --git a/docs/Project.toml b/docs/Project.toml new file mode 100644 index 00000000..dfa65cd1 --- /dev/null +++ b/docs/Project.toml @@ -0,0 +1,2 @@ +[deps] +Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" diff --git a/docs/make.jl b/docs/make.jl index 2d824d3f..8412b5e3 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -13,7 +13,7 @@ makedocs( deploydocs( repo = "github.com/GiovineItalia/Compose.jl.git", - julia = "0.5", + julia = "1.0", osname = "linux", deps = nothing, make = nothing, diff --git a/examples/golden_rect.jl b/examples/golden_rect.jl index 8b78f3c6..9ebb24e5 100755 --- a/examples/golden_rect.jl +++ b/examples/golden_rect.jl @@ -2,6 +2,7 @@ using Colors using Compose +using Compat.MathConstants function golden_rect(n::Int) if n == 0 return context() end diff --git a/src/Compose.jl b/src/Compose.jl index 056b0807..16dad600 100644 --- a/src/Compose.jl +++ b/src/Compose.jl @@ -197,6 +197,7 @@ try getfield(Compose, :Cairo) # throws if Cairo isn't being used show(io::IO, ::MIME"image/png", ctx::Context) = draw(PNG(io, default_graphic_width, default_graphic_height), ctx) +catch end function pad_outer(c::Context, diff --git a/src/cairo_backends.jl b/src/cairo_backends.jl index bcdb9455..cbe6b27a 100644 --- a/src/cairo_backends.jl +++ b/src/cairo_backends.jl @@ -110,8 +110,8 @@ function Image{B}(surface::CairoSurface, fontsize = default_font_size, font = default_font_family, clip = nothing, - state_stack = Array{ImagePropertyState}(0), - property_stack = Array{ImagePropertyFrame}(0), + state_stack = Array{ImagePropertyState}(undef, 0), + property_stack = Array{ImagePropertyFrame}(undef, 0), vector_properties = Dict{Type, Union{Property, Nothing}}(), owns_surface = false, ownedfile = false, @@ -298,7 +298,7 @@ function push_property_frame(img::Image, properties::Vector{Property}) frame = ImagePropertyFrame() applied_properties = Set{Type}() - scalar_properties = Array{Property}(0) + scalar_properties = Array{Property}(undef, 0) for property in properties if isscalar(property) && !(typeof(property) in applied_properties) push!(scalar_properties, property) @@ -471,8 +471,8 @@ apply_property(img::Image, property::SVGAttributePrimitive) = nothing # -------------- function current_point(img::Image) - x = Array{Float64}(1) - y = Array{Float64}(1) + x = Array{Float64}(undef, 1) + y = Array{Float64}(undef, 1) ccall((:cairo_get_current_point, Cairo._jl_libcairo), Cvoid, (Ptr{Cvoid}, Ptr{Float64}, Ptr{Float64}), img.ctx.ptr, x, y) return ((x[1] / img.ppmm)*mm, (x[2] / img.ppmm)*mm) @@ -667,8 +667,8 @@ function draw(img::Image, prim::EllipsePrimitive) (prim.x_point[2].value - cy)^2) ry = sqrt((prim.y_point[1].value - cx)^2 + (prim.y_point[2].value - cy)^2) - theta = atan2(prim.x_point[2].value - cy, - prim.x_point[1].value - cx) + theta = atan(prim.x_point[2].value - cy, + prim.x_point[1].value - cx) all(isfinite([cx, cy, rx, ry, theta])) || return diff --git a/src/container.jl b/src/container.jl index ad885cf9..20e964fc 100644 --- a/src/container.jl +++ b/src/container.jl @@ -400,7 +400,7 @@ function drawpart(backend::Backend, container::Container, has_properties = false if !isa(ctx.property_children, ListNull) || ctx.clip has_properties = true - properties = Array{Property}(0) + properties = Array{Property}(undef, 0) child = ctx.property_children while !isa(child, ListNull) @@ -457,7 +457,7 @@ function drawpart(backend::Backend, container::Container, end if ordered_children - container_children = Array{Tuple{Int, Int, Container}}(0) + container_children = Array{Tuple{Int, Int, Container}}(undef, 0) child = ctx.container_children while !isa(child, ListNull) push!(container_children, @@ -497,7 +497,7 @@ function introspect(root::Context) # TODO: It would be nice if we can try to do a better job of positioning # nodes within their levels - q = Queue(Tuple{ComposeNode, Int}) + q = Queue{Tuple{ComposeNode, Int}}() enqueue!(q, (root, 1)) figs = compose!(context(), stroke("#333"), linewidth(0.5mm)) figsize = 6mm diff --git a/src/fontfallback.jl b/src/fontfallback.jl index 46b9779d..f0ee81ed 100644 --- a/src/fontfallback.jl +++ b/src/fontfallback.jl @@ -18,8 +18,8 @@ const text_extents_scale_y = 1.0 # Normalized Levenshtein distance between two strings. function levenshtein(a::AbstractString, b::AbstractString) - a = Compat.replace(lowercase(a), r"\s+"=>"") - b = Compat.replace(lowercase(b), r"\s+"=>"") + a = replace(lowercase(a), r"\s+"=>"") + b = replace(lowercase(b), r"\s+"=>"") n = length(a) m = length(b) D = zeros(UInt, n + 1, m + 1) @@ -74,7 +74,7 @@ end # Approximate text width in millimeters. # function text_width(widths::Dict, text::AbstractString, size::Float64) - stripped_text = Compat.replace(text, r"<[^>]*>"=>"") + stripped_text = replace(text, r"<[^>]*>"=>"") width = 0 for c in stripped_text width += get(widths, string(c), widths["w"]) @@ -144,7 +144,7 @@ end # Amazingly crude fallback to parse pango markup into svg. function pango_to_svg(text::AbstractString) pat = r"<(/?)\s*([^>]*)\s*>" - input = convert(Array{UInt8}, text) + input = codeunits(text) output = IOBuffer() lastpos = 1 diff --git a/src/form.jl b/src/form.jl index 316d7f3b..fa95e06d 100644 --- a/src/form.jl +++ b/src/form.jl @@ -65,7 +65,7 @@ function polygon(point_arrays::AbstractArray, tag=empty_tag) VecType = XM == YM == Any ? Vec : Tuple{XM, YM} PrimType = XM == YM == Any ? PolygonPrimitive : PolygonPrimitive{VecType} - polyprims = Array{PrimType}(length(point_arrays)) + polyprims = Array{PrimType}(undef, length(point_arrays)) for (i, point_array) in enumerate(point_arrays) polyprims[i] = PrimType(VecType[(x_measure(point[1]), y_measure(point[2])) for point in point_array]) @@ -471,7 +471,7 @@ function line(point_arrays::AbstractArray, tag=empty_tag) VecType = XM == YM == Any ? Vec2 : Tuple{XM, YM} PrimType = XM == YM == Any ? LinePrimitive : LinePrimitive{VecType} - lineprims = Array{PrimType}(length(point_arrays)) + lineprims = Array{PrimType}(undef, length(point_arrays)) for (i, point_array) in enumerate(point_arrays) p = PrimType(VecType[(x_measure(point[1]), y_measure(point[2])) for point in point_array]) diff --git a/src/list.jl b/src/list.jl index ce9f842a..3eec7cf1 100644 --- a/src/list.jl +++ b/src/list.jl @@ -17,9 +17,9 @@ head(l::ListNode) = l.head tail(l::ListNode) = l.tail # iterator -start(l::List) = l -next(::List, l::List) = (l.head, l.tail) -done(::List, l::List) = typeof(l) <: ListNull +function Base.iterate(l::List, state=l) + return typeof(state) <: ListNull ? nothing : (state.head, state.tail) +end cons(value, l::List{T}) where T = ListNode{T}(value, l) function length(l::List{T}) where T diff --git a/src/misc.jl b/src/misc.jl index 1f71c0de..fcafb3e7 100644 --- a/src/misc.jl +++ b/src/misc.jl @@ -95,7 +95,7 @@ macro makeprimitives(args) push!(maxlen_ex.args, quote if isempty($(esc(arr))) - primitives = Array{$(T)}(0) + primitives = Array{$(T)}(undef, 0) @goto done end end) push!(maxlen_ex.args, quote n = max(n, length($(esc(arr)))) end) @@ -106,7 +106,7 @@ macro makeprimitives(args) quote $(maxlen_ex) - primitives = Array{$(esc(T))}(n) + primitives = Array{$(esc(T))}(undef, n) for i in 1:n $(iter_ex) primitives[i] = $(esc(constructor)) diff --git a/src/pango.jl b/src/pango.jl index 2473d680..65cadbc5 100644 --- a/src/pango.jl +++ b/src/pango.jl @@ -91,7 +91,7 @@ function pango_text_extents(pangolayout::PangoLayout, text::AbstractString) Cvoid, (Ptr{Cvoid}, Ptr{UInt8}, Int32), pangolayout.layout, textarray, length(textarray)) - extents = Array{Int32}(4) + extents = Array{Int32}(undef, 4) ccall((:pango_layout_get_extents, libpango), Cvoid, (Ptr{Cvoid}, Ptr{Int32}, Ptr{Int32}), pangolayout.layout, extents, C_NULL) @@ -290,8 +290,8 @@ function unpack_pango_attr_list(ptr::Ptr{Cvoid}) attr_it, eval(attr_name)) attr_it_range = () -> begin - start_idx = Array{Int32}(1) - end_idx = Array{Int32}(1) + start_idx = Array{Int32}(undef, 1) + end_idx = Array{Int32}(undef, 1) ccall((:pango_attr_iterator_range, libpango), Cvoid, (Ptr{Cvoid}, Ptr{Int32}, Ptr{Int32}), attr_it, start_idx, end_idx) @@ -299,7 +299,7 @@ function unpack_pango_attr_list(ptr::Ptr{Cvoid}) end - attrs = Array{Tuple{Int, PangoAttr}}(0) + attrs = Array{Tuple{Int, PangoAttr}}(undef, 0) while attr_it_next() != 0 attr = PangoAttr() @@ -339,7 +339,7 @@ function pango_to_svg(text::AbstractString) # TODO: do c_stripped_text and c_attr_list need to be freed? - text = convert(Vector{UInt8}, unsafe_string(c_stripped_text[])) + text = unsafe_wrap(Array, c_stripped_text[]) last_idx = 1 open_tag = false diff --git a/src/pgf_backend.jl b/src/pgf_backend.jl index 9db4b4b0..e57857bf 100644 --- a/src/pgf_backend.jl +++ b/src/pgf_backend.jl @@ -93,7 +93,7 @@ function PGF(out::IO, buf = IOBuffer(), visible = true, color_set = Set{Color}([colorant"black"]), - property_stack = Array{PGFPropertyFrame}(0), + property_stack = Array{PGFPropertyFrame}(undef, 0), vector_properties = Dict{Type, Union{Property, Nothing}}(), clippath = nothing, finished = false, @@ -384,8 +384,8 @@ function draw(img::PGF, prim::EllipsePrimitive, idx::Int) (prim.x_point[2].value - cy)^2) ry = sqrt((prim.y_point[1].value - cx)^2 + (prim.y_point[2].value - cy)^2) - theta = rad2deg(atan2(prim.x_point[2].value - cy, - prim.x_point[1].value - cx)) + theta = rad2deg(atan(prim.x_point[2].value - cy, + prim.x_point[1].value - cx)) all(isfinite([cx, cy, rx, ry, theta])) || return @@ -458,7 +458,7 @@ function push_property_frame(img::PGF, properties::Vector{Property}) frame = PGFPropertyFrame() applied_properties = Set{Type}() - scalar_properties = Array{Property}(0) + scalar_properties = Array{Property}(undef, 0) for property in properties if !isrepeatable(property) && (typeof(property) in applied_properties) continue diff --git a/src/property.jl b/src/property.jl index 7a025cdc..aec1b65f 100644 --- a/src/property.jl +++ b/src/property.jl @@ -234,7 +234,7 @@ end const Clip = Property{ClipPrimitive} -clip() = Clip([ClipPrimitive(Array{Vec}(0))]) +clip() = Clip([ClipPrimitive(Array{Vec}(undef, 0))]) function clip(points::AbstractArray{T}) where T <: XYTupleOrVec XM, YM = narrow_polygon_point_types(Vector[points]) @@ -255,7 +255,7 @@ function clip(point_arrays::AbstractArray...) VecType = XM == YM == Any ? Vec : Vec{XM, YM} PrimType = XM == YM == Any ? ClipPrimitive : ClipPrimitive{VecType} - clipprims = Array{PrimType}(length(point_arrays)) + clipprims = Array{PrimType}(undef, length(point_arrays)) for (i, point_array) in enumerate(point_arrays) clipprims[i] = ClipPrimitive(VecType[(x_measure(point[1]), y_measure(point[2])) for point in point_array]) @@ -434,9 +434,9 @@ function resolve(box::AbsoluteBox, units::UnitBox, t::Transform, primitive::JSCa i = 1 validx = 1 while true - j = search(primitive.code, '%', i) + j = findnext(primitive.code, '%', i) - if j == 0 + if j === nothing write(newcode, primitive.code[i:end]) break end diff --git a/src/svg.jl b/src/svg.jl index 0fd59761..eab6f83e 100644 --- a/src/svg.jl +++ b/src/svg.jl @@ -1,9 +1,6 @@ using Compat -if VERSION < v"0.7-" - import Base.Random.uuid4 -else - import UUIDs: uuid4 -end +using Compat.Base64 +using Compat.UUIDs const snapsvgjs = joinpath(dirname(@__FILE__), "..", "data", "snap.svg-min.js") @@ -60,7 +57,7 @@ function svg_print_float(io::IO, x::AbstractFloat) end end -let a = Array{UInt8}(20) +let a = Array{UInt8}(undef, 20) global svg_print_uint function svg_print_uint(io::IO, x::Unsigned, width = 0, drop = false) n = length(a) @@ -115,7 +112,7 @@ end #=end=# # Javascript contained to CDATA block needs to avoid ']]' -escape_script(js::AbstractString) = replace(js, "]]", "] ]") +escape_script(js::AbstractString) = replace(js, "]]"=>"] ]") # When subtree rooted at a context is drawn, it pushes its property children # in the form of a property frame. @@ -230,10 +227,10 @@ function SVG(out::IO, cached_out = nothing, id = string("img-", string(uuid4())[1:8]), indentation = 0, - property_stack = Array{SVGPropertyFrame}(0), + property_stack = Array{SVGPropertyFrame}(undef, 0), vector_properties = Dict{Type, Union{Property, Nothing}}(), clippaths = OrderedDict{ClipPrimitive, Compat.String}(), - batches = Array{Tuple{FormPrimitive, Compat.String}}(0), + batches = Array{Tuple{FormPrimitive, Compat.String}}(undef, 0), embobj = Set{AbstractString}(), finished = false, ownedfile = false, @@ -409,7 +406,7 @@ function finish(img::SVG) write(img.out, """ """) elseif img.jsmode == :linkabs @@ -428,7 +425,7 @@ function finish(img::SVG) if img.jsmode == :embed write(img.out, "