Swiftpack.co - Package - WeirdMath/SwiftyHaru


Build Status codecov documentation Language Platform Cocoapods

SwiftyHaru is an object-oriented Swift wrapper for LibHaru, a C library for creating PDF documents. It brings the safety of Swift to the process of creating PDFs on different platforms like Linux, macOS, iOS, watchOS and tvOS.

Check out which features of LibHaru has already been implemented in FEATURES.md


  • Swift 4.2+
  • iOS 8.0+
  • macOS 10.10+
  • tvOS 9.0+
  • watchOS 2.0+
  • Ubuntu 14.04+



For the latest release in CocoaPods add the following to your Podfile:


pod 'SwiftyHaru'

For the latest dev build:


pod 'SwiftyHaru', :git => 'https://github.com/WeirdMath/SwiftyHaru.git', :branch => 'dev'

Swift Package Manager

Add SwiftyHaru as a dependency to your Package.swift. For example:

let package = Package(
    name: "YourPackageName",
    dependencies: [
        .package(url: "https://github.com/WeirdMath/SwiftyHaru.git", from: "0.3.0")

Important: when building your project that has SwiftyHaru as a dependency, you need to pass the -Xlinker -lz flags to the compiler. This is because SwiftyHaru has to be linked with zlib (which must be intalled on your computer). For example:

$ swift build -Xlinker -lz
$ swift test -Xlinker -lz


Available here.

Getting started

import SwiftyHaru

// Initialize stuff
let document = PDFDocument()

try document.addPage(width: 600, height: 400) { context in

    // Construct a path
    let path = Path()
        .moving(toX: 100, y: 100)
        .appendingLine(toX: 400, y: 100)
        .moving(toX: 500, y: 200)
        .appendingArc(x: 400, y: 200, radius: 100, beginningAngle: 90, endAngle: 180)
        .appendingCircle(x: 200, y: 200, radius: 50)
        .moving(toX: 500, y: 200)
        .appendingCurve(controlPoint1: Point(x: 400, y: 200),
                        controlPoint2: Point(x: 400, y: 300),
                        endPoint: Point(x: 500, y: 300))

    // Paint the path
    context.strokeColor = .blue

    // Put some text
    context.textLeading = 11
    try context.show(text: "Roses are red,\nViolets are blue,\nSugar is sweet,\nAnd so are you.",
                     atX: 300, y: 200)



$ make debug


$ make release


$ make test

Generating Xcode project

Since the Xcode project is explicitly gitignored, you might want to generate it in order to make development comfortable for you. This can be accomplished by running the following command:

make generate-xcodeproj


Stars: 41
Help us keep the lights on

Used By

Total: 0


0.3.0 - Dec 24, 2018

Please note that this version requires Swift 4.2.

Breaking changes:

(Those are a bit massive, sorry.)

  • PDFPage.draw(_:) is removed. The closure for drawing can now be passed to the PDFDocument.addPage(_:) family of methods. This is because multiple calls of PDFPage.draw(_:) resulted in redundant drawing operations (when resetting the context to the default state before each call). To migrate, merge your multiple calls of PDFPage.draw(_:) to one call of PDFDocument.addPage(_:). Pay attention that because of this the DrawingContext.textLeading property is initially set to 0 (not 11 like before), so you may want to change its value before doing any text operations. Also, if you need to access the PDFPage's properties from the drawing closure, use the DrawingContext.page property.
  • PDFPage.draw(object:position:) and PDFPage.draw(object:x:y:) are removed. Use the DrawingContext.draw(_:position:) and DrawingContext.draw(_:x:y:) methods instead.
  • DashStyle.pattern and DashStyle.phase are now let, since changing those values wasn't in any way validated.
  • Vector is now a separate type, not a typealias for Point. Its intefrace has slightly changed: the fields have been renamed from x and y to dx and dy. This new type includes some arithmetic operators that make its use simpler.
  • The required method draw(in:position:) of the Drawable protocol is marked throws.
  • PDFDocument.setEncryptionMode(to:) and PDFDocument.setPermissions(to:) are removed. Use the PDFDocument.setPassword(owner:user:permissions:encryptionMode:) method instead.
  • DrawingContext.withNewGState(_:) doesn't throw if its argument doesn't. Same for DrawingContext.clip(to:rule:_:). If the graphics state stack depth exceeds static DrawingContext.maxGraphicsStateDepth, a precondition failure occures.
  • static PDFError.exceedGStateLimit is removed.

Implemented features:

  • AffineTransform struct that helps you easily apply transforms like rotation, scaling and translation to a document's coordinate system.
  • Concatenating the transformation matrix of a page + convenience methods for translation, scaling and rotation.
  • Getting the current transformation matrix of a page.
  • Added conformance to Hashable for many types.
  • Improved debug descriptions for Color and the geometric types.

0.2.0 - Jun 25, 2017

Finally, the second version of SwiftyHaru is released!

Plenty of new features were implemented, fixed building when using SPM. Please note that this version requires Swift 3.1.

If you use CocoaPods, you'll be happy to know that we don't use CLibHaru and CLibPNG as separate pods that SwiftyHaru depends on anymore, but rather they are included in the same pod. It makes managing dependencies a bit simpler.

You can refer to the FEATURES.md file if you want to see the exact functionality of LibHaru that is present in SwiftyHaru 0.2.0.

Breaking changes:

  • Changed the signature of the DrawingContext.fill(_:evenOddRule:stroke:) and DrawingContext.clip(to:evenOddRule:_:) methods. Instead of Bool value for fill rule they now require the Path.FillRule enum value.

Closed issues:

  • Implement high-level grid drawing #6
  • Package has unsupported layout for linux #7

Implemented features:

  • Loading TrueType fonts from a .ttc collection
  • Getting a bounding box of a specified text put at a specified position
  • Getting the ascent of a font
  • Getting the descent of a font
  • Getting the x-height of a font
  • Getting the cap height of a font
  • Setting metadata (author, creator, title, subject, keywords, creation date, modification date)
  • Setting a password, encryption mode and permissions
  • Setting a compression mode
  • Getting the depth of the graphics state stack
  • Closure-based syntax for saving and restoring the graphics state
  • Showing a text in a provided rectangle
  • High-level customizable interface for drawing grids!


  • Setting miterLimit, font and fontSize of DrawingContext, width and height of PDFPage to an invalid value now causes precondition failure.
  • Many more.

0.1.0 - Nov 2, 2016

The first release is here!


This release includes some basic functionality implemented around LibHaru. For details see FEATURES.md.

Closed issues:

  • Add CocoaPods support #4

Implemented features:

  • Creating PDF documents
  • Saving a document's contents into binary Data
  • Appending and inserting pages to documents
  • Setting a page's layout
  • Adding labels to pages
  • Loading TrueType fonts from file
  • Setting a page's size
  • Rotating a page
  • Measuring a width of a specified text
  • Path construction
  • Path painting
  • Setting a font
  • Setting a font size
  • Setting a line width
  • Setting a line cap
  • Setting a line join
  • Setting a miter limit
  • Setting a dash style
  • Setting a text leading
  • Setting a stroke and fill color and color space
  • Putting a text on a page