mirror of
https://github.com/foliojs/pdfkit.git
synced 2025-12-08 20:15:54 +00:00
Merge branch 'master' of github.com:devongovett/pdfkit into fontkit
Conflicts: lib/font/table.coffee lib/font/tables/cmap.coffee lib/font/tables/glyf.coffee lib/font/tables/head.coffee lib/font/tables/hhea.coffee lib/font/tables/hmtx.coffee lib/font/tables/loca.coffee lib/font/tables/maxp.coffee lib/font/tables/name.coffee lib/font/tables/os2.coffee lib/font/tables/post.coffee
This commit is contained in:
commit
6b2bea9835
2
LICENSE
2
LICENSE
@ -1,5 +1,5 @@
|
||||
MIT LICENSE
|
||||
Copyright (c) 2011 Devon Govett
|
||||
Copyright (c) 2014 Devon Govett
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
|
||||
A JavaScript PDF generation library for Node and the browser.
|
||||
|
||||
[](https://gratipay.com/devongovett)
|
||||
|
||||
## Description
|
||||
|
||||
PDFKit is a PDF document generation library for Node and the browser that makes creating complex, multi-page, printable documents easy.
|
||||
@ -158,4 +160,4 @@ For complete API documentation and more examples, see the [PDFKit website](http:
|
||||
|
||||
## License
|
||||
|
||||
PDFKit is available under the MIT license.
|
||||
PDFKit is available under the MIT license.
|
||||
|
||||
@ -117,6 +117,48 @@ For example:
|
||||
bottom: 50
|
||||
left: 72
|
||||
right: 72
|
||||
|
||||
## Switching to previous pages
|
||||
|
||||
PDFKit normally flushes pages to the output file immediately when a new page is created, making
|
||||
it impossible to jump back and add content to previous pages. This is normally not an issue, but
|
||||
in some circumstances it can be useful to add content to pages after the whole document, or a part
|
||||
of the document, has been created already. Examples include adding page numbers, or filling in other
|
||||
parts of information you don't have until the rest of the document has been created.
|
||||
|
||||
PDFKit has a `bufferPages` option in versions v0.7.0 and later that allows you to control when
|
||||
pages are flushed to the output file yourself rather than letting PDFKit handle that for you. To use
|
||||
it, just pass `bufferPages: true` as an option to the `PDFDocument` constructor. Then, you can call
|
||||
`doc.switchToPage(pageNumber)` to switch to a previous page (page numbers start at 0).
|
||||
|
||||
When you're ready to flush the buffered pages to the output file, call `flushPages`.
|
||||
This method is automatically called by `doc.end()`, so if you just want to buffer all pages in the document, you
|
||||
never need to call it. Finally, there is a `bufferedPageRange` method, which returns the range
|
||||
of pages that are currently buffered. Here is a small example that shows how you might add page
|
||||
numbers to a document.
|
||||
|
||||
# create a document, and enable bufferPages mode
|
||||
doc = new PDFDocument
|
||||
bufferPages: true
|
||||
|
||||
# add some content...
|
||||
doc.addPage()
|
||||
# ...
|
||||
doc.addPage()
|
||||
|
||||
# see the range of buffered pages
|
||||
range = doc.bufferedPageRange() # => { start: 0, count: 2 }
|
||||
|
||||
for i in [range.start...range.start + range.count]
|
||||
doc.switchToPage(i)
|
||||
doc.text "Page #{i + 1} of #{range.count}"
|
||||
|
||||
# manually flush pages that have been buffered
|
||||
doc.flushPages()
|
||||
|
||||
# or, if you are at the end of the document anyway,
|
||||
# doc.end() will call it for you automatically.
|
||||
doc.end()
|
||||
|
||||
## Setting document metadata
|
||||
|
||||
|
||||
1994
docs/guide.pdf
1994
docs/guide.pdf
File diff suppressed because it is too large
Load Diff
@ -19,11 +19,11 @@ class Data
|
||||
@writeByte if val then 1 else 0
|
||||
|
||||
readUInt32: ->
|
||||
b1 = @readByte() << 24
|
||||
b1 = @readByte() * 0x1000000
|
||||
b2 = @readByte() << 16
|
||||
b3 = @readByte() << 8
|
||||
b4 = @readByte()
|
||||
b1 | b2 | b3 | b4
|
||||
b1 + b2 + b3 + b4
|
||||
|
||||
writeUInt32: (val) ->
|
||||
@writeByte (val >>> 24) & 0xff
|
||||
@ -137,4 +137,4 @@ class Data
|
||||
for byte in bytes
|
||||
@writeByte byte
|
||||
|
||||
module.exports = Data
|
||||
module.exports = Data
|
||||
|
||||
@ -19,6 +19,9 @@ class PDFDocument extends stream.Readable
|
||||
# Whether streams should be compressed
|
||||
@compress = @options.compress ? yes
|
||||
|
||||
@_pageBuffer = []
|
||||
@_pageBufferStart = 0
|
||||
|
||||
# The PDF object store
|
||||
@_offsets = []
|
||||
@_waiting = 0
|
||||
@ -76,11 +79,12 @@ class PDFDocument extends stream.Readable
|
||||
|
||||
addPage: (options = @options) ->
|
||||
# end the current page if needed
|
||||
@page?.end()
|
||||
|
||||
@flushPages() unless @options.bufferPages
|
||||
|
||||
# create a page object
|
||||
@page = new PDFPage(this, options)
|
||||
|
||||
@_pageBuffer.push(@page)
|
||||
|
||||
# add the page to the object store
|
||||
pages = @_root.data.Pages.data
|
||||
pages.Kids.push @page.dictionary
|
||||
@ -96,7 +100,27 @@ class PDFDocument extends stream.Readable
|
||||
@transform 1, 0, 0, -1, 0, @page.height
|
||||
|
||||
return this
|
||||
|
||||
|
||||
bufferedPageRange: ->
|
||||
return { start: @_pageBufferStart, count: @_pageBuffer.length }
|
||||
|
||||
switchToPage: (n) ->
|
||||
unless page = @_pageBuffer[n - @_pageBufferStart]
|
||||
throw new Error "switchToPage(#{n}) out of bounds, current buffer covers pages #{@_pageBufferStart} to #{@_pageBufferStart + @_pageBuffer.length - 1}"
|
||||
|
||||
@page = page
|
||||
|
||||
flushPages: ->
|
||||
# this local variable exists so we're future-proof against
|
||||
# reentrant calls to flushPages.
|
||||
pages = @_pageBuffer
|
||||
@_pageBuffer = []
|
||||
@_pageBufferStart += pages.length
|
||||
for page in pages
|
||||
page.end()
|
||||
|
||||
return
|
||||
|
||||
ref: (data) ->
|
||||
ref = new PDFReference(this, @_offsets.length + 1, data)
|
||||
@_offsets.push null # placeholder for this object's offset once it is finalized
|
||||
@ -144,8 +168,7 @@ class PDFDocument extends stream.Readable
|
||||
'
|
||||
|
||||
end: ->
|
||||
@page.end()
|
||||
|
||||
@flushPages()
|
||||
@_info = @ref()
|
||||
for key, val of @info
|
||||
if typeof val is 'string'
|
||||
|
||||
@ -14,8 +14,8 @@ class AFMFont
|
||||
@charWidths = (@glyphWidths[characters[i]] for i in [0..255])
|
||||
|
||||
@bbox = (+e for e in @attributes['FontBBox'].split /\s+/)
|
||||
@ascender = +@attributes['Ascender']
|
||||
@decender = +@attributes['Descender']
|
||||
@ascender = +(@attributes['Ascender'] or 0)
|
||||
@decender = +(@attributes['Descender'] or 0)
|
||||
@lineGap = (@bbox[3] - @bbox[1]) - (@ascender - @decender)
|
||||
|
||||
parse: ->
|
||||
|
||||
@ -4,16 +4,18 @@ LineBreaker = require 'linebreak'
|
||||
class LineWrapper extends EventEmitter
|
||||
constructor: (@document, options) ->
|
||||
@indent = options.indent or 0
|
||||
@charSpacing = options.characterSpacing or 0
|
||||
@characterSpacing = options.characterSpacing or 0
|
||||
@wordSpacing = options.wordSpacing is 0
|
||||
@columns = options.columns or 1
|
||||
@columnGap = options.columnGap ? 18 # 1/4 inch
|
||||
@lineWidth = (options.width - (@columnGap * (@columns - 1))) / @columns
|
||||
@spaceLeft = @lineWidth
|
||||
@startX = @document.x
|
||||
@startY = @document.y
|
||||
@column = 1
|
||||
@ellipsis = options.ellipsis
|
||||
@continuedX = 0
|
||||
@features = options.features
|
||||
|
||||
# calculate the maximum Y position the text can appear at
|
||||
if options.height?
|
||||
@ -34,6 +36,8 @@ class LineWrapper extends EventEmitter
|
||||
@once 'line', =>
|
||||
@document.x -= indent
|
||||
@lineWidth += indent
|
||||
if options.continued and not @continuedX
|
||||
@continuedX = @indent
|
||||
@continuedX = 0 unless options.continued
|
||||
|
||||
# handle left aligning last lines of paragraphs
|
||||
@ -48,7 +52,7 @@ class LineWrapper extends EventEmitter
|
||||
@lastLine = false
|
||||
|
||||
wordWidth: (word) ->
|
||||
return @document.widthOfString(word, this) + @charSpacing + @wordSpacing
|
||||
return @document.widthOfString(word, this) + @characterSpacing + @wordSpacing
|
||||
|
||||
eachWord: (text, fn) ->
|
||||
# setup a unicode line breaker
|
||||
@ -62,7 +66,7 @@ class LineWrapper extends EventEmitter
|
||||
|
||||
# if the word is longer than the whole line, chop it up
|
||||
# TODO: break by grapheme clusters, not JS string characters
|
||||
if w > @lineWidth
|
||||
if w > @lineWidth + @continuedX
|
||||
# make some fake break objects
|
||||
lbk = last
|
||||
fbk = {}
|
||||
@ -95,7 +99,7 @@ class LineWrapper extends EventEmitter
|
||||
wrap: (text, options) ->
|
||||
# override options from previous continued fragments
|
||||
@indent = options.indent if options.indent?
|
||||
@charSpacing = options.characterSpacing if options.characterSpacing?
|
||||
@characterSpacing = options.characterSpacing if options.characterSpacing?
|
||||
@wordSpacing = options.wordSpacing if options.wordSpacing?
|
||||
@ellipsis = options.ellipsis if options.ellipsis?
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@ module.exports =
|
||||
|
||||
note: (x, y, w, h, contents, options = {}) ->
|
||||
options.Subtype = 'Text'
|
||||
options.Contents = PDFObject.s contents
|
||||
options.Contents = PDFObject.s contents, true
|
||||
options.Name = 'Comment'
|
||||
options.color ?= [243, 223, 92]
|
||||
@annotate x, y, w, h, options
|
||||
@ -73,7 +73,7 @@ module.exports =
|
||||
|
||||
textAnnotation: (x, y, w, h, text, options = {}) ->
|
||||
options.Subtype = 'FreeText'
|
||||
options.Contents = PDFObject.s text
|
||||
options.Contents = PDFObject.s text, true
|
||||
options.DA = PDFObject.s ''
|
||||
@annotate x, y, w, h, options
|
||||
|
||||
|
||||
@ -117,7 +117,6 @@ module.exports =
|
||||
|
||||
wrapper.wrap items.join('\n'), options
|
||||
|
||||
@x -= indent
|
||||
return this
|
||||
|
||||
_initOptions: (x = {}, y, options = {}) ->
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
"document",
|
||||
"vector"
|
||||
],
|
||||
"version": "0.6.3",
|
||||
"version": "0.7.0",
|
||||
"homepage": "http://pdfkit.org/",
|
||||
"author": {
|
||||
"name": "Devon Govett",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user