Merge pull request #572 from alafr/numbers

Pdf corruption with small numbers
This commit is contained in:
Devon Govett 2016-12-10 11:29:35 -08:00 committed by GitHub
commit e1a4f490b3
4 changed files with 30 additions and 30 deletions

View File

@ -129,7 +129,12 @@ class PDFDocument extends stream.Readable
@_offsets.push null # placeholder for this object's offset once it is finalized
@_waiting++
return ref
number: (n) ->
if n > -1e21 and n < 1e21
return Math.round(n * 1e6) / 1e6
throw new Error "unsupported number: #{n}"
_read: ->
# do nothing, but this method is required by node

View File

@ -223,17 +223,17 @@ module.exports =
@addContent "BT"
# text position
@addContent "1 0 0 1 #{x} #{y} Tm"
@addContent "1 0 0 1 #{@number(x)} #{@number(y)} Tm"
# font and font size
@addContent "/#{@_font.id} #{@_fontSize} Tf"
@addContent "/#{@_font.id} #{@number(@_fontSize)} Tf"
# rendering mode
mode = if options.fill and options.stroke then 2 else if options.stroke then 1 else 0
@addContent "#{mode} Tr" if mode
# Character spacing
@addContent "#{characterSpacing} Tc" if characterSpacing
@addContent "#{@number(characterSpacing)} Tc" if characterSpacing
# Add the actual text
# If we have a word spacing value, we need to encode each word separately
@ -266,7 +266,7 @@ module.exports =
if last < cur
hex = encoded.slice(last, cur).join ''
advance = positions[cur - 1].xAdvance - positions[cur - 1].advanceWidth
commands.push "<#{hex}> #{-advance}"
commands.push "<#{hex}> #{@number(-advance)}"
last = cur
@ -286,14 +286,14 @@ module.exports =
flush i
# Move the text position and flush just the current character
@addContent "1 0 0 1 #{x + pos.xOffset * scale} #{y + pos.yOffset * scale} Tm"
@addContent "1 0 0 1 #{@number(x + pos.xOffset * scale)} #{@number(y + pos.yOffset * scale)} Tm"
flush i + 1
hadOffset = yes
else
# If the last character had an offset, reset the text position
if hadOffset
@addContent "1 0 0 1 #{x} #{y} Tm"
@addContent "1 0 0 1 #{@number(x)} #{@number(y)} Tm"
hadOffset = no
# Group segments that don't have any advance adjustments

View File

@ -21,7 +21,7 @@ module.exports =
@addContent 'h'
lineWidth: (w) ->
@addContent "#{w} w"
@addContent "#{@number(w)} w"
_CAP_STYLES:
BUTT: 0
@ -42,36 +42,36 @@ module.exports =
@addContent "#{j} j"
miterLimit: (m) ->
@addContent "#{m} M"
@addContent "#{@number(m)} M"
dash: (length, options = {}) ->
return this unless length?
if Array.isArray length
length = length.join ' '
length = (@number(v) for v in length).join(' ')
phase = options.phase or 0
@addContent "[#{length}] #{phase} d"
@addContent "[#{length}] #{@number(phase)} d"
else
space = options.space ? length
phase = options.phase or 0
@addContent "[#{length} #{space}] #{phase} d"
@addContent "[#{@number(length)} #{@number(space)}] #{@number(phase)} d"
undash: ->
@addContent "[] 0 d"
moveTo: (x, y) ->
@addContent "#{x} #{y} m"
@addContent "#{@number(x)} #{@number(y)} m"
lineTo: (x, y) ->
@addContent "#{x} #{y} l"
@addContent "#{@number(x)} #{@number(y)} l"
bezierCurveTo: (cp1x, cp1y, cp2x, cp2y, x, y) ->
@addContent "#{cp1x} #{cp1y} #{cp2x} #{cp2y} #{x} #{y} c"
@addContent "#{@number(cp1x)} #{@number(cp1y)} #{@number(cp2x)} #{@number(cp2y)} #{@number(x)} #{@number(y)} c"
quadraticCurveTo: (cpx, cpy, x, y) ->
@addContent "#{cpx} #{cpy} #{x} #{y} v"
@addContent "#{@number(cpx)} #{@number(cpy)} #{@number(x)} #{@number(y)} v"
rect: (x, y, w, h) ->
@addContent "#{x} #{y} #{w} #{h} re"
@addContent "#{@number(x)} #{@number(y)} #{@number(w)} #{@number(h)} re"
roundedRect: (x, y, w, h, r = 0) ->
r = Math.min(r, 0.5 * w, 0.5 * h)
@ -168,7 +168,7 @@ module.exports =
m[4] = m0 * dx + m2 * dy + m4
m[5] = m1 * dx + m3 * dy + m5
values = (+v.toFixed(5) for v in [m11, m12, m21, m22, dx, dy]).join(' ')
values = (@number(v) for v in [m11, m12, m21, m22, dx, dy]).join(' ')
@addContent "#{values} cm"
translate: (x, y) ->

View File

@ -310,12 +310,12 @@ class SVGPath
th_half = 0.5 * (th1 - th0)
t = (8 / 3) * Math.sin(th_half * 0.5) * Math.sin(th_half * 0.5) / Math.sin(th_half)
x1 = fixRoundingError(cx + Math.cos(th0) - t * Math.sin(th0))
y1 = fixRoundingError(cy + Math.sin(th0) + t * Math.cos(th0))
x3 = fixRoundingError(cx + Math.cos(th1))
y3 = fixRoundingError(cy + Math.sin(th1))
x2 = fixRoundingError(x3 + t * Math.sin(th1))
y2 = fixRoundingError(y3 - t * Math.cos(th1))
x1 = cx + Math.cos(th0) - t * Math.sin(th0)
y1 = cy + Math.sin(th0) + t * Math.cos(th0)
x3 = cx + Math.cos(th1)
y3 = cy + Math.sin(th1)
x2 = x3 + t * Math.sin(th1)
y2 = y3 - t * Math.cos(th1)
return [
a00 * x1 + a01 * y1, a10 * x1 + a11 * y1,
@ -323,9 +323,4 @@ class SVGPath
a00 * x3 + a01 * y3, a10 * x3 + a11 * y3
]
fixRoundingError = (x) ->
if Math.abs(Math.round(x) - x) < 0.0000000000001
return Math.round(x);
return x
module.exports = SVGPath
module.exports = SVGPath