2015-10-18 09:30:28 +02:00
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/ * C o p y r i g h t 2 0 1 2 M o z i l l a F o u n d a t i o n
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
* /
// Initializing PDFJS global object (if still undefined)
if ( typeof PDFJS === 'undefined' ) {
( typeof window !== 'undefined' ? window : this ) . PDFJS = { } ;
}
PDFJS . version = '0.8.765' ;
PDFJS . build = '88ec2bd' ;
( function pdfjsWrapper ( ) {
// Use strict in our context only - users might not want it
'use strict' ;
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/ * C o p y r i g h t 2 0 1 2 M o z i l l a F o u n d a t i o n
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
* /
/* globals Cmd, ColorSpace, Dict, MozBlobBuilder, Name, PDFJS, Ref, URL */
'use strict' ;
var globalScope = ( typeof window === 'undefined' ) ? this : window ;
var isWorker = ( typeof window == 'undefined' ) ;
var ERRORS = 0 , WARNINGS = 1 , INFOS = 5 ;
var verbosity = WARNINGS ;
var FONT _IDENTITY _MATRIX = [ 0.001 , 0 , 0 , 0.001 , 0 , 0 ] ;
var TextRenderingMode = {
FILL : 0 ,
STROKE : 1 ,
FILL _STROKE : 2 ,
INVISIBLE : 3 ,
FILL _ADD _TO _PATH : 4 ,
STROKE _ADD _TO _PATH : 5 ,
FILL _STROKE _ADD _TO _PATH : 6 ,
ADD _TO _PATH : 7 ,
FILL _STROKE _MASK : 3 ,
ADD _TO _PATH _FLAG : 4
} ;
// The global PDFJS object exposes the API
// In production, it will be declared outside a global wrapper
// In development, it will be declared here
if ( ! globalScope . PDFJS ) {
globalScope . PDFJS = { } ;
}
globalScope . PDFJS . pdfBug = false ;
// All the possible operations for an operator list.
var OPS = PDFJS . OPS = {
// Intentionally start from 1 so it is easy to spot bad operators that will be
// 0's.
dependency : 1 ,
setLineWidth : 2 ,
setLineCap : 3 ,
setLineJoin : 4 ,
setMiterLimit : 5 ,
setDash : 6 ,
setRenderingIntent : 7 ,
setFlatness : 8 ,
setGState : 9 ,
save : 10 ,
restore : 11 ,
transform : 12 ,
moveTo : 13 ,
lineTo : 14 ,
curveTo : 15 ,
curveTo2 : 16 ,
curveTo3 : 17 ,
closePath : 18 ,
rectangle : 19 ,
stroke : 20 ,
closeStroke : 21 ,
fill : 22 ,
eoFill : 23 ,
fillStroke : 24 ,
eoFillStroke : 25 ,
closeFillStroke : 26 ,
closeEOFillStroke : 27 ,
endPath : 28 ,
clip : 29 ,
eoClip : 30 ,
beginText : 31 ,
endText : 32 ,
setCharSpacing : 33 ,
setWordSpacing : 34 ,
setHScale : 35 ,
setLeading : 36 ,
setFont : 37 ,
setTextRenderingMode : 38 ,
setTextRise : 39 ,
moveText : 40 ,
setLeadingMoveText : 41 ,
setTextMatrix : 42 ,
nextLine : 43 ,
showText : 44 ,
showSpacedText : 45 ,
nextLineShowText : 46 ,
nextLineSetSpacingShowText : 47 ,
setCharWidth : 48 ,
setCharWidthAndBounds : 49 ,
setStrokeColorSpace : 50 ,
setFillColorSpace : 51 ,
setStrokeColor : 52 ,
setStrokeColorN : 53 ,
setFillColor : 54 ,
setFillColorN : 55 ,
setStrokeGray : 56 ,
setFillGray : 57 ,
setStrokeRGBColor : 58 ,
setFillRGBColor : 59 ,
setStrokeCMYKColor : 60 ,
setFillCMYKColor : 61 ,
shadingFill : 62 ,
beginInlineImage : 63 ,
beginImageData : 64 ,
endInlineImage : 65 ,
paintXObject : 66 ,
markPoint : 67 ,
markPointProps : 68 ,
beginMarkedContent : 69 ,
beginMarkedContentProps : 70 ,
endMarkedContent : 71 ,
beginCompat : 72 ,
endCompat : 73 ,
paintFormXObjectBegin : 74 ,
paintFormXObjectEnd : 75 ,
beginGroup : 76 ,
endGroup : 77 ,
beginAnnotations : 78 ,
endAnnotations : 79 ,
beginAnnotation : 80 ,
endAnnotation : 81 ,
paintJpegXObject : 82 ,
paintImageMaskXObject : 83 ,
paintImageMaskXObjectGroup : 84 ,
paintImageXObject : 85 ,
paintInlineImageXObject : 86 ,
paintInlineImageXObjectGroup : 87
} ;
// Use only for debugging purposes. This should not be used in any code that is
// in mozilla master.
var log = ( function ( ) {
if ( 'console' in globalScope && 'log' in globalScope [ 'console' ] ) {
return globalScope [ 'console' ] [ 'log' ] . bind ( globalScope [ 'console' ] ) ;
} else {
return function nop ( ) {
} ;
}
} ) ( ) ;
// A notice for devs that will not trigger the fallback UI. These are good
// for things that are helpful to devs, such as warning that Workers were
// disabled, which is important to devs but not end users.
function info ( msg ) {
if ( verbosity >= INFOS ) {
log ( 'Info: ' + msg ) ;
PDFJS . LogManager . notify ( 'info' , msg ) ;
}
}
// Non-fatal warnings that should trigger the fallback UI.
function warn ( msg ) {
if ( verbosity >= WARNINGS ) {
log ( 'Warning: ' + msg ) ;
PDFJS . LogManager . notify ( 'warn' , msg ) ;
}
}
// Fatal errors that should trigger the fallback UI and halt execution by
// throwing an exception.
function error ( msg ) {
// If multiple arguments were passed, pass them all to the log function.
if ( arguments . length > 1 ) {
var logArguments = [ 'Error:' ] ;
logArguments . push . apply ( logArguments , arguments ) ;
log . apply ( null , logArguments ) ;
// Join the arguments into a single string for the lines below.
msg = [ ] . join . call ( arguments , ' ' ) ;
} else {
log ( 'Error: ' + msg ) ;
}
log ( backtrace ( ) ) ;
PDFJS . LogManager . notify ( 'error' , msg ) ;
throw new Error ( msg ) ;
}
// Missing features that should trigger the fallback UI.
function TODO ( what ) {
warn ( 'TODO: ' + what ) ;
}
function backtrace ( ) {
try {
throw new Error ( ) ;
} catch ( e ) {
return e . stack ? e . stack . split ( '\n' ) . slice ( 2 ) . join ( '\n' ) : '' ;
}
}
function assert ( cond , msg ) {
if ( ! cond )
error ( msg ) ;
}
// Combines two URLs. The baseUrl shall be absolute URL. If the url is an
// absolute URL, it will be returned as is.
function combineUrl ( baseUrl , url ) {
if ( ! url )
return baseUrl ;
if ( url . indexOf ( ':' ) >= 0 )
return url ;
if ( url . charAt ( 0 ) == '/' ) {
// absolute path
var i = baseUrl . indexOf ( '://' ) ;
i = baseUrl . indexOf ( '/' , i + 3 ) ;
return baseUrl . substring ( 0 , i ) + url ;
} else {
// relative path
var pathLength = baseUrl . length , i ;
i = baseUrl . lastIndexOf ( '#' ) ;
pathLength = i >= 0 ? i : pathLength ;
i = baseUrl . lastIndexOf ( '?' , pathLength ) ;
pathLength = i >= 0 ? i : pathLength ;
var prefixLength = baseUrl . lastIndexOf ( '/' , pathLength ) ;
return baseUrl . substring ( 0 , prefixLength + 1 ) + url ;
}
}
// Validates if URL is safe and allowed, e.g. to avoid XSS.
function isValidUrl ( url , allowRelative ) {
if ( ! url ) {
return false ;
}
var colon = url . indexOf ( ':' ) ;
if ( colon < 0 ) {
return allowRelative ;
}
var protocol = url . substr ( 0 , colon ) ;
switch ( protocol ) {
case 'http' :
case 'https' :
case 'ftp' :
case 'mailto' :
return true ;
default :
return false ;
}
}
PDFJS . isValidUrl = isValidUrl ;
// In a well-formed PDF, |cond| holds. If it doesn't, subsequent
// behavior is undefined.
function assertWellFormed ( cond , msg ) {
if ( ! cond )
error ( msg ) ;
}
var LogManager = PDFJS . LogManager = ( function LogManagerClosure ( ) {
var loggers = [ ] ;
return {
addLogger : function logManager _addLogger ( logger ) {
loggers . push ( logger ) ;
} ,
notify : function ( type , message ) {
for ( var i = 0 , ii = loggers . length ; i < ii ; i ++ ) {
var logger = loggers [ i ] ;
if ( logger [ type ] )
logger [ type ] ( message ) ;
}
}
} ;
} ) ( ) ;
function shadow ( obj , prop , value ) {
Object . defineProperty ( obj , prop , { value : value ,
enumerable : true ,
configurable : true ,
writable : false } ) ;
return value ;
}
var PasswordResponses = PDFJS . PasswordResponses = {
NEED _PASSWORD : 1 ,
INCORRECT _PASSWORD : 2
} ;
var PasswordException = ( function PasswordExceptionClosure ( ) {
function PasswordException ( msg , code ) {
this . name = 'PasswordException' ;
this . message = msg ;
this . code = code ;
}
PasswordException . prototype = new Error ( ) ;
PasswordException . constructor = PasswordException ;
return PasswordException ;
} ) ( ) ;
var UnknownErrorException = ( function UnknownErrorExceptionClosure ( ) {
function UnknownErrorException ( msg , details ) {
this . name = 'UnknownErrorException' ;
this . message = msg ;
this . details = details ;
}
UnknownErrorException . prototype = new Error ( ) ;
UnknownErrorException . constructor = UnknownErrorException ;
return UnknownErrorException ;
} ) ( ) ;
var InvalidPDFException = ( function InvalidPDFExceptionClosure ( ) {
function InvalidPDFException ( msg ) {
this . name = 'InvalidPDFException' ;
this . message = msg ;
}
InvalidPDFException . prototype = new Error ( ) ;
InvalidPDFException . constructor = InvalidPDFException ;
return InvalidPDFException ;
} ) ( ) ;
var MissingPDFException = ( function MissingPDFExceptionClosure ( ) {
function MissingPDFException ( msg ) {
this . name = 'MissingPDFException' ;
this . message = msg ;
}
MissingPDFException . prototype = new Error ( ) ;
MissingPDFException . constructor = MissingPDFException ;
return MissingPDFException ;
} ) ( ) ;
var NotImplementedException = ( function NotImplementedExceptionClosure ( ) {
function NotImplementedException ( msg ) {
this . message = msg ;
}
NotImplementedException . prototype = new Error ( ) ;
NotImplementedException . prototype . name = 'NotImplementedException' ;
NotImplementedException . constructor = NotImplementedException ;
return NotImplementedException ;
} ) ( ) ;
var MissingDataException = ( function MissingDataExceptionClosure ( ) {
function MissingDataException ( begin , end ) {
this . begin = begin ;
this . end = end ;
this . message = 'Missing data [' + begin + ', ' + end + ')' ;
}
MissingDataException . prototype = new Error ( ) ;
MissingDataException . prototype . name = 'MissingDataException' ;
MissingDataException . constructor = MissingDataException ;
return MissingDataException ;
} ) ( ) ;
var XRefParseException = ( function XRefParseExceptionClosure ( ) {
function XRefParseException ( msg ) {
this . message = msg ;
}
XRefParseException . prototype = new Error ( ) ;
XRefParseException . prototype . name = 'XRefParseException' ;
XRefParseException . constructor = XRefParseException ;
return XRefParseException ;
} ) ( ) ;
function bytesToString ( bytes ) {
var str = '' ;
var length = bytes . length ;
for ( var n = 0 ; n < length ; ++ n )
str += String . fromCharCode ( bytes [ n ] ) ;
return str ;
}
function stringToBytes ( str ) {
var length = str . length ;
var bytes = new Uint8Array ( length ) ;
for ( var n = 0 ; n < length ; ++ n )
bytes [ n ] = str . charCodeAt ( n ) & 0xFF ;
return bytes ;
}
var IDENTITY _MATRIX = [ 1 , 0 , 0 , 1 , 0 , 0 ] ;
var Util = PDFJS . Util = ( function UtilClosure ( ) {
function Util ( ) { }
Util . makeCssRgb = function Util _makeCssRgb ( rgb ) {
return 'rgb(' + rgb [ 0 ] + ',' + rgb [ 1 ] + ',' + rgb [ 2 ] + ')' ;
} ;
Util . makeCssCmyk = function Util _makeCssCmyk ( cmyk ) {
var rgb = ColorSpace . singletons . cmyk . getRgb ( cmyk , 0 ) ;
return Util . makeCssRgb ( rgb ) ;
} ;
// Concatenates two transformation matrices together and returns the result.
Util . transform = function Util _transform ( m1 , m2 ) {
return [
m1 [ 0 ] * m2 [ 0 ] + m1 [ 2 ] * m2 [ 1 ] ,
m1 [ 1 ] * m2 [ 0 ] + m1 [ 3 ] * m2 [ 1 ] ,
m1 [ 0 ] * m2 [ 2 ] + m1 [ 2 ] * m2 [ 3 ] ,
m1 [ 1 ] * m2 [ 2 ] + m1 [ 3 ] * m2 [ 3 ] ,
m1 [ 0 ] * m2 [ 4 ] + m1 [ 2 ] * m2 [ 5 ] + m1 [ 4 ] ,
m1 [ 1 ] * m2 [ 4 ] + m1 [ 3 ] * m2 [ 5 ] + m1 [ 5 ]
] ;
} ;
// For 2d affine transforms
Util . applyTransform = function Util _applyTransform ( p , m ) {
var xt = p [ 0 ] * m [ 0 ] + p [ 1 ] * m [ 2 ] + m [ 4 ] ;
var yt = p [ 0 ] * m [ 1 ] + p [ 1 ] * m [ 3 ] + m [ 5 ] ;
return [ xt , yt ] ;
} ;
Util . applyInverseTransform = function Util _applyInverseTransform ( p , m ) {
var d = m [ 0 ] * m [ 3 ] - m [ 1 ] * m [ 2 ] ;
var xt = ( p [ 0 ] * m [ 3 ] - p [ 1 ] * m [ 2 ] + m [ 2 ] * m [ 5 ] - m [ 4 ] * m [ 3 ] ) / d ;
var yt = ( - p [ 0 ] * m [ 1 ] + p [ 1 ] * m [ 0 ] + m [ 4 ] * m [ 1 ] - m [ 5 ] * m [ 0 ] ) / d ;
return [ xt , yt ] ;
} ;
// Applies the transform to the rectangle and finds the minimum axially
// aligned bounding box.
Util . getAxialAlignedBoundingBox =
function Util _getAxialAlignedBoundingBox ( r , m ) {
var p1 = Util . applyTransform ( r , m ) ;
var p2 = Util . applyTransform ( r . slice ( 2 , 4 ) , m ) ;
var p3 = Util . applyTransform ( [ r [ 0 ] , r [ 3 ] ] , m ) ;
var p4 = Util . applyTransform ( [ r [ 2 ] , r [ 1 ] ] , m ) ;
return [
Math . min ( p1 [ 0 ] , p2 [ 0 ] , p3 [ 0 ] , p4 [ 0 ] ) ,
Math . min ( p1 [ 1 ] , p2 [ 1 ] , p3 [ 1 ] , p4 [ 1 ] ) ,
Math . max ( p1 [ 0 ] , p2 [ 0 ] , p3 [ 0 ] , p4 [ 0 ] ) ,
Math . max ( p1 [ 1 ] , p2 [ 1 ] , p3 [ 1 ] , p4 [ 1 ] )
] ;
} ;
Util . inverseTransform = function Util _inverseTransform ( m ) {
var d = m [ 0 ] * m [ 3 ] - m [ 1 ] * m [ 2 ] ;
return [ m [ 3 ] / d , - m [ 1 ] / d , - m [ 2 ] / d , m [ 0 ] / d ,
( m [ 2 ] * m [ 5 ] - m [ 4 ] * m [ 3 ] ) / d , ( m [ 4 ] * m [ 1 ] - m [ 5 ] * m [ 0 ] ) / d ] ;
} ;
// Apply a generic 3d matrix M on a 3-vector v:
// | a b c | | X |
// | d e f | x | Y |
// | g h i | | Z |
// M is assumed to be serialized as [a,b,c,d,e,f,g,h,i],
// with v as [X,Y,Z]
Util . apply3dTransform = function Util _apply3dTransform ( m , v ) {
return [
m [ 0 ] * v [ 0 ] + m [ 1 ] * v [ 1 ] + m [ 2 ] * v [ 2 ] ,
m [ 3 ] * v [ 0 ] + m [ 4 ] * v [ 1 ] + m [ 5 ] * v [ 2 ] ,
m [ 6 ] * v [ 0 ] + m [ 7 ] * v [ 1 ] + m [ 8 ] * v [ 2 ]
] ;
} ;
// This calculation uses Singular Value Decomposition.
// The SVD can be represented with formula A = USV. We are interested in the
// matrix S here because it represents the scale values.
Util . singularValueDecompose2dScale =
function Util _singularValueDecompose2dScale ( m ) {
var transpose = [ m [ 0 ] , m [ 2 ] , m [ 1 ] , m [ 3 ] ] ;
// Multiply matrix m with its transpose.
var a = m [ 0 ] * transpose [ 0 ] + m [ 1 ] * transpose [ 2 ] ;
var b = m [ 0 ] * transpose [ 1 ] + m [ 1 ] * transpose [ 3 ] ;
var c = m [ 2 ] * transpose [ 0 ] + m [ 3 ] * transpose [ 2 ] ;
var d = m [ 2 ] * transpose [ 1 ] + m [ 3 ] * transpose [ 3 ] ;
// Solve the second degree polynomial to get roots.
var first = ( a + d ) / 2 ;
var second = Math . sqrt ( ( a + d ) * ( a + d ) - 4 * ( a * d - c * b ) ) / 2 ;
var sx = first + second || 1 ;
var sy = first - second || 1 ;
// Scale values are the square roots of the eigenvalues.
return [ Math . sqrt ( sx ) , Math . sqrt ( sy ) ] ;
} ;
// Normalize rectangle rect=[x1, y1, x2, y2] so that (x1,y1) < (x2,y2)
// For coordinate systems whose origin lies in the bottom-left, this
// means normalization to (BL,TR) ordering. For systems with origin in the
// top-left, this means (TL,BR) ordering.
Util . normalizeRect = function Util _normalizeRect ( rect ) {
var r = rect . slice ( 0 ) ; // clone rect
if ( rect [ 0 ] > rect [ 2 ] ) {
r [ 0 ] = rect [ 2 ] ;
r [ 2 ] = rect [ 0 ] ;
}
if ( rect [ 1 ] > rect [ 3 ] ) {
r [ 1 ] = rect [ 3 ] ;
r [ 3 ] = rect [ 1 ] ;
}
return r ;
} ;
// Returns a rectangle [x1, y1, x2, y2] corresponding to the
// intersection of rect1 and rect2. If no intersection, returns 'false'
// The rectangle coordinates of rect1, rect2 should be [x1, y1, x2, y2]
Util . intersect = function Util _intersect ( rect1 , rect2 ) {
function compare ( a , b ) {
return a - b ;
}
// Order points along the axes
var orderedX = [ rect1 [ 0 ] , rect1 [ 2 ] , rect2 [ 0 ] , rect2 [ 2 ] ] . sort ( compare ) ,
orderedY = [ rect1 [ 1 ] , rect1 [ 3 ] , rect2 [ 1 ] , rect2 [ 3 ] ] . sort ( compare ) ,
result = [ ] ;
rect1 = Util . normalizeRect ( rect1 ) ;
rect2 = Util . normalizeRect ( rect2 ) ;
// X: first and second points belong to different rectangles?
if ( ( orderedX [ 0 ] === rect1 [ 0 ] && orderedX [ 1 ] === rect2 [ 0 ] ) ||
( orderedX [ 0 ] === rect2 [ 0 ] && orderedX [ 1 ] === rect1 [ 0 ] ) ) {
// Intersection must be between second and third points
result [ 0 ] = orderedX [ 1 ] ;
result [ 2 ] = orderedX [ 2 ] ;
} else {
return false ;
}
// Y: first and second points belong to different rectangles?
if ( ( orderedY [ 0 ] === rect1 [ 1 ] && orderedY [ 1 ] === rect2 [ 1 ] ) ||
( orderedY [ 0 ] === rect2 [ 1 ] && orderedY [ 1 ] === rect1 [ 1 ] ) ) {
// Intersection must be between second and third points
result [ 1 ] = orderedY [ 1 ] ;
result [ 3 ] = orderedY [ 2 ] ;
} else {
return false ;
}
return result ;
} ;
Util . sign = function Util _sign ( num ) {
return num < 0 ? - 1 : 1 ;
} ;
// TODO(mack): Rename appendToArray
Util . concatenateToArray = function concatenateToArray ( arr1 , arr2 ) {
Array . prototype . push . apply ( arr1 , arr2 ) ;
} ;
Util . prependToArray = function concatenateToArray ( arr1 , arr2 ) {
Array . prototype . unshift . apply ( arr1 , arr2 ) ;
} ;
Util . extendObj = function extendObj ( obj1 , obj2 ) {
for ( var key in obj2 ) {
obj1 [ key ] = obj2 [ key ] ;
}
} ;
Util . getInheritableProperty = function Util _getInheritableProperty ( dict ,
name ) {
while ( dict && ! dict . has ( name ) ) {
dict = dict . get ( 'Parent' ) ;
}
if ( ! dict ) {
return null ;
}
return dict . get ( name ) ;
} ;
Util . inherit = function Util _inherit ( sub , base , prototype ) {
sub . prototype = Object . create ( base . prototype ) ;
sub . prototype . constructor = sub ;
for ( var prop in prototype ) {
sub . prototype [ prop ] = prototype [ prop ] ;
}
} ;
Util . loadScript = function Util _loadScript ( src , callback ) {
var script = document . createElement ( 'script' ) ;
var loaded = false ;
script . setAttribute ( 'src' , src ) ;
if ( callback ) {
script . onload = function ( ) {
if ( ! loaded ) {
callback ( ) ;
}
loaded = true ;
} ;
}
document . getElementsByTagName ( 'head' ) [ 0 ] . appendChild ( script ) ;
} ;
return Util ;
} ) ( ) ;
var PageViewport = PDFJS . PageViewport = ( function PageViewportClosure ( ) {
function PageViewport ( viewBox , scale , rotation , offsetX , offsetY , dontFlip ) {
this . viewBox = viewBox ;
this . scale = scale ;
this . rotation = rotation ;
this . offsetX = offsetX ;
this . offsetY = offsetY ;
// creating transform to convert pdf coordinate system to the normal
// canvas like coordinates taking in account scale and rotation
var centerX = ( viewBox [ 2 ] + viewBox [ 0 ] ) / 2 ;
var centerY = ( viewBox [ 3 ] + viewBox [ 1 ] ) / 2 ;
var rotateA , rotateB , rotateC , rotateD ;
rotation = rotation % 360 ;
rotation = rotation < 0 ? rotation + 360 : rotation ;
switch ( rotation ) {
case 180 :
rotateA = - 1 ; rotateB = 0 ; rotateC = 0 ; rotateD = 1 ;
break ;
case 90 :
rotateA = 0 ; rotateB = 1 ; rotateC = 1 ; rotateD = 0 ;
break ;
case 270 :
rotateA = 0 ; rotateB = - 1 ; rotateC = - 1 ; rotateD = 0 ;
break ;
//case 0:
default :
rotateA = 1 ; rotateB = 0 ; rotateC = 0 ; rotateD = - 1 ;
break ;
}
if ( dontFlip ) {
rotateC = - rotateC ; rotateD = - rotateD ;
}
var offsetCanvasX , offsetCanvasY ;
var width , height ;
if ( rotateA === 0 ) {
offsetCanvasX = Math . abs ( centerY - viewBox [ 1 ] ) * scale + offsetX ;
offsetCanvasY = Math . abs ( centerX - viewBox [ 0 ] ) * scale + offsetY ;
width = Math . abs ( viewBox [ 3 ] - viewBox [ 1 ] ) * scale ;
height = Math . abs ( viewBox [ 2 ] - viewBox [ 0 ] ) * scale ;
} else {
offsetCanvasX = Math . abs ( centerX - viewBox [ 0 ] ) * scale + offsetX ;
offsetCanvasY = Math . abs ( centerY - viewBox [ 1 ] ) * scale + offsetY ;
width = Math . abs ( viewBox [ 2 ] - viewBox [ 0 ] ) * scale ;
height = Math . abs ( viewBox [ 3 ] - viewBox [ 1 ] ) * scale ;
}
// creating transform for the following operations:
// translate(-centerX, -centerY), rotate and flip vertically,
// scale, and translate(offsetCanvasX, offsetCanvasY)
this . transform = [
rotateA * scale ,
rotateB * scale ,
rotateC * scale ,
rotateD * scale ,
offsetCanvasX - rotateA * scale * centerX - rotateC * scale * centerY ,
offsetCanvasY - rotateB * scale * centerX - rotateD * scale * centerY
] ;
this . width = width ;
this . height = height ;
this . fontScale = scale ;
}
PageViewport . prototype = {
clone : function PageViewPort _clone ( args ) {
args = args || { } ;
var scale = 'scale' in args ? args . scale : this . scale ;
var rotation = 'rotation' in args ? args . rotation : this . rotation ;
return new PageViewport ( this . viewBox . slice ( ) , scale , rotation ,
this . offsetX , this . offsetY , args . dontFlip ) ;
} ,
convertToViewportPoint : function PageViewport _convertToViewportPoint ( x , y ) {
return Util . applyTransform ( [ x , y ] , this . transform ) ;
} ,
convertToViewportRectangle :
function PageViewport _convertToViewportRectangle ( rect ) {
var tl = Util . applyTransform ( [ rect [ 0 ] , rect [ 1 ] ] , this . transform ) ;
var br = Util . applyTransform ( [ rect [ 2 ] , rect [ 3 ] ] , this . transform ) ;
return [ tl [ 0 ] , tl [ 1 ] , br [ 0 ] , br [ 1 ] ] ;
} ,
convertToPdfPoint : function PageViewport _convertToPdfPoint ( x , y ) {
return Util . applyInverseTransform ( [ x , y ] , this . transform ) ;
}
} ;
return PageViewport ;
} ) ( ) ;
var PDFStringTranslateTable = [
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0x2D8 , 0x2C7 , 0x2C6 , 0x2D9 , 0x2DD , 0x2DB , 0x2DA , 0x2DC , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x2022 , 0x2020 , 0x2021 , 0x2026 , 0x2014 ,
0x2013 , 0x192 , 0x2044 , 0x2039 , 0x203A , 0x2212 , 0x2030 , 0x201E , 0x201C ,
0x201D , 0x2018 , 0x2019 , 0x201A , 0x2122 , 0xFB01 , 0xFB02 , 0x141 , 0x152 , 0x160 ,
0x178 , 0x17D , 0x131 , 0x142 , 0x153 , 0x161 , 0x17E , 0 , 0x20AC
] ;
function stringToPDFString ( str ) {
var i , n = str . length , str2 = '' ;
if ( str [ 0 ] === '\xFE' && str [ 1 ] === '\xFF' ) {
// UTF16BE BOM
for ( i = 2 ; i < n ; i += 2 )
str2 += String . fromCharCode (
( str . charCodeAt ( i ) << 8 ) | str . charCodeAt ( i + 1 ) ) ;
} else {
for ( i = 0 ; i < n ; ++ i ) {
var code = PDFStringTranslateTable [ str . charCodeAt ( i ) ] ;
str2 += code ? String . fromCharCode ( code ) : str . charAt ( i ) ;
}
}
return str2 ;
}
function stringToUTF8String ( str ) {
return decodeURIComponent ( escape ( str ) ) ;
}
function isEmptyObj ( obj ) {
for ( var key in obj ) {
return false ;
}
return true ;
}
function isBool ( v ) {
return typeof v == 'boolean' ;
}
function isInt ( v ) {
return typeof v == 'number' && ( ( v | 0 ) == v ) ;
}
function isNum ( v ) {
return typeof v == 'number' ;
}
function isString ( v ) {
return typeof v == 'string' ;
}
function isNull ( v ) {
return v === null ;
}
function isName ( v ) {
return v instanceof Name ;
}
function isCmd ( v , cmd ) {
return v instanceof Cmd && ( ! cmd || v . cmd == cmd ) ;
}
function isDict ( v , type ) {
if ( ! ( v instanceof Dict ) ) {
return false ;
}
if ( ! type ) {
return true ;
}
var dictType = v . get ( 'Type' ) ;
return isName ( dictType ) && dictType . name == type ;
}
function isArray ( v ) {
return v instanceof Array ;
}
function isStream ( v ) {
return typeof v == 'object' && v !== null && v !== undefined &&
( 'getBytes' in v ) ;
}
function isArrayBuffer ( v ) {
return typeof v == 'object' && v !== null && v !== undefined &&
( 'byteLength' in v ) ;
}
function isRef ( v ) {
return v instanceof Ref ;
}
function isPDFFunction ( v ) {
var fnDict ;
if ( typeof v != 'object' )
return false ;
else if ( isDict ( v ) )
fnDict = v ;
else if ( isStream ( v ) )
fnDict = v . dict ;
else
return false ;
return fnDict . has ( 'FunctionType' ) ;
}
/ * *
* The following promise implementation tries to generally implment the
* Promise / A + spec . Some notable differences from other promise libaries are :
* - There currently isn ' t a seperate deferred and promise object .
* - Unhandled rejections eventually show an error if they aren ' t handled .
*
* Based off of the work in :
* https : //bugzilla.mozilla.org/show_bug.cgi?id=810490
* /
var Promise = PDFJS . Promise = ( function PromiseClosure ( ) {
var STATUS _PENDING = 0 ;
var STATUS _RESOLVED = 1 ;
var STATUS _REJECTED = 2 ;
// In an attempt to avoid silent exceptions, unhandled rejections are
// tracked and if they aren't handled in a certain amount of time an
// error is logged.
var REJECTION _TIMEOUT = 500 ;
var HandlerManager = {
handlers : [ ] ,
running : false ,
unhandledRejections : [ ] ,
pendingRejectionCheck : false ,
scheduleHandlers : function scheduleHandlers ( promise ) {
if ( promise . _status == STATUS _PENDING ) {
return ;
}
this . handlers = this . handlers . concat ( promise . _handlers ) ;
promise . _handlers = [ ] ;
if ( this . running ) {
return ;
}
this . running = true ;
setTimeout ( this . runHandlers . bind ( this ) , 0 ) ;
} ,
runHandlers : function runHandlers ( ) {
while ( this . handlers . length > 0 ) {
var handler = this . handlers . shift ( ) ;
var nextStatus = handler . thisPromise . _status ;
var nextValue = handler . thisPromise . _value ;
try {
if ( nextStatus === STATUS _RESOLVED ) {
if ( typeof ( handler . onResolve ) == 'function' ) {
nextValue = handler . onResolve ( nextValue ) ;
}
} else if ( typeof ( handler . onReject ) === 'function' ) {
nextValue = handler . onReject ( nextValue ) ;
nextStatus = STATUS _RESOLVED ;
if ( handler . thisPromise . _unhandledRejection ) {
this . removeUnhandeledRejection ( handler . thisPromise ) ;
}
}
} catch ( ex ) {
nextStatus = STATUS _REJECTED ;
nextValue = ex ;
}
handler . nextPromise . _updateStatus ( nextStatus , nextValue ) ;
}
this . running = false ;
} ,
addUnhandledRejection : function addUnhandledRejection ( promise ) {
this . unhandledRejections . push ( {
promise : promise ,
time : Date . now ( )
} ) ;
this . scheduleRejectionCheck ( ) ;
} ,
removeUnhandeledRejection : function removeUnhandeledRejection ( promise ) {
promise . _unhandledRejection = false ;
for ( var i = 0 ; i < this . unhandledRejections . length ; i ++ ) {
if ( this . unhandledRejections [ i ] . promise === promise ) {
this . unhandledRejections . splice ( i ) ;
i -- ;
}
}
} ,
scheduleRejectionCheck : function scheduleRejectionCheck ( ) {
if ( this . pendingRejectionCheck ) {
return ;
}
this . pendingRejectionCheck = true ;
setTimeout ( function rejectionCheck ( ) {
this . pendingRejectionCheck = false ;
var now = Date . now ( ) ;
for ( var i = 0 ; i < this . unhandledRejections . length ; i ++ ) {
if ( now - this . unhandledRejections [ i ] . time > REJECTION _TIMEOUT ) {
var unhandled = this . unhandledRejections [ i ] . promise . _value ;
var msg = 'Unhandled rejection: ' + unhandled ;
if ( unhandled . stack ) {
msg += '\n' + unhandled . stack ;
}
warn ( msg ) ;
this . unhandledRejections . splice ( i ) ;
i -- ;
}
}
if ( this . unhandledRejections . length ) {
this . scheduleRejectionCheck ( ) ;
}
} . bind ( this ) , REJECTION _TIMEOUT ) ;
}
} ;
function Promise ( ) {
this . _status = STATUS _PENDING ;
this . _handlers = [ ] ;
}
/ * *
* Builds a promise that is resolved when all the passed in promises are
* resolved .
* @ param { array } array of data and / or promises to wait for .
* @ return { Promise } New dependant promise .
* /
Promise . all = function Promise _all ( promises ) {
var deferred = new Promise ( ) ;
var unresolved = promises . length ;
var results = [ ] ;
if ( unresolved === 0 ) {
deferred . resolve ( results ) ;
return deferred ;
}
function reject ( reason ) {
if ( deferred . _status === STATUS _REJECTED ) {
return ;
}
results = [ ] ;
deferred . reject ( reason ) ;
}
for ( var i = 0 , ii = promises . length ; i < ii ; ++ i ) {
var promise = promises [ i ] ;
var resolve = ( function ( i ) {
return function ( value ) {
if ( deferred . _status === STATUS _REJECTED ) {
return ;
}
results [ i ] = value ;
unresolved -- ;
if ( unresolved === 0 )
deferred . resolve ( results ) ;
} ;
} ) ( i ) ;
if ( Promise . isPromise ( promise ) ) {
promise . then ( resolve , reject ) ;
} else {
resolve ( promise ) ;
}
}
return deferred ;
} ;
/ * *
* Checks if the value is likely a promise ( has a 'then' function ) .
* @ return { boolean } true if x is thenable
* /
Promise . isPromise = function Promise _isPromise ( value ) {
return value && typeof value . then === 'function' ;
} ;
Promise . prototype = {
_status : null ,
_value : null ,
_handlers : null ,
_unhandledRejection : null ,
_updateStatus : function Promise _ _updateStatus ( status , value ) {
if ( this . _status === STATUS _RESOLVED ||
this . _status === STATUS _REJECTED ) {
return ;
}
if ( status == STATUS _RESOLVED &&
Promise . isPromise ( value ) ) {
value . then ( this . _updateStatus . bind ( this , STATUS _RESOLVED ) ,
this . _updateStatus . bind ( this , STATUS _REJECTED ) ) ;
return ;
}
this . _status = status ;
this . _value = value ;
if ( status === STATUS _REJECTED && this . _handlers . length === 0 ) {
this . _unhandledRejection = true ;
HandlerManager . addUnhandledRejection ( this ) ;
}
HandlerManager . scheduleHandlers ( this ) ;
} ,
get isResolved ( ) {
return this . _status === STATUS _RESOLVED ;
} ,
get isRejected ( ) {
return this . _status === STATUS _REJECTED ;
} ,
resolve : function Promise _resolve ( value ) {
this . _updateStatus ( STATUS _RESOLVED , value ) ;
} ,
reject : function Promise _reject ( reason ) {
this . _updateStatus ( STATUS _REJECTED , reason ) ;
} ,
then : function Promise _then ( onResolve , onReject ) {
var nextPromise = new Promise ( ) ;
this . _handlers . push ( {
thisPromise : this ,
onResolve : onResolve ,
onReject : onReject ,
nextPromise : nextPromise
} ) ;
HandlerManager . scheduleHandlers ( this ) ;
return nextPromise ;
}
} ;
return Promise ;
} ) ( ) ;
var StatTimer = ( function StatTimerClosure ( ) {
function rpad ( str , pad , length ) {
while ( str . length < length )
str += pad ;
return str ;
}
function StatTimer ( ) {
this . started = { } ;
this . times = [ ] ;
this . enabled = true ;
}
StatTimer . prototype = {
time : function StatTimer _time ( name ) {
if ( ! this . enabled )
return ;
if ( name in this . started )
warn ( 'Timer is already running for ' + name ) ;
this . started [ name ] = Date . now ( ) ;
} ,
timeEnd : function StatTimer _timeEnd ( name ) {
if ( ! this . enabled )
return ;
if ( ! ( name in this . started ) )
warn ( 'Timer has not been started for ' + name ) ;
this . times . push ( {
'name' : name ,
'start' : this . started [ name ] ,
'end' : Date . now ( )
} ) ;
// Remove timer from started so it can be called again.
delete this . started [ name ] ;
} ,
toString : function StatTimer _toString ( ) {
var times = this . times ;
var out = '' ;
// Find the longest name for padding purposes.
var longest = 0 ;
for ( var i = 0 , ii = times . length ; i < ii ; ++ i ) {
var name = times [ i ] [ 'name' ] ;
if ( name . length > longest )
longest = name . length ;
}
for ( var i = 0 , ii = times . length ; i < ii ; ++ i ) {
var span = times [ i ] ;
var duration = span . end - span . start ;
out += rpad ( span [ 'name' ] , ' ' , longest ) + ' ' + duration + 'ms\n' ;
}
return out ;
}
} ;
return StatTimer ;
} ) ( ) ;
PDFJS . createBlob = function createBlob ( data , contentType ) {
if ( typeof Blob !== 'undefined' )
return new Blob ( [ data ] , { type : contentType } ) ;
// Blob builder is deprecated in FF14 and removed in FF18.
var bb = new MozBlobBuilder ( ) ;
bb . append ( data ) ;
return bb . getBlob ( contentType ) ;
} ;
PDFJS . createObjectURL = ( function createObjectURLClosure ( ) {
if ( typeof URL !== 'undefined' && URL . createObjectURL ) {
return function createObjectURL ( data , contentType ) {
var blob = PDFJS . createBlob ( data , contentType ) ;
return URL . createObjectURL ( blob ) ;
} ;
}
// Blob/createObjectURL is not available, falling back to data schema.
var digits =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' ;
return function createObjectURL ( data , contentType ) {
var buffer = 'data:' + contentType + ';base64,' ;
for ( var i = 0 , ii = data . length ; i < ii ; i += 3 ) {
var b1 = data [ i ] & 0xFF ;
var b2 = data [ i + 1 ] & 0xFF ;
var b3 = data [ i + 2 ] & 0xFF ;
var d1 = b1 >> 2 , d2 = ( ( b1 & 3 ) << 4 ) | ( b2 >> 4 ) ;
var d3 = i + 1 < ii ? ( ( b2 & 0xF ) << 2 ) | ( b3 >> 6 ) : 64 ;
var d4 = i + 2 < ii ? ( b3 & 0x3F ) : 64 ;
buffer += digits [ d1 ] + digits [ d2 ] + digits [ d3 ] + digits [ d4 ] ;
}
return buffer ;
} ;
} ) ( ) ;
function MessageHandler ( name , comObj ) {
this . name = name ;
this . comObj = comObj ;
this . callbackIndex = 1 ;
this . postMessageTransfers = true ;
var callbacks = this . callbacks = { } ;
var ah = this . actionHandler = { } ;
ah [ 'console_log' ] = [ function ahConsoleLog ( data ) {
log . apply ( null , data ) ;
} ] ;
// If there's no console available, console_error in the
// action handler will do nothing.
if ( 'console' in globalScope ) {
ah [ 'console_error' ] = [ function ahConsoleError ( data ) {
globalScope [ 'console' ] . error . apply ( null , data ) ;
} ] ;
} else {
ah [ 'console_error' ] = [ function ahConsoleError ( data ) {
log . apply ( null , data ) ;
} ] ;
}
ah [ '_warn' ] = [ function ah _Warn ( data ) {
warn ( data ) ;
} ] ;
comObj . onmessage = function messageHandlerComObjOnMessage ( event ) {
var data = event . data ;
if ( data . isReply ) {
var callbackId = data . callbackId ;
if ( data . callbackId in callbacks ) {
var callback = callbacks [ callbackId ] ;
delete callbacks [ callbackId ] ;
callback ( data . data ) ;
} else {
error ( 'Cannot resolve callback ' + callbackId ) ;
}
} else if ( data . action in ah ) {
var action = ah [ data . action ] ;
if ( data . callbackId ) {
var promise = new Promise ( ) ;
promise . then ( function ( resolvedData ) {
comObj . postMessage ( {
isReply : true ,
callbackId : data . callbackId ,
data : resolvedData
} ) ;
} ) ;
action [ 0 ] . call ( action [ 1 ] , data . data , promise ) ;
} else {
action [ 0 ] . call ( action [ 1 ] , data . data ) ;
}
} else {
error ( 'Unkown action from worker: ' + data . action ) ;
}
} ;
}
MessageHandler . prototype = {
on : function messageHandlerOn ( actionName , handler , scope ) {
var ah = this . actionHandler ;
if ( ah [ actionName ] ) {
error ( 'There is already an actionName called "' + actionName + '"' ) ;
}
ah [ actionName ] = [ handler , scope ] ;
} ,
/ * *
* Sends a message to the comObj to invoke the action with the supplied data .
* @ param { String } actionName Action to call .
* @ param { JSON } data JSON data to send .
* @ param { function } [ callback ] Optional callback that will handle a reply .
* @ param { Array } [ transfers ] Optional list of transfers / ArrayBuffers
* /
send : function messageHandlerSend ( actionName , data , callback , transfers ) {
var message = {
action : actionName ,
data : data
} ;
if ( callback ) {
var callbackId = this . callbackIndex ++ ;
this . callbacks [ callbackId ] = callback ;
message . callbackId = callbackId ;
}
if ( transfers && this . postMessageTransfers ) {
this . comObj . postMessage ( message , transfers ) ;
} else {
this . comObj . postMessage ( message ) ;
}
}
} ;
function loadJpegStream ( id , imageUrl , objs ) {
var img = new Image ( ) ;
img . onload = ( function loadJpegStream _onloadClosure ( ) {
objs . resolve ( id , img ) ;
} ) ;
img . src = imageUrl ;
}
var ColorSpace = ( function ColorSpaceClosure ( ) {
// Constructor should define this.numComps, this.defaultColor, this.name
function ColorSpace ( ) {
error ( 'should not call ColorSpace constructor' ) ;
}
ColorSpace . prototype = {
/ * *
* Converts the color value to the RGB color . The color components are
* located in the src array starting from the srcOffset . Returns the array
* of the rgb components , each value ranging from [ 0 , 255 ] .
* /
getRgb : function ColorSpace _getRgb ( src , srcOffset ) {
error ( 'Should not call ColorSpace.getRgb' ) ;
} ,
/ * *
* Converts the color value to the RGB color , similar to the getRgb method .
* The result placed into the dest array starting from the destOffset .
* /
getRgbItem : function ColorSpace _getRgb ( src , srcOffset , dest , destOffset ) {
error ( 'Should not call ColorSpace.getRgbItem' ) ;
} ,
/ * *
* Converts the specified number of the color values to the RGB colors .
* The colors are located in the src array starting from the srcOffset .
* The result is placed into the dest array starting from the destOffset .
* The src array items shall be in [ 0 , 2 ^ bits ) range , the dest array items
* will be in [ 0 , 255 ] range .
* /
getRgbBuffer : function ColorSpace _getRgbBuffer ( src , srcOffset , count ,
dest , destOffset , bits ) {
error ( 'Should not call ColorSpace.getRgbBuffer' ) ;
} ,
/ * *
* Determines amount of the bytes is required to store the reslut of the
* conversion that done by the getRgbBuffer method .
* /
getOutputLength : function ColorSpace _getOutputLength ( inputLength ) {
error ( 'Should not call ColorSpace.getOutputLength' ) ;
} ,
/ * *
* Returns true if source data will be equal the result / output data .
* /
isPassthrough : function ColorSpace _isPassthrough ( bits ) {
return false ;
} ,
/ * *
* Creates the output buffer and converts the specified number of the color
* values to the RGB colors , similar to the getRgbBuffer .
* /
createRgbBuffer : function ColorSpace _createRgbBuffer ( src , srcOffset ,
count , bits ) {
if ( this . isPassthrough ( bits ) ) {
return src . subarray ( srcOffset ) ;
}
var dest = new Uint8Array ( count * 3 ) ;
var numComponentColors = 1 << bits ;
// Optimization: create a color map when there is just one component and
// we are converting more colors than the size of the color map. We
// don't build the map if the colorspace is gray or rgb since those
// methods are faster than building a map. This mainly offers big speed
// ups for indexed and alternate colorspaces.
if ( this . numComps === 1 && count > numComponentColors &&
this . name !== 'DeviceGray' && this . name !== 'DeviceRGB' ) {
// TODO it may be worth while to cache the color map. While running
// testing I never hit a cache so I will leave that out for now (perhaps
// we are reparsing colorspaces too much?).
var allColors = bits <= 8 ? new Uint8Array ( numComponentColors ) :
new Uint16Array ( numComponentColors ) ;
for ( var i = 0 ; i < numComponentColors ; i ++ ) {
allColors [ i ] = i ;
}
var colorMap = new Uint8Array ( numComponentColors * 3 ) ;
this . getRgbBuffer ( allColors , 0 , numComponentColors , colorMap , 0 , bits ) ;
var destOffset = 0 ;
for ( var i = 0 ; i < count ; ++ i ) {
var key = src [ srcOffset ++ ] * 3 ;
dest [ destOffset ++ ] = colorMap [ key ] ;
dest [ destOffset ++ ] = colorMap [ key + 1 ] ;
dest [ destOffset ++ ] = colorMap [ key + 2 ] ;
}
return dest ;
}
this . getRgbBuffer ( src , srcOffset , count , dest , 0 , bits ) ;
return dest ;
} ,
/ * *
* True if the colorspace has components in the default range of [ 0 , 1 ] .
* This should be true for all colorspaces except for lab color spaces
* which are [ 0 , 100 ] , [ - 128 , 127 ] , [ - 128 , 127 ] .
* /
usesZeroToOneRange : true
} ;
ColorSpace . parse = function ColorSpace _parse ( cs , xref , res ) {
var IR = ColorSpace . parseToIR ( cs , xref , res ) ;
if ( IR instanceof AlternateCS )
return IR ;
return ColorSpace . fromIR ( IR ) ;
} ;
ColorSpace . fromIR = function ColorSpace _fromIR ( IR ) {
var name = isArray ( IR ) ? IR [ 0 ] : IR ;
switch ( name ) {
case 'DeviceGrayCS' :
return this . singletons . gray ;
case 'DeviceRgbCS' :
return this . singletons . rgb ;
case 'DeviceCmykCS' :
return this . singletons . cmyk ;
case 'CalGrayCS' :
var whitePoint = IR [ 1 ] . WhitePoint ;
var blackPoint = IR [ 1 ] . BlackPoint ;
var gamma = IR [ 1 ] . Gamma ;
return new CalGrayCS ( whitePoint , blackPoint , gamma ) ;
case 'PatternCS' :
var basePatternCS = IR [ 1 ] ;
if ( basePatternCS )
basePatternCS = ColorSpace . fromIR ( basePatternCS ) ;
return new PatternCS ( basePatternCS ) ;
case 'IndexedCS' :
var baseIndexedCS = IR [ 1 ] ;
var hiVal = IR [ 2 ] ;
var lookup = IR [ 3 ] ;
return new IndexedCS ( ColorSpace . fromIR ( baseIndexedCS ) , hiVal , lookup ) ;
case 'AlternateCS' :
var numComps = IR [ 1 ] ;
var alt = IR [ 2 ] ;
var tintFnIR = IR [ 3 ] ;
return new AlternateCS ( numComps , ColorSpace . fromIR ( alt ) ,
PDFFunction . fromIR ( tintFnIR ) ) ;
case 'LabCS' :
var whitePoint = IR [ 1 ] . WhitePoint ;
var blackPoint = IR [ 1 ] . BlackPoint ;
var range = IR [ 1 ] . Range ;
return new LabCS ( whitePoint , blackPoint , range ) ;
default :
error ( 'Unkown name ' + name ) ;
}
return null ;
} ;
ColorSpace . parseToIR = function ColorSpace _parseToIR ( cs , xref , res ) {
if ( isName ( cs ) ) {
var colorSpaces = res . get ( 'ColorSpace' ) ;
if ( isDict ( colorSpaces ) ) {
var refcs = colorSpaces . get ( cs . name ) ;
if ( refcs )
cs = refcs ;
}
}
cs = xref . fetchIfRef ( cs ) ;
var mode ;
if ( isName ( cs ) ) {
mode = cs . name ;
this . mode = mode ;
switch ( mode ) {
case 'DeviceGray' :
case 'G' :
return 'DeviceGrayCS' ;
case 'DeviceRGB' :
case 'RGB' :
return 'DeviceRgbCS' ;
case 'DeviceCMYK' :
case 'CMYK' :
return 'DeviceCmykCS' ;
case 'Pattern' :
return [ 'PatternCS' , null ] ;
default :
error ( 'unrecognized colorspace ' + mode ) ;
}
} else if ( isArray ( cs ) ) {
mode = cs [ 0 ] . name ;
this . mode = mode ;
switch ( mode ) {
case 'DeviceGray' :
case 'G' :
return 'DeviceGrayCS' ;
case 'DeviceRGB' :
case 'RGB' :
return 'DeviceRgbCS' ;
case 'DeviceCMYK' :
case 'CMYK' :
return 'DeviceCmykCS' ;
case 'CalGray' :
var params = cs [ 1 ] . getAll ( ) ;
return [ 'CalGrayCS' , params ] ;
case 'CalRGB' :
return 'DeviceRgbCS' ;
case 'ICCBased' :
var stream = xref . fetchIfRef ( cs [ 1 ] ) ;
var dict = stream . dict ;
var numComps = dict . get ( 'N' ) ;
if ( numComps == 1 )
return 'DeviceGrayCS' ;
if ( numComps == 3 )
return 'DeviceRgbCS' ;
if ( numComps == 4 )
return 'DeviceCmykCS' ;
break ;
case 'Pattern' :
var basePatternCS = cs [ 1 ] ;
if ( basePatternCS )
basePatternCS = ColorSpace . parseToIR ( basePatternCS , xref , res ) ;
return [ 'PatternCS' , basePatternCS ] ;
case 'Indexed' :
case 'I' :
var baseIndexedCS = ColorSpace . parseToIR ( cs [ 1 ] , xref , res ) ;
var hiVal = cs [ 2 ] + 1 ;
var lookup = xref . fetchIfRef ( cs [ 3 ] ) ;
if ( isStream ( lookup ) ) {
lookup = lookup . getBytes ( ) ;
}
return [ 'IndexedCS' , baseIndexedCS , hiVal , lookup ] ;
case 'Separation' :
case 'DeviceN' :
var name = cs [ 1 ] ;
var numComps = 1 ;
if ( isName ( name ) )
numComps = 1 ;
else if ( isArray ( name ) )
numComps = name . length ;
var alt = ColorSpace . parseToIR ( cs [ 2 ] , xref , res ) ;
var tintFnIR = PDFFunction . getIR ( xref , xref . fetchIfRef ( cs [ 3 ] ) ) ;
return [ 'AlternateCS' , numComps , alt , tintFnIR ] ;
case 'Lab' :
var params = cs [ 1 ] . getAll ( ) ;
return [ 'LabCS' , params ] ;
default :
error ( 'unimplemented color space object "' + mode + '"' ) ;
}
} else {
error ( 'unrecognized color space object: "' + cs + '"' ) ;
}
return null ;
} ;
/ * *
* Checks if a decode map matches the default decode map for a color space .
* This handles the general decode maps where there are two values per
* component . e . g . [ 0 , 1 , 0 , 1 , 0 , 1 ] for a RGB color .
* This does not handle Lab , Indexed , or Pattern decode maps since they are
* slightly different .
* @ param { Array } decode Decode map ( usually from an image ) .
* @ param { Number } n Number of components the color space has .
* /
ColorSpace . isDefaultDecode = function ColorSpace _isDefaultDecode ( decode , n ) {
if ( ! decode )
return true ;
if ( n * 2 !== decode . length ) {
warn ( 'The decode map is not the correct length' ) ;
return true ;
}
for ( var i = 0 , ii = decode . length ; i < ii ; i += 2 ) {
if ( decode [ i ] !== 0 || decode [ i + 1 ] != 1 )
return false ;
}
return true ;
} ;
ColorSpace . singletons = {
get gray ( ) {
return shadow ( this , 'gray' , new DeviceGrayCS ( ) ) ;
} ,
get rgb ( ) {
return shadow ( this , 'rgb' , new DeviceRgbCS ( ) ) ;
} ,
get cmyk ( ) {
return shadow ( this , 'cmyk' , new DeviceCmykCS ( ) ) ;
}
} ;
return ColorSpace ;
} ) ( ) ;
/ * *
* Alternate color space handles both Separation and DeviceN color spaces . A
* Separation color space is actually just a DeviceN with one color component .
* Both color spaces use a tinting function to convert colors to a base color
* space .
* /
var AlternateCS = ( function AlternateCSClosure ( ) {
function AlternateCS ( numComps , base , tintFn ) {
this . name = 'Alternate' ;
this . numComps = numComps ;
this . defaultColor = new Float32Array ( numComps ) ;
for ( var i = 0 ; i < numComps ; ++ i ) {
this . defaultColor [ i ] = 1 ;
}
this . base = base ;
this . tintFn = tintFn ;
}
AlternateCS . prototype = {
getRgb : function AlternateCS _getRgb ( src , srcOffset ) {
var rgb = new Uint8Array ( 3 ) ;
this . getRgbItem ( src , srcOffset , rgb , 0 ) ;
return rgb ;
} ,
getRgbItem : function AlternateCS _getRgbItem ( src , srcOffset ,
dest , destOffset ) {
var baseNumComps = this . base . numComps ;
var input = 'subarray' in src ?
src . subarray ( srcOffset , srcOffset + this . numComps ) :
Array . prototype . slice . call ( src , srcOffset , srcOffset + this . numComps ) ;
var tinted = this . tintFn ( input ) ;
this . base . getRgbItem ( tinted , 0 , dest , destOffset ) ;
} ,
getRgbBuffer : function AlternateCS _getRgbBuffer ( src , srcOffset , count ,
dest , destOffset , bits ) {
var tintFn = this . tintFn ;
var base = this . base ;
var scale = 1 / ( ( 1 << bits ) - 1 ) ;
var baseNumComps = base . numComps ;
var usesZeroToOneRange = base . usesZeroToOneRange ;
var isPassthrough = base . isPassthrough ( 8 ) || ! usesZeroToOneRange ;
var pos = isPassthrough ? destOffset : 0 ;
var baseBuf = isPassthrough ? dest : new Uint8Array ( baseNumComps * count ) ;
var numComps = this . numComps ;
var scaled = new Float32Array ( numComps ) ;
for ( var i = 0 ; i < count ; i ++ ) {
for ( var j = 0 ; j < numComps ; j ++ ) {
scaled [ j ] = src [ srcOffset ++ ] * scale ;
}
var tinted = tintFn ( scaled ) ;
if ( usesZeroToOneRange ) {
for ( var j = 0 ; j < baseNumComps ; j ++ ) {
baseBuf [ pos ++ ] = tinted [ j ] * 255 ;
}
} else {
base . getRgbItem ( tinted , 0 , baseBuf , pos ) ;
pos += baseNumComps ;
}
}
if ( ! isPassthrough ) {
base . getRgbBuffer ( baseBuf , 0 , count , dest , destOffset , 8 ) ;
}
} ,
getOutputLength : function AlternateCS _getOutputLength ( inputLength ) {
return this . base . getOutputLength ( inputLength *
this . base . numComps / this . numComps ) ;
} ,
isPassthrough : ColorSpace . prototype . isPassthrough ,
createRgbBuffer : ColorSpace . prototype . createRgbBuffer ,
isDefaultDecode : function AlternateCS _isDefaultDecode ( decodeMap ) {
return ColorSpace . isDefaultDecode ( decodeMap , this . numComps ) ;
} ,
usesZeroToOneRange : true
} ;
return AlternateCS ;
} ) ( ) ;
var PatternCS = ( function PatternCSClosure ( ) {
function PatternCS ( baseCS ) {
this . name = 'Pattern' ;
this . base = baseCS ;
}
PatternCS . prototype = { } ;
return PatternCS ;
} ) ( ) ;
var IndexedCS = ( function IndexedCSClosure ( ) {
function IndexedCS ( base , highVal , lookup ) {
this . name = 'Indexed' ;
this . numComps = 1 ;
this . defaultColor = new Uint8Array ( [ 0 ] ) ;
this . base = base ;
this . highVal = highVal ;
var baseNumComps = base . numComps ;
var length = baseNumComps * highVal ;
var lookupArray ;
if ( isStream ( lookup ) ) {
lookupArray = new Uint8Array ( length ) ;
var bytes = lookup . getBytes ( length ) ;
lookupArray . set ( bytes ) ;
} else if ( isString ( lookup ) ) {
lookupArray = new Uint8Array ( length ) ;
for ( var i = 0 ; i < length ; ++ i )
lookupArray [ i ] = lookup . charCodeAt ( i ) ;
} else if ( lookup instanceof Uint8Array || lookup instanceof Array ) {
lookupArray = lookup ;
} else {
error ( 'Unrecognized lookup table: ' + lookup ) ;
}
this . lookup = lookupArray ;
}
IndexedCS . prototype = {
getRgb : function IndexedCS _getRgb ( src , srcOffset ) {
var numComps = this . base . numComps ;
var start = src [ srcOffset ] * numComps ;
return this . base . getRgb ( this . lookup , start ) ;
} ,
getRgbItem : function IndexedCS _getRgbItem ( src , srcOffset ,
dest , destOffset ) {
var numComps = this . base . numComps ;
var start = src [ srcOffset ] * numComps ;
this . base . getRgbItem ( this . lookup , start , dest , destOffset ) ;
} ,
getRgbBuffer : function IndexedCS _getRgbBuffer ( src , srcOffset , count ,
dest , destOffset ) {
var base = this . base ;
var numComps = base . numComps ;
var outputDelta = base . getOutputLength ( numComps ) ;
var lookup = this . lookup ;
for ( var i = 0 ; i < count ; ++ i ) {
var lookupPos = src [ srcOffset ++ ] * numComps ;
base . getRgbBuffer ( lookup , lookupPos , 1 , dest , destOffset , 8 ) ;
destOffset += outputDelta ;
}
} ,
getOutputLength : function IndexedCS _getOutputLength ( inputLength ) {
return this . base . getOutputLength ( inputLength * this . base . numComps ) ;
} ,
isPassthrough : ColorSpace . prototype . isPassthrough ,
createRgbBuffer : ColorSpace . prototype . createRgbBuffer ,
isDefaultDecode : function IndexedCS _isDefaultDecode ( decodeMap ) {
// indexed color maps shouldn't be changed
return true ;
} ,
usesZeroToOneRange : true
} ;
return IndexedCS ;
} ) ( ) ;
var DeviceGrayCS = ( function DeviceGrayCSClosure ( ) {
function DeviceGrayCS ( ) {
this . name = 'DeviceGray' ;
this . numComps = 1 ;
this . defaultColor = new Float32Array ( [ 0 ] ) ;
}
DeviceGrayCS . prototype = {
getRgb : function DeviceGrayCS _getRgb ( src , srcOffset ) {
var rgb = new Uint8Array ( 3 ) ;
this . getRgbItem ( src , srcOffset , rgb , 0 ) ;
return rgb ;
} ,
getRgbItem : function DeviceGrayCS _getRgbItem ( src , srcOffset ,
dest , destOffset ) {
var c = ( src [ srcOffset ] * 255 ) | 0 ;
c = c < 0 ? 0 : c > 255 ? 255 : c ;
dest [ destOffset ] = dest [ destOffset + 1 ] = dest [ destOffset + 2 ] = c ;
} ,
getRgbBuffer : function DeviceGrayCS _getRgbBuffer ( src , srcOffset , count ,
dest , destOffset , bits ) {
var scale = 255 / ( ( 1 << bits ) - 1 ) ;
var j = srcOffset , q = destOffset ;
for ( var i = 0 ; i < count ; ++ i ) {
var c = ( scale * src [ j ++ ] ) | 0 ;
dest [ q ++ ] = c ;
dest [ q ++ ] = c ;
dest [ q ++ ] = c ;
}
} ,
getOutputLength : function DeviceGrayCS _getOutputLength ( inputLength ) {
return inputLength * 3 ;
} ,
isPassthrough : ColorSpace . prototype . isPassthrough ,
createRgbBuffer : ColorSpace . prototype . createRgbBuffer ,
isDefaultDecode : function DeviceGrayCS _isDefaultDecode ( decodeMap ) {
return ColorSpace . isDefaultDecode ( decodeMap , this . numComps ) ;
} ,
usesZeroToOneRange : true
} ;
return DeviceGrayCS ;
} ) ( ) ;
var DeviceRgbCS = ( function DeviceRgbCSClosure ( ) {
function DeviceRgbCS ( ) {
this . name = 'DeviceRGB' ;
this . numComps = 3 ;
this . defaultColor = new Float32Array ( [ 0 , 0 , 0 ] ) ;
}
DeviceRgbCS . prototype = {
getRgb : function DeviceRgbCS _getRgb ( src , srcOffset ) {
var rgb = new Uint8Array ( 3 ) ;
this . getRgbItem ( src , srcOffset , rgb , 0 ) ;
return rgb ;
} ,
getRgbItem : function DeviceRgbCS _getRgbItem ( src , srcOffset ,
dest , destOffset ) {
var r = ( src [ srcOffset ] * 255 ) | 0 ;
var g = ( src [ srcOffset + 1 ] * 255 ) | 0 ;
var b = ( src [ srcOffset + 2 ] * 255 ) | 0 ;
dest [ destOffset ] = r < 0 ? 0 : r > 255 ? 255 : r ;
dest [ destOffset + 1 ] = g < 0 ? 0 : g > 255 ? 255 : g ;
dest [ destOffset + 2 ] = b < 0 ? 0 : b > 255 ? 255 : b ;
} ,
getRgbBuffer : function DeviceRgbCS _getRgbBuffer ( src , srcOffset , count ,
dest , destOffset , bits ) {
var length = count * 3 ;
if ( bits == 8 ) {
dest . set ( src . subarray ( srcOffset , srcOffset + length ) , destOffset ) ;
return ;
}
var scale = 255 / ( ( 1 << bits ) - 1 ) ;
var j = srcOffset , q = destOffset ;
for ( var i = 0 ; i < length ; ++ i ) {
dest [ q ++ ] = ( scale * src [ j ++ ] ) | 0 ;
}
} ,
getOutputLength : function DeviceRgbCS _getOutputLength ( inputLength ) {
return inputLength ;
} ,
isPassthrough : function DeviceRgbCS _isPassthrough ( bits ) {
return bits == 8 ;
} ,
createRgbBuffer : ColorSpace . prototype . createRgbBuffer ,
isDefaultDecode : function DeviceRgbCS _isDefaultDecode ( decodeMap ) {
return ColorSpace . isDefaultDecode ( decodeMap , this . numComps ) ;
} ,
usesZeroToOneRange : true
} ;
return DeviceRgbCS ;
} ) ( ) ;
var DeviceCmykCS = ( function DeviceCmykCSClosure ( ) {
// The coefficients below was found using numerical analysis: the method of
// steepest descent for the sum((f_i - color_value_i)^2) for r/g/b colors,
// where color_value is the tabular value from the table of sampled RGB colors
// from CMYK US Web Coated (SWOP) colorspace, and f_i is the corresponding
// CMYK color conversion using the estimation below:
// f(A, B,.. N) = Acc+Bcm+Ccy+Dck+c+Fmm+Gmy+Hmk+Im+Jyy+Kyk+Ly+Mkk+Nk+255
function convertToRgb ( src , srcOffset , srcScale , dest , destOffset ) {
var c = src [ srcOffset + 0 ] * srcScale ;
var m = src [ srcOffset + 1 ] * srcScale ;
var y = src [ srcOffset + 2 ] * srcScale ;
var k = src [ srcOffset + 3 ] * srcScale ;
var r =
c * ( - 4.387332384609988 * c + 54.48615194189176 * m +
18.82290502165302 * y + 212.25662451639585 * k +
- 285.2331026137004 ) +
m * ( 1.7149763477362134 * m - 5.6096736904047315 * y +
- 17.873870861415444 * k - 5.497006427196366 ) +
y * ( - 2.5217340131683033 * y - 21.248923337353073 * k +
17.5119270841813 ) +
k * ( - 21.86122147463605 * k - 189.48180835922747 ) + 255 ;
var g =
c * ( 8.841041422036149 * c + 60.118027045597366 * m +
6.871425592049007 * y + 31.159100130055922 * k +
- 79.2970844816548 ) +
m * ( - 15.310361306967817 * m + 17.575251261109482 * y +
131.35250912493976 * k - 190.9453302588951 ) +
y * ( 4.444339102852739 * y + 9.8632861493405 * k - 24.86741582555878 ) +
k * ( - 20.737325471181034 * k - 187.80453709719578 ) + 255 ;
var b =
c * ( 0.8842522430003296 * c + 8.078677503112928 * m +
30.89978309703729 * y - 0.23883238689178934 * k +
- 14.183576799673286 ) +
m * ( 10.49593273432072 * m + 63.02378494754052 * y +
50.606957656360734 * k - 112.23884253719248 ) +
y * ( 0.03296041114873217 * y + 115.60384449646641 * k +
- 193.58209356861505 ) +
k * ( - 22.33816807309886 * k - 180.12613974708367 ) + 255 ;
dest [ destOffset ] = r > 255 ? 255 : r < 0 ? 0 : r ;
dest [ destOffset + 1 ] = g > 255 ? 255 : g < 0 ? 0 : g ;
dest [ destOffset + 2 ] = b > 255 ? 255 : b < 0 ? 0 : b ;
}
function DeviceCmykCS ( ) {
this . name = 'DeviceCMYK' ;
this . numComps = 4 ;
this . defaultColor = new Float32Array ( [ 0 , 0 , 0 , 1 ] ) ;
}
DeviceCmykCS . prototype = {
getRgb : function DeviceCmykCS _getRgb ( src , srcOffset ) {
var rgb = new Uint8Array ( 3 ) ;
convertToRgb ( src , srcOffset , 1 , rgb , 0 ) ;
return rgb ;
} ,
getRgbItem : function DeviceCmykCS _getRgbItem ( src , srcOffset ,
dest , destOffset ) {
convertToRgb ( src , srcOffset , 1 , dest , destOffset ) ;
} ,
getRgbBuffer : function DeviceCmykCS _getRgbBuffer ( src , srcOffset , count ,
dest , destOffset , bits ) {
var scale = 1 / ( ( 1 << bits ) - 1 ) ;
for ( var i = 0 ; i < count ; i ++ ) {
convertToRgb ( src , srcOffset , scale , dest , destOffset ) ;
srcOffset += 4 ;
destOffset += 3 ;
}
} ,
getOutputLength : function DeviceCmykCS _getOutputLength ( inputLength ) {
return ( inputLength >> 2 ) * 3 ;
} ,
isPassthrough : ColorSpace . prototype . isPassthrough ,
createRgbBuffer : ColorSpace . prototype . createRgbBuffer ,
isDefaultDecode : function DeviceCmykCS _isDefaultDecode ( decodeMap ) {
return ColorSpace . isDefaultDecode ( decodeMap , this . numComps ) ;
} ,
usesZeroToOneRange : true
} ;
return DeviceCmykCS ;
} ) ( ) ;
//
// CalGrayCS: Based on "PDF Reference, Sixth Ed", p.245
//
var CalGrayCS = ( function CalGrayCSClosure ( ) {
function CalGrayCS ( whitePoint , blackPoint , gamma ) {
this . name = 'CalGray' ;
this . numComps = 3 ;
this . defaultColor = new Float32Array ( [ 0 , 0 , 0 ] ) ;
if ( ! whitePoint ) {
error ( 'WhitePoint missing - required for color space CalGray' ) ;
}
blackPoint = blackPoint || [ 0 , 0 , 0 ] ;
gamma = gamma || 1 ;
// Translate arguments to spec variables.
this . XW = whitePoint [ 0 ] ;
this . YW = whitePoint [ 1 ] ;
this . ZW = whitePoint [ 2 ] ;
this . XB = blackPoint [ 0 ] ;
this . YB = blackPoint [ 1 ] ;
this . ZB = blackPoint [ 2 ] ;
this . G = gamma ;
// Validate variables as per spec.
if ( this . XW < 0 || this . ZW < 0 || this . YW !== 1 ) {
error ( 'Invalid WhitePoint components for ' + this . name +
', no fallback available' ) ;
}
if ( this . XB < 0 || this . YB < 0 || this . ZB < 0 ) {
info ( 'Invalid BlackPoint for ' + this . name + ', falling back to default' ) ;
this . XB = this . YB = this . ZB = 0 ;
}
if ( this . XB !== 0 || this . YB !== 0 || this . ZB !== 0 ) {
TODO ( this . name + ', BlackPoint: XB: ' + this . XB + ', YB: ' + this . YB +
', ZB: ' + this . ZB + ', only default values are supported.' ) ;
}
if ( this . G < 1 ) {
info ( 'Invalid Gamma: ' + this . G + ' for ' + this . name +
', falling back to default' ) ;
this . G = 1 ;
}
}
CalGrayCS . prototype = {
getRgb : function CalGrayCS _getRgb ( src , srcOffset ) {
var rgb = new Uint8Array ( 3 ) ;
this . getRgbItem ( src , srcOffset , rgb , 0 ) ;
return rgb ;
} ,
getRgbItem : function CalGrayCS _getRgbItem ( src , srcOffset ,
dest , destOffset ) {
// A represents a gray component of a calibrated gray space.
// A <---> AG in the spec
var A = src [ srcOffset ] ;
var AG = Math . pow ( A , this . G ) ;
// Computes intermediate variables M, L, N as per spec.
// Except if other than default BlackPoint values are used.
var M = this . XW * AG ;
var L = this . YW * AG ;
var N = this . ZW * AG ;
// Decode XYZ, as per spec.
var X = M ;
var Y = L ;
var Z = N ;
// http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html, Ch 4.
// This yields values in range [0, 100].
var Lstar = Math . max ( 116 * Math . pow ( Y , 1 / 3 ) - 16 , 0 ) ;
// Convert values to rgb range [0, 255].
dest [ destOffset ] = Lstar * 255 / 100 ;
dest [ destOffset + 1 ] = Lstar * 255 / 100 ;
dest [ destOffset + 2 ] = Lstar * 255 / 100 ;
} ,
getRgbBuffer : function CalGrayCS _getRgbBuffer ( src , srcOffset , count ,
dest , destOffset , bits ) {
// TODO: This part is copied from DeviceGray. Make this utility function.
var scale = 255 / ( ( 1 << bits ) - 1 ) ;
var j = srcOffset , q = destOffset ;
for ( var i = 0 ; i < count ; ++ i ) {
var c = ( scale * src [ j ++ ] ) | 0 ;
dest [ q ++ ] = c ;
dest [ q ++ ] = c ;
dest [ q ++ ] = c ;
}
} ,
getOutputLength : function CalGrayCS _getOutputLength ( inputLength ) {
return inputLength * 3 ;
} ,
isPassthrough : ColorSpace . prototype . isPassthrough ,
createRgbBuffer : ColorSpace . prototype . createRgbBuffer ,
isDefaultDecode : function CalGrayCS _isDefaultDecode ( decodeMap ) {
return ColorSpace . isDefaultDecode ( decodeMap , this . numComps ) ;
} ,
usesZeroToOneRange : true
} ;
return CalGrayCS ;
} ) ( ) ;
//
// LabCS: Based on "PDF Reference, Sixth Ed", p.250
//
var LabCS = ( function LabCSClosure ( ) {
function LabCS ( whitePoint , blackPoint , range ) {
this . name = 'Lab' ;
this . numComps = 3 ;
this . defaultColor = new Float32Array ( [ 0 , 0 , 0 ] ) ;
if ( ! whitePoint )
error ( 'WhitePoint missing - required for color space Lab' ) ;
blackPoint = blackPoint || [ 0 , 0 , 0 ] ;
range = range || [ - 100 , 100 , - 100 , 100 ] ;
// Translate args to spec variables
this . XW = whitePoint [ 0 ] ;
this . YW = whitePoint [ 1 ] ;
this . ZW = whitePoint [ 2 ] ;
this . amin = range [ 0 ] ;
this . amax = range [ 1 ] ;
this . bmin = range [ 2 ] ;
this . bmax = range [ 3 ] ;
// These are here just for completeness - the spec doesn't offer any
// formulas that use BlackPoint in Lab
this . XB = blackPoint [ 0 ] ;
this . YB = blackPoint [ 1 ] ;
this . ZB = blackPoint [ 2 ] ;
// Validate vars as per spec
if ( this . XW < 0 || this . ZW < 0 || this . YW !== 1 )
error ( 'Invalid WhitePoint components, no fallback available' ) ;
if ( this . XB < 0 || this . YB < 0 || this . ZB < 0 ) {
info ( 'Invalid BlackPoint, falling back to default' ) ;
this . XB = this . YB = this . ZB = 0 ;
}
if ( this . amin > this . amax || this . bmin > this . bmax ) {
info ( 'Invalid Range, falling back to defaults' ) ;
this . amin = - 100 ;
this . amax = 100 ;
this . bmin = - 100 ;
this . bmax = 100 ;
}
}
// Function g(x) from spec
function fn _g ( x ) {
if ( x >= 6 / 29 )
return x * x * x ;
else
return ( 108 / 841 ) * ( x - 4 / 29 ) ;
}
function decode ( value , high1 , low2 , high2 ) {
return low2 + ( value ) * ( high2 - low2 ) / ( high1 ) ;
}
// If decoding is needed maxVal should be 2^bits per component - 1.
function convertToRgb ( cs , src , srcOffset , maxVal , dest , destOffset ) {
// XXX: Lab input is in the range of [0, 100], [amin, amax], [bmin, bmax]
// not the usual [0, 1]. If a command like setFillColor is used the src
// values will already be within the correct range. However, if we are
// converting an image we have to map the values to the correct range given
// above.
// Ls,as,bs <---> L*,a*,b* in the spec
var Ls = src [ srcOffset ] ;
var as = src [ srcOffset + 1 ] ;
var bs = src [ srcOffset + 2 ] ;
if ( maxVal !== false ) {
Ls = decode ( Ls , maxVal , 0 , 100 ) ;
as = decode ( as , maxVal , cs . amin , cs . amax ) ;
bs = decode ( bs , maxVal , cs . bmin , cs . bmax ) ;
}
// Adjust limits of 'as' and 'bs'
as = as > cs . amax ? cs . amax : as < cs . amin ? cs . amin : as ;
bs = bs > cs . bmax ? cs . bmax : bs < cs . bmin ? cs . bmin : bs ;
// Computes intermediate variables X,Y,Z as per spec
var M = ( Ls + 16 ) / 116 ;
var L = M + ( as / 500 ) ;
var N = M - ( bs / 200 ) ;
var X = cs . XW * fn _g ( L ) ;
var Y = cs . YW * fn _g ( M ) ;
var Z = cs . ZW * fn _g ( N ) ;
var r , g , b ;
// Using different conversions for D50 and D65 white points,
// per http://www.color.org/srgb.pdf
if ( cs . ZW < 1 ) {
// Assuming D50 (X=0.9642, Y=1.00, Z=0.8249)
r = X * 3.1339 + Y * - 1.6170 + Z * - 0.4906 ;
g = X * - 0.9785 + Y * 1.9160 + Z * 0.0333 ;
b = X * 0.0720 + Y * - 0.2290 + Z * 1.4057 ;
} else {
// Assuming D65 (X=0.9505, Y=1.00, Z=1.0888)
r = X * 3.2406 + Y * - 1.5372 + Z * - 0.4986 ;
g = X * - 0.9689 + Y * 1.8758 + Z * 0.0415 ;
b = X * 0.0557 + Y * - 0.2040 + Z * 1.0570 ;
}
// clamp color values to [0,1] range then convert to [0,255] range.
dest [ destOffset ] = Math . sqrt ( r < 0 ? 0 : r > 1 ? 1 : r ) * 255 ;
dest [ destOffset + 1 ] = Math . sqrt ( g < 0 ? 0 : g > 1 ? 1 : g ) * 255 ;
dest [ destOffset + 2 ] = Math . sqrt ( b < 0 ? 0 : b > 1 ? 1 : b ) * 255 ;
}
LabCS . prototype = {
getRgb : function LabCS _getRgb ( src , srcOffset ) {
var rgb = new Uint8Array ( 3 ) ;
convertToRgb ( this , src , srcOffset , false , rgb , 0 ) ;
return rgb ;
} ,
getRgbItem : function LabCS _getRgbItem ( src , srcOffset , dest , destOffset ) {
convertToRgb ( this , src , srcOffset , false , dest , destOffset ) ;
} ,
getRgbBuffer : function LabCS _getRgbBuffer ( src , srcOffset , count ,
dest , destOffset , bits ) {
var maxVal = ( 1 << bits ) - 1 ;
for ( var i = 0 ; i < count ; i ++ ) {
convertToRgb ( this , src , srcOffset , maxVal , dest , destOffset ) ;
srcOffset += 3 ;
destOffset += 3 ;
}
} ,
getOutputLength : function LabCS _getOutputLength ( inputLength ) {
return inputLength ;
} ,
isPassthrough : ColorSpace . prototype . isPassthrough ,
isDefaultDecode : function LabCS _isDefaultDecode ( decodeMap ) {
// XXX: Decoding is handled with the lab conversion because of the strange
// ranges that are used.
return true ;
} ,
usesZeroToOneRange : false
} ;
return LabCS ;
} ) ( ) ;
var PatternType = {
AXIAL : 2 ,
RADIAL : 3
} ;
var Pattern = ( function PatternClosure ( ) {
// Constructor should define this.getPattern
function Pattern ( ) {
error ( 'should not call Pattern constructor' ) ;
}
Pattern . prototype = {
// Input: current Canvas context
// Output: the appropriate fillStyle or strokeStyle
getPattern : function Pattern _getPattern ( ctx ) {
error ( 'Should not call Pattern.getStyle: ' + ctx ) ;
}
} ;
Pattern . shadingFromIR = function Pattern _shadingFromIR ( raw ) {
return Shadings [ raw [ 0 ] ] . fromIR ( raw ) ;
} ;
Pattern . parseShading = function Pattern _parseShading ( shading , matrix , xref ,
res ) {
var dict = isStream ( shading ) ? shading . dict : shading ;
var type = dict . get ( 'ShadingType' ) ;
switch ( type ) {
case PatternType . AXIAL :
case PatternType . RADIAL :
// Both radial and axial shadings are handled by RadialAxial shading.
return new Shadings . RadialAxial ( dict , matrix , xref , res ) ;
default :
TODO ( 'Unsupported shading type: ' + type ) ;
return new Shadings . Dummy ( ) ;
}
} ;
return Pattern ;
} ) ( ) ;
var Shadings = { } ;
// A small number to offset the first/last color stops so we can insert ones to
// support extend. Number.MIN_VALUE appears to be too small and breaks the
// extend. 1e-7 works in FF but chrome seems to use an even smaller sized number
// internally so we have to go bigger.
Shadings . SMALL _NUMBER = 1e-2 ;
// Radial and axial shading have very similar implementations
// If needed, the implementations can be broken into two classes
Shadings . RadialAxial = ( function RadialAxialClosure ( ) {
function RadialAxial ( dict , matrix , xref , res , ctx ) {
this . matrix = matrix ;
this . coordsArr = dict . get ( 'Coords' ) ;
this . shadingType = dict . get ( 'ShadingType' ) ;
this . type = 'Pattern' ;
this . ctx = ctx ;
var cs = dict . get ( 'ColorSpace' , 'CS' ) ;
cs = ColorSpace . parse ( cs , xref , res ) ;
this . cs = cs ;
var t0 = 0.0 , t1 = 1.0 ;
if ( dict . has ( 'Domain' ) ) {
var domainArr = dict . get ( 'Domain' ) ;
t0 = domainArr [ 0 ] ;
t1 = domainArr [ 1 ] ;
}
var extendStart = false , extendEnd = false ;
if ( dict . has ( 'Extend' ) ) {
var extendArr = dict . get ( 'Extend' ) ;
extendStart = extendArr [ 0 ] ;
extendEnd = extendArr [ 1 ] ;
}
if ( this . shadingType === PatternType . RADIAL &&
( ! extendStart || ! extendEnd ) ) {
// Radial gradient only currently works if either circle is fully within
// the other circle.
var x1 = this . coordsArr [ 0 ] ;
var y1 = this . coordsArr [ 1 ] ;
var r1 = this . coordsArr [ 2 ] ;
var x2 = this . coordsArr [ 3 ] ;
var y2 = this . coordsArr [ 4 ] ;
var r2 = this . coordsArr [ 5 ] ;
var distance = Math . sqrt ( ( x1 - x2 ) * ( x1 - x2 ) + ( y1 - y2 ) * ( y1 - y2 ) ) ;
if ( r1 <= r2 + distance &&
r2 <= r1 + distance ) {
warn ( 'Unsupported radial gradient.' ) ;
}
}
this . extendStart = extendStart ;
this . extendEnd = extendEnd ;
var fnObj = dict . get ( 'Function' ) ;
var fn ;
if ( isArray ( fnObj ) ) {
var fnArray = [ ] ;
for ( var j = 0 , jj = fnObj . length ; j < jj ; j ++ ) {
var obj = xref . fetchIfRef ( fnObj [ j ] ) ;
if ( ! isPDFFunction ( obj ) ) {
error ( 'Invalid function' ) ;
}
fnArray . push ( PDFFunction . parse ( xref , obj ) ) ;
}
fn = function radialAxialColorFunction ( arg ) {
var out = [ ] ;
for ( var i = 0 , ii = fnArray . length ; i < ii ; i ++ ) {
out . push ( fnArray [ i ] ( arg ) [ 0 ] ) ;
}
return out ;
} ;
} else {
if ( ! isPDFFunction ( fnObj ) ) {
error ( 'Invalid function' ) ;
}
fn = PDFFunction . parse ( xref , fnObj ) ;
}
// 10 samples seems good enough for now, but probably won't work
// if there are sharp color changes. Ideally, we would implement
// the spec faithfully and add lossless optimizations.
var diff = t1 - t0 ;
var step = diff / 10 ;
var colorStops = this . colorStops = [ ] ;
// Protect against bad domains so we don't end up in an infinte loop below.
if ( t0 >= t1 || step <= 0 ) {
// Acrobat doesn't seem to handle these cases so we'll ignore for
// now.
info ( 'Bad shading domain.' ) ;
return ;
}
for ( var i = t0 ; i <= t1 ; i += step ) {
var rgbColor = cs . getRgb ( fn ( [ i ] ) , 0 ) ;
var cssColor = Util . makeCssRgb ( rgbColor ) ;
colorStops . push ( [ ( i - t0 ) / diff , cssColor ] ) ;
}
var background = 'transparent' ;
if ( dict . has ( 'Background' ) ) {
var rgbColor = cs . getRgb ( dict . get ( 'Background' ) , 0 ) ;
background = Util . makeCssRgb ( rgbColor ) ;
}
if ( ! extendStart ) {
// Insert a color stop at the front and offset the first real color stop
// so it doesn't conflict with the one we insert.
colorStops . unshift ( [ 0 , background ] ) ;
colorStops [ 1 ] [ 0 ] += Shadings . SMALL _NUMBER ;
}
if ( ! extendEnd ) {
// Same idea as above in extendStart but for the end.
colorStops [ colorStops . length - 1 ] [ 0 ] -= Shadings . SMALL _NUMBER ;
colorStops . push ( [ 1 , background ] ) ;
}
this . colorStops = colorStops ;
}
RadialAxial . fromIR = function RadialAxial _fromIR ( raw ) {
var type = raw [ 1 ] ;
var colorStops = raw [ 2 ] ;
var p0 = raw [ 3 ] ;
var p1 = raw [ 4 ] ;
var r0 = raw [ 5 ] ;
var r1 = raw [ 6 ] ;
return {
type : 'Pattern' ,
getPattern : function RadialAxial _getPattern ( ctx ) {
var grad ;
if ( type == PatternType . AXIAL )
grad = ctx . createLinearGradient ( p0 [ 0 ] , p0 [ 1 ] , p1 [ 0 ] , p1 [ 1 ] ) ;
else if ( type == PatternType . RADIAL )
grad = ctx . createRadialGradient ( p0 [ 0 ] , p0 [ 1 ] , r0 , p1 [ 0 ] , p1 [ 1 ] , r1 ) ;
for ( var i = 0 , ii = colorStops . length ; i < ii ; ++ i ) {
var c = colorStops [ i ] ;
grad . addColorStop ( c [ 0 ] , c [ 1 ] ) ;
}
return grad ;
}
} ;
} ;
RadialAxial . prototype = {
getIR : function RadialAxial _getIR ( ) {
var coordsArr = this . coordsArr ;
var type = this . shadingType ;
if ( type == PatternType . AXIAL ) {
var p0 = [ coordsArr [ 0 ] , coordsArr [ 1 ] ] ;
var p1 = [ coordsArr [ 2 ] , coordsArr [ 3 ] ] ;
var r0 = null ;
var r1 = null ;
} else if ( type == PatternType . RADIAL ) {
var p0 = [ coordsArr [ 0 ] , coordsArr [ 1 ] ] ;
var p1 = [ coordsArr [ 3 ] , coordsArr [ 4 ] ] ;
var r0 = coordsArr [ 2 ] ;
var r1 = coordsArr [ 5 ] ;
} else {
error ( 'getPattern type unknown: ' + type ) ;
}
var matrix = this . matrix ;
if ( matrix ) {
p0 = Util . applyTransform ( p0 , matrix ) ;
p1 = Util . applyTransform ( p1 , matrix ) ;
}
return [ 'RadialAxial' , type , this . colorStops , p0 , p1 , r0 , r1 ] ;
}
} ;
return RadialAxial ;
} ) ( ) ;
Shadings . Dummy = ( function DummyClosure ( ) {
function Dummy ( ) {
this . type = 'Pattern' ;
}
Dummy . fromIR = function Dummy _fromIR ( ) {
return {
type : 'Pattern' ,
getPattern : function Dummy _fromIR _getPattern ( ) {
return 'hotpink' ;
}
} ;
} ;
Dummy . prototype = {
getIR : function Dummy _getIR ( ) {
return [ 'Dummy' ] ;
}
} ;
return Dummy ;
} ) ( ) ;
var TilingPattern = ( function TilingPatternClosure ( ) {
var PaintType = {
COLORED : 1 ,
UNCOLORED : 2
} ;
var MAX _PATTERN _SIZE = 3000 ; // 10in @ 300dpi shall be enough
function TilingPattern ( IR , color , ctx , objs , commonObjs , baseTransform ) {
this . name = IR [ 1 ] [ 0 ] . name ;
this . operatorList = IR [ 2 ] ;
this . matrix = IR [ 3 ] || [ 1 , 0 , 0 , 1 , 0 , 0 ] ;
this . bbox = IR [ 4 ] ;
this . xstep = IR [ 5 ] ;
this . ystep = IR [ 6 ] ;
this . paintType = IR [ 7 ] ;
this . tilingType = IR [ 8 ] ;
this . color = color ;
this . objs = objs ;
this . commonObjs = commonObjs ;
this . baseTransform = baseTransform ;
this . type = 'Pattern' ;
this . ctx = ctx ;
}
TilingPattern . getIR = function TilingPattern _getIR ( operatorList , dict , args ) {
var matrix = dict . get ( 'Matrix' ) ;
var bbox = dict . get ( 'BBox' ) ;
var xstep = dict . get ( 'XStep' ) ;
var ystep = dict . get ( 'YStep' ) ;
var paintType = dict . get ( 'PaintType' ) ;
var tilingType = dict . get ( 'TilingType' ) ;
return [
'TilingPattern' , args , operatorList , matrix , bbox , xstep , ystep ,
paintType , tilingType
] ;
} ;
TilingPattern . prototype = {
createPatternCanvas : function TilinPattern _createPatternCanvas ( owner ) {
var operatorList = this . operatorList ;
var bbox = this . bbox ;
var xstep = this . xstep ;
var ystep = this . ystep ;
var paintType = this . paintType ;
var tilingType = this . tilingType ;
var color = this . color ;
var objs = this . objs ;
var commonObjs = this . commonObjs ;
var ctx = this . ctx ;
TODO ( 'TilingType: ' + tilingType ) ;
var x0 = bbox [ 0 ] , y0 = bbox [ 1 ] , x1 = bbox [ 2 ] , y1 = bbox [ 3 ] ;
var topLeft = [ x0 , y0 ] ;
// we want the canvas to be as large as the step size
var botRight = [ x0 + xstep , y0 + ystep ] ;
var width = botRight [ 0 ] - topLeft [ 0 ] ;
var height = botRight [ 1 ] - topLeft [ 1 ] ;
// Obtain scale from matrix and current transformation matrix.
var matrixScale = Util . singularValueDecompose2dScale ( this . matrix ) ;
var curMatrixScale = Util . singularValueDecompose2dScale (
this . baseTransform ) ;
var combinedScale = [ matrixScale [ 0 ] * curMatrixScale [ 0 ] ,
matrixScale [ 1 ] * curMatrixScale [ 1 ] ] ;
// MAX_PATTERN_SIZE is used to avoid OOM situation.
// Use width and height values that are as close as possible to the end
// result when the pattern is used. Too low value makes the pattern look
// blurry. Too large value makes it look too crispy.
width = Math . min ( Math . ceil ( Math . abs ( width * combinedScale [ 0 ] ) ) ,
MAX _PATTERN _SIZE ) ;
height = Math . min ( Math . ceil ( Math . abs ( height * combinedScale [ 1 ] ) ) ,
MAX _PATTERN _SIZE ) ;
var tmpCanvas = CachedCanvases . getCanvas ( 'pattern' , width , height , true ) ;
var tmpCtx = tmpCanvas . context ;
var graphics = new CanvasGraphics ( tmpCtx , commonObjs , objs ) ;
graphics . groupLevel = owner . groupLevel ;
this . setFillAndStrokeStyleToContext ( tmpCtx , paintType , color ) ;
this . setScale ( width , height , xstep , ystep ) ;
this . transformToScale ( graphics ) ;
// transform coordinates to pattern space
var tmpTranslate = [ 1 , 0 , 0 , 1 , - topLeft [ 0 ] , - topLeft [ 1 ] ] ;
graphics . transform . apply ( graphics , tmpTranslate ) ;
this . clipBbox ( graphics , bbox , x0 , y0 , x1 , y1 ) ;
graphics . executeOperatorList ( operatorList ) ;
return tmpCanvas . canvas ;
} ,
setScale : function TilingPattern _setScale ( width , height , xstep , ystep ) {
this . scale = [ width / xstep , height / ystep ] ;
} ,
transformToScale : function TilingPattern _transformToScale ( graphics ) {
var scale = this . scale ;
var tmpScale = [ scale [ 0 ] , 0 , 0 , scale [ 1 ] , 0 , 0 ] ;
graphics . transform . apply ( graphics , tmpScale ) ;
} ,
scaleToContext : function TilingPattern _scaleToContext ( ) {
var scale = this . scale ;
this . ctx . scale ( 1 / scale [ 0 ] , 1 / scale [ 1 ] ) ;
} ,
clipBbox : function clipBbox ( graphics , bbox , x0 , y0 , x1 , y1 ) {
if ( bbox && isArray ( bbox ) && 4 == bbox . length ) {
var bboxWidth = x1 - x0 ;
var bboxHeight = y1 - y0 ;
graphics . rectangle ( x0 , y0 , bboxWidth , bboxHeight ) ;
graphics . clip ( ) ;
graphics . endPath ( ) ;
}
} ,
setFillAndStrokeStyleToContext :
function setFillAndStrokeStyleToContext ( context , paintType , color ) {
switch ( paintType ) {
case PaintType . COLORED :
var ctx = this . ctx ;
context . fillStyle = ctx . fillStyle ;
context . strokeStyle = ctx . strokeStyle ;
break ;
case PaintType . UNCOLORED :
var rgbColor = ColorSpace . singletons . rgb . getRgb ( color , 0 ) ;
var cssColor = Util . makeCssRgb ( rgbColor ) ;
context . fillStyle = cssColor ;
context . strokeStyle = cssColor ;
break ;
default :
error ( 'Unsupported paint type: ' + paintType ) ;
}
} ,
getPattern : function TilingPattern _getPattern ( ctx , owner ) {
var temporaryPatternCanvas = this . createPatternCanvas ( owner ) ;
var ctx = this . ctx ;
ctx . setTransform . apply ( ctx , this . baseTransform ) ;
ctx . transform . apply ( ctx , this . matrix ) ;
this . scaleToContext ( ) ;
return ctx . createPattern ( temporaryPatternCanvas , 'repeat' ) ;
}
} ;
return TilingPattern ;
} ) ( ) ;
var PDFFunction = ( function PDFFunctionClosure ( ) {
var CONSTRUCT _SAMPLED = 0 ;
var CONSTRUCT _INTERPOLATED = 2 ;
var CONSTRUCT _STICHED = 3 ;
var CONSTRUCT _POSTSCRIPT = 4 ;
return {
getSampleArray : function PDFFunction _getSampleArray ( size , outputSize , bps ,
str ) {
var length = 1 ;
for ( var i = 0 , ii = size . length ; i < ii ; i ++ )
length *= size [ i ] ;
length *= outputSize ;
var array = [ ] ;
var codeSize = 0 ;
var codeBuf = 0 ;
// 32 is a valid bps so shifting won't work
var sampleMul = 1.0 / ( Math . pow ( 2.0 , bps ) - 1 ) ;
var strBytes = str . getBytes ( ( length * bps + 7 ) / 8 ) ;
var strIdx = 0 ;
for ( var i = 0 ; i < length ; i ++ ) {
while ( codeSize < bps ) {
codeBuf <<= 8 ;
codeBuf |= strBytes [ strIdx ++ ] ;
codeSize += 8 ;
}
codeSize -= bps ;
array . push ( ( codeBuf >> codeSize ) * sampleMul ) ;
codeBuf &= ( 1 << codeSize ) - 1 ;
}
return array ;
} ,
getIR : function PDFFunction _getIR ( xref , fn ) {
var dict = fn . dict ;
if ( ! dict )
dict = fn ;
var types = [ this . constructSampled ,
null ,
this . constructInterpolated ,
this . constructStiched ,
this . constructPostScript ] ;
var typeNum = dict . get ( 'FunctionType' ) ;
var typeFn = types [ typeNum ] ;
if ( ! typeFn )
error ( 'Unknown type of function' ) ;
return typeFn . call ( this , fn , dict , xref ) ;
} ,
fromIR : function PDFFunction _fromIR ( IR ) {
var type = IR [ 0 ] ;
switch ( type ) {
case CONSTRUCT _SAMPLED :
return this . constructSampledFromIR ( IR ) ;
case CONSTRUCT _INTERPOLATED :
return this . constructInterpolatedFromIR ( IR ) ;
case CONSTRUCT _STICHED :
return this . constructStichedFromIR ( IR ) ;
//case CONSTRUCT_POSTSCRIPT:
default :
return this . constructPostScriptFromIR ( IR ) ;
}
} ,
parse : function PDFFunction _parse ( xref , fn ) {
var IR = this . getIR ( xref , fn ) ;
return this . fromIR ( IR ) ;
} ,
constructSampled : function PDFFunction _constructSampled ( str , dict ) {
function toMultiArray ( arr ) {
var inputLength = arr . length ;
var outputLength = arr . length / 2 ;
var out = [ ] ;
var index = 0 ;
for ( var i = 0 ; i < inputLength ; i += 2 ) {
out [ index ] = [ arr [ i ] , arr [ i + 1 ] ] ;
++ index ;
}
return out ;
}
var domain = dict . get ( 'Domain' ) ;
var range = dict . get ( 'Range' ) ;
if ( ! domain || ! range )
error ( 'No domain or range' ) ;
var inputSize = domain . length / 2 ;
var outputSize = range . length / 2 ;
domain = toMultiArray ( domain ) ;
range = toMultiArray ( range ) ;
var size = dict . get ( 'Size' ) ;
var bps = dict . get ( 'BitsPerSample' ) ;
var order = dict . get ( 'Order' ) || 1 ;
if ( order !== 1 ) {
// No description how cubic spline interpolation works in PDF32000:2008
// As in poppler, ignoring order, linear interpolation may work as good
TODO ( 'No support for cubic spline interpolation: ' + order ) ;
}
var encode = dict . get ( 'Encode' ) ;
if ( ! encode ) {
encode = [ ] ;
for ( var i = 0 ; i < inputSize ; ++ i ) {
encode . push ( 0 ) ;
encode . push ( size [ i ] - 1 ) ;
}
}
encode = toMultiArray ( encode ) ;
var decode = dict . get ( 'Decode' ) ;
if ( ! decode )
decode = range ;
else
decode = toMultiArray ( decode ) ;
var samples = this . getSampleArray ( size , outputSize , bps , str ) ;
return [
CONSTRUCT _SAMPLED , inputSize , domain , encode , decode , samples , size ,
outputSize , Math . pow ( 2 , bps ) - 1 , range
] ;
} ,
constructSampledFromIR : function PDFFunction _constructSampledFromIR ( IR ) {
// See chapter 3, page 109 of the PDF reference
function interpolate ( x , xmin , xmax , ymin , ymax ) {
return ymin + ( ( x - xmin ) * ( ( ymax - ymin ) / ( xmax - xmin ) ) ) ;
}
return function constructSampledFromIRResult ( args ) {
// See chapter 3, page 110 of the PDF reference.
var m = IR [ 1 ] ;
var domain = IR [ 2 ] ;
var encode = IR [ 3 ] ;
var decode = IR [ 4 ] ;
var samples = IR [ 5 ] ;
var size = IR [ 6 ] ;
var n = IR [ 7 ] ;
var mask = IR [ 8 ] ;
var range = IR [ 9 ] ;
if ( m != args . length )
error ( 'Incorrect number of arguments: ' + m + ' != ' +
args . length ) ;
var x = args ;
// Building the cube vertices: its part and sample index
// http://rjwagner49.com/Mathematics/Interpolation.pdf
var cubeVertices = 1 << m ;
var cubeN = new Float64Array ( cubeVertices ) ;
var cubeVertex = new Uint32Array ( cubeVertices ) ;
for ( var j = 0 ; j < cubeVertices ; j ++ )
cubeN [ j ] = 1 ;
var k = n , pos = 1 ;
// Map x_i to y_j for 0 <= i < m using the sampled function.
for ( var i = 0 ; i < m ; ++ i ) {
// x_i' = min(max(x_i, Domain_2i), Domain_2i+1)
var domain _2i = domain [ i ] [ 0 ] ;
var domain _2i _1 = domain [ i ] [ 1 ] ;
var xi = Math . min ( Math . max ( x [ i ] , domain _2i ) , domain _2i _1 ) ;
// e_i = Interpolate(x_i', Domain_2i, Domain_2i+1,
// Encode_2i, Encode_2i+1)
var e = interpolate ( xi , domain _2i , domain _2i _1 ,
encode [ i ] [ 0 ] , encode [ i ] [ 1 ] ) ;
// e_i' = min(max(e_i, 0), Size_i - 1)
var size _i = size [ i ] ;
e = Math . min ( Math . max ( e , 0 ) , size _i - 1 ) ;
// Adjusting the cube: N and vertex sample index
var e0 = e < size _i - 1 ? Math . floor ( e ) : e - 1 ; // e1 = e0 + 1;
var n0 = e0 + 1 - e ; // (e1 - e) / (e1 - e0);
var n1 = e - e0 ; // (e - e0) / (e1 - e0);
var offset0 = e0 * k ;
var offset1 = offset0 + k ; // e1 * k
for ( var j = 0 ; j < cubeVertices ; j ++ ) {
if ( j & pos ) {
cubeN [ j ] *= n1 ;
cubeVertex [ j ] += offset1 ;
} else {
cubeN [ j ] *= n0 ;
cubeVertex [ j ] += offset0 ;
}
}
k *= size _i ;
pos <<= 1 ;
}
var y = new Float64Array ( n ) ;
for ( var j = 0 ; j < n ; ++ j ) {
// Sum all cube vertices' samples portions
var rj = 0 ;
for ( var i = 0 ; i < cubeVertices ; i ++ )
rj += samples [ cubeVertex [ i ] + j ] * cubeN [ i ] ;
// r_j' = Interpolate(r_j, 0, 2^BitsPerSample - 1,
// Decode_2j, Decode_2j+1)
rj = interpolate ( rj , 0 , 1 , decode [ j ] [ 0 ] , decode [ j ] [ 1 ] ) ;
// y_j = min(max(r_j, range_2j), range_2j+1)
y [ j ] = Math . min ( Math . max ( rj , range [ j ] [ 0 ] ) , range [ j ] [ 1 ] ) ;
}
return y ;
} ;
} ,
constructInterpolated : function PDFFunction _constructInterpolated ( str ,
dict ) {
var c0 = dict . get ( 'C0' ) || [ 0 ] ;
var c1 = dict . get ( 'C1' ) || [ 1 ] ;
var n = dict . get ( 'N' ) ;
if ( ! isArray ( c0 ) || ! isArray ( c1 ) )
error ( 'Illegal dictionary for interpolated function' ) ;
var length = c0 . length ;
var diff = [ ] ;
for ( var i = 0 ; i < length ; ++ i )
diff . push ( c1 [ i ] - c0 [ i ] ) ;
return [ CONSTRUCT _INTERPOLATED , c0 , diff , n ] ;
} ,
constructInterpolatedFromIR :
function PDFFunction _constructInterpolatedFromIR ( IR ) {
var c0 = IR [ 1 ] ;
var diff = IR [ 2 ] ;
var n = IR [ 3 ] ;
var length = diff . length ;
return function constructInterpolatedFromIRResult ( args ) {
var x = n == 1 ? args [ 0 ] : Math . pow ( args [ 0 ] , n ) ;
var out = [ ] ;
for ( var j = 0 ; j < length ; ++ j )
out . push ( c0 [ j ] + ( x * diff [ j ] ) ) ;
return out ;
} ;
} ,
constructStiched : function PDFFunction _constructStiched ( fn , dict , xref ) {
var domain = dict . get ( 'Domain' ) ;
if ( ! domain )
error ( 'No domain' ) ;
var inputSize = domain . length / 2 ;
if ( inputSize != 1 )
error ( 'Bad domain for stiched function' ) ;
var fnRefs = dict . get ( 'Functions' ) ;
var fns = [ ] ;
for ( var i = 0 , ii = fnRefs . length ; i < ii ; ++ i )
fns . push ( PDFFunction . getIR ( xref , xref . fetchIfRef ( fnRefs [ i ] ) ) ) ;
var bounds = dict . get ( 'Bounds' ) ;
var encode = dict . get ( 'Encode' ) ;
return [ CONSTRUCT _STICHED , domain , bounds , encode , fns ] ;
} ,
constructStichedFromIR : function PDFFunction _constructStichedFromIR ( IR ) {
var domain = IR [ 1 ] ;
var bounds = IR [ 2 ] ;
var encode = IR [ 3 ] ;
var fnsIR = IR [ 4 ] ;
var fns = [ ] ;
for ( var i = 0 , ii = fnsIR . length ; i < ii ; i ++ ) {
fns . push ( PDFFunction . fromIR ( fnsIR [ i ] ) ) ;
}
return function constructStichedFromIRResult ( args ) {
var clip = function constructStichedFromIRClip ( v , min , max ) {
if ( v > max )
v = max ;
else if ( v < min )
v = min ;
return v ;
} ;
// clip to domain
var v = clip ( args [ 0 ] , domain [ 0 ] , domain [ 1 ] ) ;
// calulate which bound the value is in
for ( var i = 0 , ii = bounds . length ; i < ii ; ++ i ) {
if ( v < bounds [ i ] )
break ;
}
// encode value into domain of function
var dmin = domain [ 0 ] ;
if ( i > 0 )
dmin = bounds [ i - 1 ] ;
var dmax = domain [ 1 ] ;
if ( i < bounds . length )
dmax = bounds [ i ] ;
var rmin = encode [ 2 * i ] ;
var rmax = encode [ 2 * i + 1 ] ;
var v2 = rmin + ( v - dmin ) * ( rmax - rmin ) / ( dmax - dmin ) ;
// call the appropropriate function
return fns [ i ] ( [ v2 ] ) ;
} ;
} ,
constructPostScript : function PDFFunction _constructPostScript ( fn , dict ,
xref ) {
var domain = dict . get ( 'Domain' ) ;
var range = dict . get ( 'Range' ) ;
if ( ! domain )
error ( 'No domain.' ) ;
if ( ! range )
error ( 'No range.' ) ;
var lexer = new PostScriptLexer ( fn ) ;
var parser = new PostScriptParser ( lexer ) ;
var code = parser . parse ( ) ;
return [ CONSTRUCT _POSTSCRIPT , domain , range , code ] ;
} ,
constructPostScriptFromIR : function PDFFunction _constructPostScriptFromIR (
IR ) {
var domain = IR [ 1 ] ;
var range = IR [ 2 ] ;
var code = IR [ 3 ] ;
var numOutputs = range . length / 2 ;
var evaluator = new PostScriptEvaluator ( code ) ;
// Cache the values for a big speed up, the cache size is limited though
// since the number of possible values can be huge from a PS function.
var cache = new FunctionCache ( ) ;
return function constructPostScriptFromIRResult ( args ) {
var initialStack = [ ] ;
for ( var i = 0 , ii = ( domain . length / 2 ) ; i < ii ; ++ i ) {
initialStack . push ( args [ i ] ) ;
}
var key = initialStack . join ( '_' ) ;
if ( cache . has ( key ) )
return cache . get ( key ) ;
var stack = evaluator . execute ( initialStack ) ;
var transformed = [ ] ;
for ( i = numOutputs - 1 ; i >= 0 ; -- i ) {
var out = stack . pop ( ) ;
var rangeIndex = 2 * i ;
if ( out < range [ rangeIndex ] )
out = range [ rangeIndex ] ;
else if ( out > range [ rangeIndex + 1 ] )
out = range [ rangeIndex + 1 ] ;
transformed [ i ] = out ;
}
cache . set ( key , transformed ) ;
return transformed ;
} ;
}
} ;
} ) ( ) ;
var FunctionCache = ( function FunctionCacheClosure ( ) {
// Of 10 PDF's with type4 functions the maxium number of distinct values seen
// was 256. This still may need some tweaking in the future though.
var MAX _CACHE _SIZE = 1024 ;
function FunctionCache ( ) {
this . cache = { } ;
this . total = 0 ;
}
FunctionCache . prototype = {
has : function FunctionCache _has ( key ) {
return key in this . cache ;
} ,
get : function FunctionCache _get ( key ) {
return this . cache [ key ] ;
} ,
set : function FunctionCache _set ( key , value ) {
if ( this . total < MAX _CACHE _SIZE ) {
this . cache [ key ] = value ;
this . total ++ ;
}
}
} ;
return FunctionCache ;
} ) ( ) ;
var PostScriptStack = ( function PostScriptStackClosure ( ) {
var MAX _STACK _SIZE = 100 ;
function PostScriptStack ( initialStack ) {
this . stack = initialStack || [ ] ;
}
PostScriptStack . prototype = {
push : function PostScriptStack _push ( value ) {
if ( this . stack . length >= MAX _STACK _SIZE )
error ( 'PostScript function stack overflow.' ) ;
this . stack . push ( value ) ;
} ,
pop : function PostScriptStack _pop ( ) {
if ( this . stack . length <= 0 )
error ( 'PostScript function stack underflow.' ) ;
return this . stack . pop ( ) ;
} ,
copy : function PostScriptStack _copy ( n ) {
if ( this . stack . length + n >= MAX _STACK _SIZE )
error ( 'PostScript function stack overflow.' ) ;
var stack = this . stack ;
for ( var i = stack . length - n , j = n - 1 ; j >= 0 ; j -- , i ++ )
stack . push ( stack [ i ] ) ;
} ,
index : function PostScriptStack _index ( n ) {
this . push ( this . stack [ this . stack . length - n - 1 ] ) ;
} ,
// rotate the last n stack elements p times
roll : function PostScriptStack _roll ( n , p ) {
var stack = this . stack ;
var l = stack . length - n ;
var r = stack . length - 1 , c = l + ( p - Math . floor ( p / n ) * n ) , i , j , t ;
for ( i = l , j = r ; i < j ; i ++ , j -- ) {
t = stack [ i ] ; stack [ i ] = stack [ j ] ; stack [ j ] = t ;
}
for ( i = l , j = c - 1 ; i < j ; i ++ , j -- ) {
t = stack [ i ] ; stack [ i ] = stack [ j ] ; stack [ j ] = t ;
}
for ( i = c , j = r ; i < j ; i ++ , j -- ) {
t = stack [ i ] ; stack [ i ] = stack [ j ] ; stack [ j ] = t ;
}
}
} ;
return PostScriptStack ;
} ) ( ) ;
var PostScriptEvaluator = ( function PostScriptEvaluatorClosure ( ) {
function PostScriptEvaluator ( operators , operands ) {
this . operators = operators ;
this . operands = operands ;
}
PostScriptEvaluator . prototype = {
execute : function PostScriptEvaluator _execute ( initialStack ) {
var stack = new PostScriptStack ( initialStack ) ;
var counter = 0 ;
var operators = this . operators ;
var length = operators . length ;
var operator , a , b ;
while ( counter < length ) {
operator = operators [ counter ++ ] ;
if ( typeof operator == 'number' ) {
// Operator is really an operand and should be pushed to the stack.
stack . push ( operator ) ;
continue ;
}
switch ( operator ) {
// non standard ps operators
case 'jz' : // jump if false
b = stack . pop ( ) ;
a = stack . pop ( ) ;
if ( ! a )
counter = b ;
break ;
case 'j' : // jump
a = stack . pop ( ) ;
counter = a ;
break ;
// all ps operators in alphabetical order (excluding if/ifelse)
case 'abs' :
a = stack . pop ( ) ;
stack . push ( Math . abs ( a ) ) ;
break ;
case 'add' :
b = stack . pop ( ) ;
a = stack . pop ( ) ;
stack . push ( a + b ) ;
break ;
case 'and' :
b = stack . pop ( ) ;
a = stack . pop ( ) ;
if ( isBool ( a ) && isBool ( b ) )
stack . push ( a && b ) ;
else
stack . push ( a & b ) ;
break ;
case 'atan' :
a = stack . pop ( ) ;
stack . push ( Math . atan ( a ) ) ;
break ;
case 'bitshift' :
b = stack . pop ( ) ;
a = stack . pop ( ) ;
if ( a > 0 )
stack . push ( a << b ) ;
else
stack . push ( a >> b ) ;
break ;
case 'ceiling' :
a = stack . pop ( ) ;
stack . push ( Math . ceil ( a ) ) ;
break ;
case 'copy' :
a = stack . pop ( ) ;
stack . copy ( a ) ;
break ;
case 'cos' :
a = stack . pop ( ) ;
stack . push ( Math . cos ( a ) ) ;
break ;
case 'cvi' :
a = stack . pop ( ) | 0 ;
stack . push ( a ) ;
break ;
case 'cvr' :
// noop
break ;
case 'div' :
b = stack . pop ( ) ;
a = stack . pop ( ) ;
stack . push ( a / b ) ;
break ;
case 'dup' :
stack . copy ( 1 ) ;
break ;
case 'eq' :
b = stack . pop ( ) ;
a = stack . pop ( ) ;
stack . push ( a == b ) ;
break ;
case 'exch' :
stack . roll ( 2 , 1 ) ;
break ;
case 'exp' :
b = stack . pop ( ) ;
a = stack . pop ( ) ;
stack . push ( Math . pow ( a , b ) ) ;
break ;
case 'false' :
stack . push ( false ) ;
break ;
case 'floor' :
a = stack . pop ( ) ;
stack . push ( Math . floor ( a ) ) ;
break ;
case 'ge' :
b = stack . pop ( ) ;
a = stack . pop ( ) ;
stack . push ( a >= b ) ;
break ;
case 'gt' :
b = stack . pop ( ) ;
a = stack . pop ( ) ;
stack . push ( a > b ) ;
break ;
case 'idiv' :
b = stack . pop ( ) ;
a = stack . pop ( ) ;
stack . push ( ( a / b ) | 0 ) ;
break ;
case 'index' :
a = stack . pop ( ) ;
stack . index ( a ) ;
break ;
case 'le' :
b = stack . pop ( ) ;
a = stack . pop ( ) ;
stack . push ( a <= b ) ;
break ;
case 'ln' :
a = stack . pop ( ) ;
stack . push ( Math . log ( a ) ) ;
break ;
case 'log' :
a = stack . pop ( ) ;
stack . push ( Math . log ( a ) / Math . LN10 ) ;
break ;
case 'lt' :
b = stack . pop ( ) ;
a = stack . pop ( ) ;
stack . push ( a < b ) ;
break ;
case 'mod' :
b = stack . pop ( ) ;
a = stack . pop ( ) ;
stack . push ( a % b ) ;
break ;
case 'mul' :
b = stack . pop ( ) ;
a = stack . pop ( ) ;
stack . push ( a * b ) ;
break ;
case 'ne' :
b = stack . pop ( ) ;
a = stack . pop ( ) ;
stack . push ( a != b ) ;
break ;
case 'neg' :
a = stack . pop ( ) ;
stack . push ( - b ) ;
break ;
case 'not' :
a = stack . pop ( ) ;
if ( isBool ( a ) && isBool ( b ) )
stack . push ( a && b ) ;
else
stack . push ( a & b ) ;
break ;
case 'or' :
b = stack . pop ( ) ;
a = stack . pop ( ) ;
if ( isBool ( a ) && isBool ( b ) )
stack . push ( a || b ) ;
else
stack . push ( a | b ) ;
break ;
case 'pop' :
stack . pop ( ) ;
break ;
case 'roll' :
b = stack . pop ( ) ;
a = stack . pop ( ) ;
stack . roll ( a , b ) ;
break ;
case 'round' :
a = stack . pop ( ) ;
stack . push ( Math . round ( a ) ) ;
break ;
case 'sin' :
a = stack . pop ( ) ;
stack . push ( Math . sin ( a ) ) ;
break ;
case 'sqrt' :
a = stack . pop ( ) ;
stack . push ( Math . sqrt ( a ) ) ;
break ;
case 'sub' :
b = stack . pop ( ) ;
a = stack . pop ( ) ;
stack . push ( a - b ) ;
break ;
case 'true' :
stack . push ( true ) ;
break ;
case 'truncate' :
a = stack . pop ( ) ;
a = a < 0 ? Math . ceil ( a ) : Math . floor ( a ) ;
stack . push ( a ) ;
break ;
case 'xor' :
b = stack . pop ( ) ;
a = stack . pop ( ) ;
if ( isBool ( a ) && isBool ( b ) )
stack . push ( a != b ) ;
else
stack . push ( a ^ b ) ;
break ;
default :
error ( 'Unknown operator ' + operator ) ;
break ;
}
}
return stack . stack ;
}
} ;
return PostScriptEvaluator ;
} ) ( ) ;
var PostScriptParser = ( function PostScriptParserClosure ( ) {
function PostScriptParser ( lexer ) {
this . lexer = lexer ;
this . operators = [ ] ;
this . token = null ;
this . prev = null ;
}
PostScriptParser . prototype = {
nextToken : function PostScriptParser _nextToken ( ) {
this . prev = this . token ;
this . token = this . lexer . getToken ( ) ;
} ,
accept : function PostScriptParser _accept ( type ) {
if ( this . token . type == type ) {
this . nextToken ( ) ;
return true ;
}
return false ;
} ,
expect : function PostScriptParser _expect ( type ) {
if ( this . accept ( type ) )
return true ;
error ( 'Unexpected symbol: found ' + this . token . type + ' expected ' +
type + '.' ) ;
} ,
parse : function PostScriptParser _parse ( ) {
this . nextToken ( ) ;
this . expect ( PostScriptTokenTypes . LBRACE ) ;
this . parseBlock ( ) ;
this . expect ( PostScriptTokenTypes . RBRACE ) ;
return this . operators ;
} ,
parseBlock : function PostScriptParser _parseBlock ( ) {
while ( true ) {
if ( this . accept ( PostScriptTokenTypes . NUMBER ) ) {
this . operators . push ( this . prev . value ) ;
} else if ( this . accept ( PostScriptTokenTypes . OPERATOR ) ) {
this . operators . push ( this . prev . value ) ;
} else if ( this . accept ( PostScriptTokenTypes . LBRACE ) ) {
this . parseCondition ( ) ;
} else {
return ;
}
}
} ,
parseCondition : function PostScriptParser _parseCondition ( ) {
// Add two place holders that will be updated later
var conditionLocation = this . operators . length ;
this . operators . push ( null , null ) ;
this . parseBlock ( ) ;
this . expect ( PostScriptTokenTypes . RBRACE ) ;
if ( this . accept ( PostScriptTokenTypes . IF ) ) {
// The true block is right after the 'if' so it just falls through on
// true else it jumps and skips the true block.
this . operators [ conditionLocation ] = this . operators . length ;
this . operators [ conditionLocation + 1 ] = 'jz' ;
} else if ( this . accept ( PostScriptTokenTypes . LBRACE ) ) {
var jumpLocation = this . operators . length ;
this . operators . push ( null , null ) ;
var endOfTrue = this . operators . length ;
this . parseBlock ( ) ;
this . expect ( PostScriptTokenTypes . RBRACE ) ;
this . expect ( PostScriptTokenTypes . IFELSE ) ;
// The jump is added at the end of the true block to skip the false
// block.
this . operators [ jumpLocation ] = this . operators . length ;
this . operators [ jumpLocation + 1 ] = 'j' ;
this . operators [ conditionLocation ] = endOfTrue ;
this . operators [ conditionLocation + 1 ] = 'jz' ;
} else {
error ( 'PS Function: error parsing conditional.' ) ;
}
}
} ;
return PostScriptParser ;
} ) ( ) ;
var PostScriptTokenTypes = {
LBRACE : 0 ,
RBRACE : 1 ,
NUMBER : 2 ,
OPERATOR : 3 ,
IF : 4 ,
IFELSE : 5
} ;
var PostScriptToken = ( function PostScriptTokenClosure ( ) {
function PostScriptToken ( type , value ) {
this . type = type ;
this . value = value ;
}
var opCache = { } ;
PostScriptToken . getOperator = function PostScriptToken _getOperator ( op ) {
var opValue = opCache [ op ] ;
if ( opValue )
return opValue ;
return opCache [ op ] = new PostScriptToken ( PostScriptTokenTypes . OPERATOR , op ) ;
} ;
PostScriptToken . LBRACE = new PostScriptToken ( PostScriptTokenTypes . LBRACE ,
'{' ) ;
PostScriptToken . RBRACE = new PostScriptToken ( PostScriptTokenTypes . RBRACE ,
'}' ) ;
PostScriptToken . IF = new PostScriptToken ( PostScriptTokenTypes . IF , 'IF' ) ;
PostScriptToken . IFELSE = new PostScriptToken ( PostScriptTokenTypes . IFELSE ,
'IFELSE' ) ;
return PostScriptToken ;
} ) ( ) ;
var PostScriptLexer = ( function PostScriptLexerClosure ( ) {
function PostScriptLexer ( stream ) {
this . stream = stream ;
this . nextChar ( ) ;
}
PostScriptLexer . prototype = {
nextChar : function PostScriptLexer _nextChar ( ) {
return ( this . currentChar = this . stream . getByte ( ) ) ;
} ,
getToken : function PostScriptLexer _getToken ( ) {
var s = '' ;
var comment = false ;
var ch = this . currentChar ;
// skip comments
while ( true ) {
if ( ch < 0 ) {
return EOF ;
}
if ( comment ) {
if ( ch === 0x0A || ch === 0x0D ) {
comment = false ;
}
} else if ( ch == 0x25 ) { // '%'
comment = true ;
} else if ( ! Lexer . isSpace ( ch ) ) {
break ;
}
ch = this . nextChar ( ) ;
}
switch ( ch | 0 ) {
case 0x30 : case 0x31 : case 0x32 : case 0x33 : case 0x34 : // '0'-'4'
case 0x35 : case 0x36 : case 0x37 : case 0x38 : case 0x39 : // '5'-'9'
case 0x2B : case 0x2D : case 0x2E : // '+', '-', '.'
return new PostScriptToken ( PostScriptTokenTypes . NUMBER ,
this . getNumber ( ) ) ;
case 0x7B : // '{'
this . nextChar ( ) ;
return PostScriptToken . LBRACE ;
case 0x7D : // '}'
this . nextChar ( ) ;
return PostScriptToken . RBRACE ;
}
// operator
var str = String . fromCharCode ( ch ) ;
while ( ( ch = this . nextChar ( ) ) >= 0 && // and 'A'-'Z', 'a'-'z'
( ( ch >= 0x41 && ch <= 0x5A ) || ( ch >= 0x61 && ch <= 0x7A ) ) ) {
str += String . fromCharCode ( ch ) ;
}
switch ( str . toLowerCase ( ) ) {
case 'if' :
return PostScriptToken . IF ;
case 'ifelse' :
return PostScriptToken . IFELSE ;
default :
return PostScriptToken . getOperator ( str ) ;
}
} ,
getNumber : function PostScriptLexer _getNumber ( ) {
var ch = this . currentChar ;
var str = String . fromCharCode ( ch ) ;
while ( ( ch = this . nextChar ( ) ) >= 0 ) {
if ( ( ch >= 0x30 && ch <= 0x39 ) || // '0'-'9'
ch === 0x2D || ch === 0x2E ) { // '-', '.'
str += String . fromCharCode ( ch ) ;
} else {
break ;
}
}
var value = parseFloat ( str ) ;
if ( isNaN ( value ) )
error ( 'Invalid floating point number: ' + value ) ;
return value ;
}
} ;
return PostScriptLexer ;
} ) ( ) ;
var Annotation = ( function AnnotationClosure ( ) {
// 12.5.5: Algorithm: Appearance streams
function getTransformMatrix ( rect , bbox , matrix ) {
var bounds = Util . getAxialAlignedBoundingBox ( bbox , matrix ) ;
var minX = bounds [ 0 ] ;
var minY = bounds [ 1 ] ;
var maxX = bounds [ 2 ] ;
var maxY = bounds [ 3 ] ;
if ( minX === maxX || minY === maxY ) {
// From real-life file, bbox was [0, 0, 0, 0]. In this case,
// just apply the transform for rect
return [ 1 , 0 , 0 , 1 , rect [ 0 ] , rect [ 1 ] ] ;
}
var xRatio = ( rect [ 2 ] - rect [ 0 ] ) / ( maxX - minX ) ;
var yRatio = ( rect [ 3 ] - rect [ 1 ] ) / ( maxY - minY ) ;
return [
xRatio ,
0 ,
0 ,
yRatio ,
rect [ 0 ] - minX * xRatio ,
rect [ 1 ] - minY * yRatio
] ;
}
function getDefaultAppearance ( dict ) {
var appearanceState = dict . get ( 'AP' ) ;
if ( ! isDict ( appearanceState ) ) {
return ;
}
var appearance ;
var appearances = appearanceState . get ( 'N' ) ;
if ( isDict ( appearances ) ) {
var as = dict . get ( 'AS' ) ;
if ( as && appearances . has ( as . name ) ) {
appearance = appearances . get ( as . name ) ;
}
} else {
appearance = appearances ;
}
return appearance ;
}
function Annotation ( params ) {
if ( params . data ) {
this . data = params . data ;
return ;
}
var dict = params . dict ;
var data = this . data = { } ;
data . subtype = dict . get ( 'Subtype' ) . name ;
var rect = dict . get ( 'Rect' ) ;
data . rect = Util . normalizeRect ( rect ) ;
data . annotationFlags = dict . get ( 'F' ) ;
var color = dict . get ( 'C' ) ;
if ( isArray ( color ) && color . length === 3 ) {
// TODO(mack): currently only supporting rgb; need support different
// colorspaces
data . color = color ;
} else {
data . color = [ 0 , 0 , 0 ] ;
}
// Some types of annotations have border style dict which has more
// info than the border array
if ( dict . has ( 'BS' ) ) {
var borderStyle = dict . get ( 'BS' ) ;
data . borderWidth = borderStyle . has ( 'W' ) ? borderStyle . get ( 'W' ) : 1 ;
} else {
var borderArray = dict . get ( 'Border' ) || [ 0 , 0 , 1 ] ;
data . borderWidth = borderArray [ 2 ] || 0 ;
}
this . appearance = getDefaultAppearance ( dict ) ;
data . hasAppearance = ! ! this . appearance ;
}
Annotation . prototype = {
getData : function Annotation _getData ( ) {
return this . data ;
} ,
hasHtml : function Annotation _hasHtml ( ) {
return false ;
} ,
getHtmlElement : function Annotation _getHtmlElement ( commonObjs ) {
throw new NotImplementedException (
'getHtmlElement() should be implemented in subclass' ) ;
} ,
// TODO(mack): Remove this, it's not really that helpful.
getEmptyContainer : function Annotation _getEmptyContainer ( tagName , rect ) {
assert ( ! isWorker ,
'getEmptyContainer() should be called from main thread' ) ;
rect = rect || this . data . rect ;
var element = document . createElement ( tagName ) ;
element . style . width = Math . ceil ( rect [ 2 ] - rect [ 0 ] ) + 'px' ;
element . style . height = Math . ceil ( rect [ 3 ] - rect [ 1 ] ) + 'px' ;
return element ;
} ,
isViewable : function Annotation _isViewable ( ) {
var data = this . data ;
return ! ! (
data &&
( ! data . annotationFlags ||
! ( data . annotationFlags & 0x22 ) ) && // Hidden or NoView
data . rect // rectangle is nessessary
) ;
} ,
loadResources : function ( keys ) {
var promise = new Promise ( ) ;
this . appearance . dict . getAsync ( 'Resources' ) . then ( function ( resources ) {
if ( ! resources ) {
promise . resolve ( ) ;
return ;
}
var objectLoader = new ObjectLoader ( resources . map ,
keys ,
resources . xref ) ;
objectLoader . load ( ) . then ( function ( ) {
promise . resolve ( resources ) ;
} ) ;
} . bind ( this ) ) ;
return promise ;
} ,
getOperatorList : function Annotation _getToOperatorList ( evaluator ) {
var promise = new Promise ( ) ;
if ( ! this . appearance ) {
promise . resolve ( new OperatorList ( ) ) ;
return promise ;
}
var data = this . data ;
var appearanceDict = this . appearance . dict ;
var resourcesPromise = this . loadResources ( [
'ExtGState' ,
'ColorSpace' ,
'Pattern' ,
'Shading' ,
'XObject' ,
'Font'
// ProcSet
// Properties
] ) ;
var bbox = appearanceDict . get ( 'BBox' ) || [ 0 , 0 , 1 , 1 ] ;
var matrix = appearanceDict . get ( 'Matrix' ) || [ 1 , 0 , 0 , 1 , 0 , 0 ] ;
var transform = getTransformMatrix ( data . rect , bbox , matrix ) ;
var border = data . border ;
resourcesPromise . then ( function ( resources ) {
var opList = new OperatorList ( ) ;
opList . addOp ( OPS . beginAnnotation , [ data . rect , transform , matrix ] ) ;
evaluator . getOperatorList ( this . appearance , resources , opList ) ;
opList . addOp ( OPS . endAnnotation , [ ] ) ;
promise . resolve ( opList ) ;
} . bind ( this ) ) ;
return promise ;
}
} ;
Annotation . getConstructor =
function Annotation _getConstructor ( subtype , fieldType ) {
if ( ! subtype ) {
return ;
}
// TODO(mack): Implement FreeText annotations
if ( subtype === 'Link' ) {
return LinkAnnotation ;
} else if ( subtype === 'Text' ) {
return TextAnnotation ;
} else if ( subtype === 'Widget' ) {
if ( ! fieldType ) {
return ;
}
if ( fieldType === 'Tx' ) {
return TextWidgetAnnotation ;
} else {
return WidgetAnnotation ;
}
} else {
return Annotation ;
}
} ;
// TODO(mack): Support loading annotation from data
Annotation . fromData = function Annotation _fromData ( data ) {
var subtype = data . subtype ;
var fieldType = data . fieldType ;
var Constructor = Annotation . getConstructor ( subtype , fieldType ) ;
if ( Constructor ) {
return new Constructor ( { data : data } ) ;
}
} ;
Annotation . fromRef = function Annotation _fromRef ( xref , ref ) {
var dict = xref . fetchIfRef ( ref ) ;
if ( ! isDict ( dict ) ) {
return ;
}
var subtype = dict . get ( 'Subtype' ) ;
subtype = isName ( subtype ) ? subtype . name : '' ;
if ( ! subtype ) {
return ;
}
var fieldType = Util . getInheritableProperty ( dict , 'FT' ) ;
fieldType = isName ( fieldType ) ? fieldType . name : '' ;
var Constructor = Annotation . getConstructor ( subtype , fieldType ) ;
if ( ! Constructor ) {
return ;
}
var params = {
dict : dict ,
ref : ref ,
} ;
var annotation = new Constructor ( params ) ;
if ( annotation . isViewable ( ) ) {
return annotation ;
} else {
TODO ( 'unimplemented annotation type: ' + subtype ) ;
}
} ;
Annotation . appendToOperatorList = function Annotation _appendToOperatorList (
annotations , opList , pdfManager , partialEvaluator ) {
function reject ( e ) {
annotationsReadyPromise . reject ( e ) ;
}
var annotationsReadyPromise = new Promise ( ) ;
var annotationPromises = [ ] ;
for ( var i = 0 , n = annotations . length ; i < n ; ++ i ) {
annotationPromises . push ( annotations [ i ] . getOperatorList ( partialEvaluator ) ) ;
}
Promise . all ( annotationPromises ) . then ( function ( datas ) {
opList . addOp ( OPS . beginAnnotations , [ ] ) ;
for ( var i = 0 , n = datas . length ; i < n ; ++ i ) {
var annotOpList = datas [ i ] ;
opList . addOpList ( annotOpList ) ;
}
opList . addOp ( OPS . endAnnotations , [ ] ) ;
annotationsReadyPromise . resolve ( ) ;
} , reject ) ;
return annotationsReadyPromise ;
} ;
return Annotation ;
} ) ( ) ;
PDFJS . Annotation = Annotation ;
var WidgetAnnotation = ( function WidgetAnnotationClosure ( ) {
function WidgetAnnotation ( params ) {
Annotation . call ( this , params ) ;
if ( params . data ) {
return ;
}
var dict = params . dict ;
var data = this . data ;
data . fieldValue = stringToPDFString (
Util . getInheritableProperty ( dict , 'V' ) || '' ) ;
data . alternativeText = stringToPDFString ( dict . get ( 'TU' ) || '' ) ;
data . defaultAppearance = Util . getInheritableProperty ( dict , 'DA' ) || '' ;
var fieldType = Util . getInheritableProperty ( dict , 'FT' ) ;
data . fieldType = isName ( fieldType ) ? fieldType . name : '' ;
data . fieldFlags = Util . getInheritableProperty ( dict , 'Ff' ) || 0 ;
this . fieldResources = Util . getInheritableProperty ( dict , 'DR' ) || new Dict ( ) ;
// Building the full field name by collecting the field and
// its ancestors 'T' data and joining them using '.'.
var fieldName = [ ] ;
var namedItem = dict ;
var ref = params . ref ;
while ( namedItem ) {
var parent = namedItem . get ( 'Parent' ) ;
var parentRef = namedItem . getRaw ( 'Parent' ) ;
var name = namedItem . get ( 'T' ) ;
if ( name ) {
fieldName . unshift ( stringToPDFString ( name ) ) ;
} else {
// The field name is absent, that means more than one field
// with the same name may exist. Replacing the empty name
// with the '`' plus index in the parent's 'Kids' array.
// This is not in the PDF spec but necessary to id the
// the input controls.
var kids = parent . get ( 'Kids' ) ;
var j , jj ;
for ( j = 0 , jj = kids . length ; j < jj ; j ++ ) {
var kidRef = kids [ j ] ;
if ( kidRef . num == ref . num && kidRef . gen == ref . gen )
break ;
}
fieldName . unshift ( '`' + j ) ;
}
namedItem = parent ;
ref = parentRef ;
}
data . fullName = fieldName . join ( '.' ) ;
}
var parent = Annotation . prototype ;
Util . inherit ( WidgetAnnotation , Annotation , {
isViewable : function WidgetAnnotation _isViewable ( ) {
if ( this . data . fieldType === 'Sig' ) {
TODO ( 'unimplemented annotation type: Widget signature' ) ;
return false ;
}
return parent . isViewable . call ( this ) ;
}
} ) ;
return WidgetAnnotation ;
} ) ( ) ;
var TextWidgetAnnotation = ( function TextWidgetAnnotationClosure ( ) {
function TextWidgetAnnotation ( params ) {
WidgetAnnotation . call ( this , params ) ;
if ( params . data ) {
return ;
}
this . data . textAlignment = Util . getInheritableProperty ( params . dict , 'Q' ) ;
}
// TODO(mack): This dupes some of the logic in CanvasGraphics.setFont()
function setTextStyles ( element , item , fontObj ) {
var style = element . style ;
style . fontSize = item . fontSize + 'px' ;
style . direction = item . fontDirection < 0 ? 'rtl' : 'ltr' ;
if ( ! fontObj ) {
return ;
}
style . fontWeight = fontObj . black ?
( fontObj . bold ? 'bolder' : 'bold' ) :
( fontObj . bold ? 'bold' : 'normal' ) ;
style . fontStyle = fontObj . italic ? 'italic' : 'normal' ;
var fontName = fontObj . loadedName ;
var fontFamily = fontName ? '"' + fontName + '", ' : '' ;
// Use a reasonable default font if the font doesn't specify a fallback
var fallbackName = fontObj . fallbackName || 'Helvetica, sans-serif' ;
style . fontFamily = fontFamily + fallbackName ;
}
var parent = WidgetAnnotation . prototype ;
Util . inherit ( TextWidgetAnnotation , WidgetAnnotation , {
hasHtml : function TextWidgetAnnotation _hasHtml ( ) {
return ! this . data . hasAppearance && ! ! this . data . fieldValue ;
} ,
getHtmlElement : function TextWidgetAnnotation _getHtmlElement ( commonObjs ) {
assert ( ! isWorker , 'getHtmlElement() shall be called from main thread' ) ;
var item = this . data ;
var element = this . getEmptyContainer ( 'div' ) ;
element . style . display = 'table' ;
var content = document . createElement ( 'div' ) ;
content . textContent = item . fieldValue ;
var textAlignment = item . textAlignment ;
content . style . textAlign = [ 'left' , 'center' , 'right' ] [ textAlignment ] ;
content . style . verticalAlign = 'middle' ;
content . style . display = 'table-cell' ;
var fontObj = item . fontRefName ?
commonObjs . getData ( item . fontRefName ) : null ;
var cssRules = setTextStyles ( content , item , fontObj ) ;
element . appendChild ( content ) ;
return element ;
} ,
getOperatorList : function TextWidgetAnnotation _getOperatorList ( evaluator ) {
if ( this . appearance ) {
return Annotation . prototype . getOperatorList . call ( this , evaluator ) ;
}
var promise = new Promise ( ) ;
var opList = new OperatorList ( ) ;
var data = this . data ;
// Even if there is an appearance stream, ignore it. This is the
// behaviour used by Adobe Reader.
var defaultAppearance = data . defaultAppearance ;
if ( ! defaultAppearance ) {
promise . resolve ( opList ) ;
return promise ;
}
// Include any font resources found in the default appearance
var stream = new Stream ( stringToBytes ( defaultAppearance ) ) ;
evaluator . getOperatorList ( stream , this . fieldResources , opList ) ;
var appearanceFnArray = opList . fnArray ;
var appearanceArgsArray = opList . argsArray ;
var fnArray = [ ] ;
var argsArray = [ ] ;
// TODO(mack): Add support for stroke color
data . rgb = [ 0 , 0 , 0 ] ;
// TODO THIS DOESN'T MAKE ANY SENSE SINCE THE fnArray IS EMPTY!
for ( var i = 0 , n = fnArray . length ; i < n ; ++ i ) {
var fnId = appearanceFnArray [ i ] ;
var args = appearanceArgsArray [ i ] ;
if ( fnId === OPS . setFont ) {
data . fontRefName = args [ 0 ] ;
var size = args [ 1 ] ;
if ( size < 0 ) {
data . fontDirection = - 1 ;
data . fontSize = - size ;
} else {
data . fontDirection = 1 ;
data . fontSize = size ;
}
} else if ( fnId === OPS . setFillRGBColor ) {
data . rgb = args ;
} else if ( fnId === OPS . setFillGray ) {
var rgbValue = args [ 0 ] * 255 ;
data . rgb = [ rgbValue , rgbValue , rgbValue ] ;
}
}
promise . resolve ( opList ) ;
return promise ;
}
} ) ;
return TextWidgetAnnotation ;
} ) ( ) ;
var TextAnnotation = ( function TextAnnotationClosure ( ) {
function TextAnnotation ( params ) {
Annotation . call ( this , params ) ;
if ( params . data ) {
return ;
}
var dict = params . dict ;
var data = this . data ;
var content = dict . get ( 'Contents' ) ;
var title = dict . get ( 'T' ) ;
data . content = stringToPDFString ( content || '' ) ;
data . title = stringToPDFString ( title || '' ) ;
data . name = ! dict . has ( 'Name' ) ? 'Note' : dict . get ( 'Name' ) . name ;
}
var ANNOT _MIN _SIZE = 10 ;
Util . inherit ( TextAnnotation , Annotation , {
getOperatorList : function TextAnnotation _getOperatorList ( evaluator ) {
var promise = new Promise ( ) ;
promise . resolve ( new OperatorList ( ) ) ;
return promise ;
} ,
hasHtml : function TextAnnotation _hasHtml ( ) {
return true ;
} ,
getHtmlElement : function TextAnnotation _getHtmlElement ( commonObjs ) {
assert ( ! isWorker , 'getHtmlElement() shall be called from main thread' ) ;
var item = this . data ;
var rect = item . rect ;
// sanity check because of OOo-generated PDFs
if ( ( rect [ 3 ] - rect [ 1 ] ) < ANNOT _MIN _SIZE ) {
rect [ 3 ] = rect [ 1 ] + ANNOT _MIN _SIZE ;
}
if ( ( rect [ 2 ] - rect [ 0 ] ) < ANNOT _MIN _SIZE ) {
rect [ 2 ] = rect [ 0 ] + ( rect [ 3 ] - rect [ 1 ] ) ; // make it square
}
var container = this . getEmptyContainer ( 'section' , rect ) ;
container . className = 'annotText' ;
var image = document . createElement ( 'img' ) ;
image . style . height = container . style . height ;
var iconName = item . name ;
image . src = PDFJS . imageResourcesPath + 'annotation-' +
iconName . toLowerCase ( ) + '.svg' ;
image . alt = '[{{type}} Annotation]' ;
image . dataset . l10nId = 'text_annotation_type' ;
image . dataset . l10nArgs = JSON . stringify ( { type : iconName } ) ;
var content = document . createElement ( 'div' ) ;
content . setAttribute ( 'hidden' , true ) ;
var title = document . createElement ( 'h1' ) ;
var text = document . createElement ( 'p' ) ;
content . style . left = Math . floor ( rect [ 2 ] - rect [ 0 ] ) + 'px' ;
content . style . top = '0px' ;
title . textContent = item . title ;
if ( ! item . content && ! item . title ) {
content . setAttribute ( 'hidden' , true ) ;
} else {
var e = document . createElement ( 'span' ) ;
var lines = item . content . split ( /(?:\r\n?|\n)/ ) ;
for ( var i = 0 , ii = lines . length ; i < ii ; ++ i ) {
var line = lines [ i ] ;
e . appendChild ( document . createTextNode ( line ) ) ;
if ( i < ( ii - 1 ) )
e . appendChild ( document . createElement ( 'br' ) ) ;
}
text . appendChild ( e ) ;
var showAnnotation = function showAnnotation ( ) {
container . style . zIndex += 1 ;
content . removeAttribute ( 'hidden' ) ;
} ;
var hideAnnotation = function hideAnnotation ( e ) {
if ( e . toElement || e . relatedTarget ) { // No context menu is used
container . style . zIndex -= 1 ;
content . setAttribute ( 'hidden' , true ) ;
}
} ;
content . addEventListener ( 'mouseover' , showAnnotation , false ) ;
content . addEventListener ( 'mouseout' , hideAnnotation , false ) ;
image . addEventListener ( 'mouseover' , showAnnotation , false ) ;
image . addEventListener ( 'mouseout' , hideAnnotation , false ) ;
}
content . appendChild ( title ) ;
content . appendChild ( text ) ;
container . appendChild ( image ) ;
container . appendChild ( content ) ;
return container ;
}
} ) ;
return TextAnnotation ;
} ) ( ) ;
var LinkAnnotation = ( function LinkAnnotationClosure ( ) {
function LinkAnnotation ( params ) {
Annotation . call ( this , params ) ;
if ( params . data ) {
return ;
}
var dict = params . dict ;
var data = this . data ;
var action = dict . get ( 'A' ) ;
if ( action ) {
var linkType = action . get ( 'S' ) . name ;
if ( linkType === 'URI' ) {
var url = addDefaultProtocolToUrl ( action . get ( 'URI' ) ) ;
// TODO: pdf spec mentions urls can be relative to a Base
// entry in the dictionary.
if ( ! isValidUrl ( url , false ) ) {
url = '' ;
}
data . url = url ;
} else if ( linkType === 'GoTo' ) {
data . dest = action . get ( 'D' ) ;
} else if ( linkType === 'GoToR' ) {
var urlDict = action . get ( 'F' ) ;
if ( isDict ( urlDict ) ) {
// We assume that the 'url' is a Filspec dictionary
// and fetch the url without checking any further
url = urlDict . get ( 'F' ) || '' ;
}
// TODO: pdf reference says that GoToR
// can also have 'NewWindow' attribute
if ( ! isValidUrl ( url , false ) ) {
url = '' ;
}
data . url = url ;
data . dest = action . get ( 'D' ) ;
} else if ( linkType === 'Named' ) {
data . action = action . get ( 'N' ) . name ;
} else {
TODO ( 'unrecognized link type: ' + linkType ) ;
}
} else if ( dict . has ( 'Dest' ) ) {
// simple destination link
var dest = dict . get ( 'Dest' ) ;
data . dest = isName ( dest ) ? dest . name : dest ;
}
}
// Lets URLs beginning with 'www.' default to using the 'http://' protocol.
function addDefaultProtocolToUrl ( url ) {
if ( url . indexOf ( 'www.' ) === 0 ) {
return ( 'http://' + url ) ;
}
return url ;
}
Util . inherit ( LinkAnnotation , Annotation , {
hasOperatorList : function LinkAnnotation _hasOperatorList ( ) {
return false ;
} ,
hasHtml : function LinkAnnotation _hasHtml ( ) {
return true ;
} ,
getHtmlElement : function LinkAnnotation _getHtmlElement ( commonObjs ) {
var rect = this . data . rect ;
var element = document . createElement ( 'a' ) ;
var borderWidth = this . data . borderWidth ;
element . style . borderWidth = borderWidth + 'px' ;
var color = this . data . color ;
var rgb = [ ] ;
for ( var i = 0 ; i < 3 ; ++ i ) {
rgb [ i ] = Math . round ( color [ i ] * 255 ) ;
}
element . style . borderColor = Util . makeCssRgb ( rgb ) ;
element . style . borderStyle = 'solid' ;
var width = rect [ 2 ] - rect [ 0 ] - 2 * borderWidth ;
var height = rect [ 3 ] - rect [ 1 ] - 2 * borderWidth ;
element . style . width = width + 'px' ;
element . style . height = height + 'px' ;
element . href = this . data . url || '' ;
return element ;
}
} ) ;
return LinkAnnotation ;
} ) ( ) ;
/ * *
* The maximum allowed image size in total pixels e . g . width * height . Images
* above this value will not be drawn . Use - 1 for no limit .
* @ var { Number }
* /
PDFJS . maxImageSize = PDFJS . maxImageSize === undefined ? - 1 : PDFJS . maxImageSize ;
/ * *
* By default fonts are converted to OpenType fonts and loaded via font face
* rules . If disabled , the font will be rendered using a built in font renderer
* that constructs the glyphs with primitive path commands .
* @ var { Boolean }
* /
PDFJS . disableFontFace = PDFJS . disableFontFace === undefined ?
false : PDFJS . disableFontFace ;
/ * *
* Path for image resources , mainly for annotation icons . Include trailing
* slash .
* @ var { String }
* /
PDFJS . imageResourcesPath = PDFJS . imageResourcesPath === undefined ?
'' : PDFJS . imageResourcesPath ;
/ * *
* Disable the web worker and run all code on the main thread . This will happen
* automatically if the browser doesn ' t support workers or sending typed arrays
* to workers .
* @ var { Boolean }
* /
PDFJS . disableWorker = PDFJS . disableWorker === undefined ?
false : PDFJS . disableWorker ;
/ * *
* Path and filename of the worker file . Required when the worker is enabled in
* development mode . If unspecified in the production build , the worker will be
* loaded based on the location of the pdf . js file .
* @ var { String }
* /
PDFJS . workerSrc = PDFJS . workerSrc === undefined ? null : PDFJS . workerSrc ;
/ * *
* Disable range request loading of PDF files . When enabled and if the server
* supports partial content requests then the PDF will be fetched in chunks .
* Enabled ( false ) by default .
* @ var { Boolean }
* /
PDFJS . disableRange = PDFJS . disableRange === undefined ?
false : PDFJS . disableRange ;
/ * *
* Disable pre - fetching of PDF file data . When range requests are enabled PDF . js
* will automatically keep fetching more data even if it isn ' t needed to display
* the current page . This default behavior can be disabled .
* @ var { Boolean }
* /
PDFJS . disableAutoFetch = PDFJS . disableAutoFetch === undefined ?
false : PDFJS . disableAutoFetch ;
/ * *
* Enables special hooks for debugging PDF . js .
* @ var { Boolean }
* /
PDFJS . pdfBug = PDFJS . pdfBug === undefined ? false : PDFJS . pdfBug ;
/ * *
* Enables transfer usage in postMessage for ArrayBuffers .
* @ var { boolean }
* /
PDFJS . postMessageTransfers = PDFJS . postMessageTransfers === undefined ?
true : PDFJS . postMessageTransfers ;
/ * *
* This is the main entry point for loading a PDF and interacting with it .
* NOTE : If a URL is used to fetch the PDF data a standard XMLHttpRequest ( XHR )
* is used , which means it must follow the same origin rules that any XHR does
* e . g . No cross domain requests without CORS .
*
* @ param { string | TypedAray | object } source Can be an url to where a PDF is
* located , a typed array ( Uint8Array ) already populated with data or
* and parameter object with the following possible fields :
* - url - The URL of the PDF .
* - data - A typed array with PDF data .
* - httpHeaders - Basic authentication headers .
* - password - For decrypting password - protected PDFs .
* - initialData - A typed array with the first portion or all of the pdf data .
* Used by the extension since some data is already loaded
* before the switch to range requests .
*
* @ param { object } pdfDataRangeTransport is optional . It is used if you want
* to manually serve range requests for data in the PDF . See viewer . js for
* an example of pdfDataRangeTransport ' s interface .
*
* @ param { function } passwordCallback is optional . It is used to request a
* password if wrong or no password was provided . The callback receives two
* parameters : function that needs to be called with new password and reason
* ( see { PasswordResponses } ) .
*
* @ return { Promise } A promise that is resolved with { PDFDocumentProxy } object .
* /
PDFJS . getDocument = function getDocument ( source ,
pdfDataRangeTransport ,
passwordCallback ,
progressCallback ) {
var workerInitializedPromise , workerReadyPromise , transport ;
if ( typeof source === 'string' ) {
source = { url : source } ;
} else if ( isArrayBuffer ( source ) ) {
source = { data : source } ;
} else if ( typeof source !== 'object' ) {
error ( 'Invalid parameter in getDocument, need either Uint8Array, ' +
'string or a parameter object' ) ;
}
if ( ! source . url && ! source . data )
error ( 'Invalid parameter array, need either .data or .url' ) ;
// copy/use all keys as is except 'url' -- full path is required
var params = { } ;
for ( var key in source ) {
if ( key === 'url' && typeof window !== 'undefined' ) {
params [ key ] = combineUrl ( window . location . href , source [ key ] ) ;
continue ;
}
params [ key ] = source [ key ] ;
}
workerInitializedPromise = new PDFJS . Promise ( ) ;
workerReadyPromise = new PDFJS . Promise ( ) ;
transport = new WorkerTransport ( workerInitializedPromise ,
workerReadyPromise , pdfDataRangeTransport , progressCallback ) ;
workerInitializedPromise . then ( function transportInitialized ( ) {
transport . passwordCallback = passwordCallback ;
transport . fetchDocument ( params ) ;
} ) ;
return workerReadyPromise ;
} ;
/ * *
* Proxy to a PDFDocument in the worker thread . Also , contains commonly used
* properties that can be read synchronously .
* /
var PDFDocumentProxy = ( function PDFDocumentProxyClosure ( ) {
function PDFDocumentProxy ( pdfInfo , transport ) {
this . pdfInfo = pdfInfo ;
this . transport = transport ;
}
PDFDocumentProxy . prototype = {
/ * *
* @ return { number } Total number of pages the PDF contains .
* /
get numPages ( ) {
return this . pdfInfo . numPages ;
} ,
/ * *
* @ return { string } A unique ID to identify a PDF . Not guaranteed to be
* unique .
* /
get fingerprint ( ) {
return this . pdfInfo . fingerprint ;
} ,
/ * *
* @ return { boolean } true if embedded document fonts are in use . Will be
* set during rendering of the pages .
* /
get embeddedFontsUsed ( ) {
return this . transport . embeddedFontsUsed ;
} ,
/ * *
* @ param { number } The page number to get . The first page is 1.
* @ return { Promise } A promise that is resolved with a { PDFPageProxy }
* object .
* /
getPage : function PDFDocumentProxy _getPage ( number ) {
return this . transport . getPage ( number ) ;
} ,
/ * *
* @ param { object } Must have 'num' and 'gen' properties .
* @ return { Promise } A promise that is resolved with the page index that is
* associated with the reference .
* /
getPageIndex : function PDFDocumentProxy _getPageIndex ( ref ) {
return this . transport . getPageIndex ( ref ) ;
} ,
/ * *
* @ return { Promise } A promise that is resolved with a lookup table for
* mapping named destinations to reference numbers .
* /
getDestinations : function PDFDocumentProxy _getDestinations ( ) {
return this . transport . getDestinations ( ) ;
} ,
/ * *
* @ return { Promise } A promise that is resolved with an array of all the
* JavaScript strings in the name tree .
* /
getJavaScript : function PDFDocumentProxy _getDestinations ( ) {
var promise = new PDFJS . Promise ( ) ;
var js = this . pdfInfo . javaScript ;
promise . resolve ( js ) ;
return promise ;
} ,
/ * *
* @ return { Promise } A promise that is resolved with an { array } that is a
* tree outline ( if it has one ) of the PDF . The tree is in the format of :
* [
* {
* title : string ,
* bold : boolean ,
* italic : boolean ,
* color : rgb array ,
* dest : dest obj ,
* items : array of more items like this
* } ,
* ...
* ] .
* /
getOutline : function PDFDocumentProxy _getOutline ( ) {
var promise = new PDFJS . Promise ( ) ;
var outline = this . pdfInfo . outline ;
promise . resolve ( outline ) ;
return promise ;
} ,
/ * *
* @ return { Promise } A promise that is resolved with an { object } that has
* info and metadata properties . Info is an { object } filled with anything
* available in the information dictionary and similarly metadata is a
* { Metadata } object with information from the metadata section of the PDF .
* /
getMetadata : function PDFDocumentProxy _getMetadata ( ) {
var promise = new PDFJS . Promise ( ) ;
var info = this . pdfInfo . info ;
var metadata = this . pdfInfo . metadata ;
promise . resolve ( {
info : info ,
metadata : metadata ? new PDFJS . Metadata ( metadata ) : null
} ) ;
return promise ;
} ,
isEncrypted : function PDFDocumentProxy _isEncrypted ( ) {
var promise = new PDFJS . Promise ( ) ;
promise . resolve ( this . pdfInfo . encrypted ) ;
return promise ;
} ,
/ * *
* @ return { Promise } A promise that is resolved with a TypedArray that has
* the raw data from the PDF .
* /
getData : function PDFDocumentProxy _getData ( ) {
var promise = new PDFJS . Promise ( ) ;
this . transport . getData ( promise ) ;
return promise ;
} ,
/ * *
* @ return { Promise } A promise that is resolved when the document ' s data
* is loaded
* /
dataLoaded : function PDFDocumentProxy _dataLoaded ( ) {
return this . transport . dataLoaded ( ) ;
} ,
cleanup : function PDFDocumentProxy _cleanup ( ) {
this . transport . startCleanup ( ) ;
} ,
destroy : function PDFDocumentProxy _destroy ( ) {
this . transport . destroy ( ) ;
}
} ;
return PDFDocumentProxy ;
} ) ( ) ;
var PDFPageProxy = ( function PDFPageProxyClosure ( ) {
function PDFPageProxy ( pageInfo , transport ) {
this . pageInfo = pageInfo ;
this . transport = transport ;
this . stats = new StatTimer ( ) ;
this . stats . enabled = ! ! globalScope . PDFJS . enableStats ;
this . commonObjs = transport . commonObjs ;
this . objs = new PDFObjects ( ) ;
this . receivingOperatorList = false ;
this . cleanupAfterRender = false ;
this . pendingDestroy = false ;
this . renderTasks = [ ] ;
}
PDFPageProxy . prototype = {
/ * *
* @ return { number } Page number of the page . First page is 1.
* /
get pageNumber ( ) {
return this . pageInfo . pageIndex + 1 ;
} ,
/ * *
* @ return { number } The number of degrees the page is rotated clockwise .
* /
get rotate ( ) {
return this . pageInfo . rotate ;
} ,
/ * *
* @ return { object } The reference that points to this page . It has 'num' and
* 'gen' properties .
* /
get ref ( ) {
return this . pageInfo . ref ;
} ,
/ * *
* @ return { array } An array of the visible portion of the PDF page in the
* user space units - [ x1 , y1 , x2 , y2 ] .
* /
get view ( ) {
return this . pageInfo . view ;
} ,
/ * *
* @ param { number } scale The desired scale of the viewport .
* @ param { number } rotate Degrees to rotate the viewport . If omitted this
* defaults to the page rotation .
* @ return { PageViewport } Contains 'width' and 'height' properties along
* with transforms required for rendering .
* /
getViewport : function PDFPageProxy _getViewport ( scale , rotate ) {
if ( arguments . length < 2 )
rotate = this . rotate ;
return new PDFJS . PageViewport ( this . view , scale , rotate , 0 , 0 ) ;
} ,
/ * *
* @ return { Promise } A promise that is resolved with an { array } of the
* annotation objects .
* /
getAnnotations : function PDFPageProxy _getAnnotations ( ) {
if ( this . annotationsPromise )
return this . annotationsPromise ;
var promise = new PDFJS . Promise ( ) ;
this . annotationsPromise = promise ;
this . transport . getAnnotations ( this . pageInfo . pageIndex ) ;
return promise ;
} ,
/ * *
* Begins the process of rendering a page to the desired context .
* @ param { object } params A parameter object that supports :
* {
* canvasContext ( required ) : A 2 D context of a DOM Canvas object . ,
* textLayer ( optional ) : An object that has beginLayout , endLayout , and
* appendText functions . ,
* imageLayer ( optional ) : An object that has beginLayout , endLayout and
* appendImage functions . ,
* continueCallback ( optional ) : A function that will be called each time
* the rendering is paused . To continue
* rendering call the function that is the
* first argument to the callback .
* } .
* @ return { RenderTask } An extended promise that is resolved when the page
* finishes rendering ( see RenderTask ) .
* /
render : function PDFPageProxy _render ( params ) {
var stats = this . stats ;
stats . time ( 'Overall' ) ;
// If there was a pending destroy cancel it so no cleanup happens during
// this call to render.
this . pendingDestroy = false ;
// If there is no displayReadyPromise yet, then the operatorList was never
// requested before. Make the request and create the promise.
if ( ! this . displayReadyPromise ) {
this . receivingOperatorList = true ;
this . displayReadyPromise = new Promise ( ) ;
this . operatorList = {
fnArray : [ ] ,
argsArray : [ ] ,
lastChunk : false
} ;
this . stats . time ( 'Page Request' ) ;
this . transport . messageHandler . send ( 'RenderPageRequest' , {
pageIndex : this . pageNumber - 1
} ) ;
}
var internalRenderTask = new InternalRenderTask ( complete , params ,
this . objs , this . commonObjs ,
this . operatorList , this . pageNumber ) ;
this . renderTasks . push ( internalRenderTask ) ;
var renderTask = new RenderTask ( internalRenderTask ) ;
var self = this ;
this . displayReadyPromise . then (
function pageDisplayReadyPromise ( transparency ) {
if ( self . pendingDestroy ) {
complete ( ) ;
return ;
}
stats . time ( 'Rendering' ) ;
internalRenderTask . initalizeGraphics ( transparency ) ;
internalRenderTask . operatorListChanged ( ) ;
} ,
function pageDisplayReadPromiseError ( reason ) {
complete ( reason ) ;
}
) ;
function complete ( error ) {
var i = self . renderTasks . indexOf ( internalRenderTask ) ;
if ( i >= 0 ) {
self . renderTasks . splice ( i , 1 ) ;
}
if ( self . cleanupAfterRender ) {
self . pendingDestroy = true ;
}
self . _tryDestroy ( ) ;
if ( error ) {
renderTask . reject ( error ) ;
} else {
renderTask . resolve ( ) ;
}
stats . timeEnd ( 'Rendering' ) ;
stats . timeEnd ( 'Overall' ) ;
}
return renderTask ;
} ,
/ * *
* @ return { Promise } That is resolved with the a { string } that is the text
* content from the page .
* /
getTextContent : function PDFPageProxy _getTextContent ( ) {
var promise = new PDFJS . Promise ( ) ;
this . transport . messageHandler . send ( 'GetTextContent' , {
pageIndex : this . pageNumber - 1
} ,
function textContentCallback ( textContent ) {
promise . resolve ( textContent ) ;
}
) ;
return promise ;
} ,
/ * *
* Stub for future feature .
* /
getOperationList : function PDFPageProxy _getOperationList ( ) {
var promise = new PDFJS . Promise ( ) ;
var operationList = { // not implemented
dependencyFontsID : null ,
operatorList : null
} ;
promise . resolve ( operationList ) ;
return promise ;
} ,
/ * *
* Destroys resources allocated by the page .
* /
destroy : function PDFPageProxy _destroy ( ) {
this . pendingDestroy = true ;
this . _tryDestroy ( ) ;
} ,
/ * *
* For internal use only . Attempts to clean up if rendering is in a state
* where that ' s possible .
* /
_tryDestroy : function PDFPageProxy _ _destroy ( ) {
if ( ! this . pendingDestroy ||
this . renderTasks . length !== 0 ||
this . receivingOperatorList ) {
return ;
}
delete this . operatorList ;
delete this . displayReadyPromise ;
this . objs . clear ( ) ;
this . pendingDestroy = false ;
} ,
/ * *
* For internal use only .
* /
_startRenderPage : function PDFPageProxy _startRenderPage ( transparency ) {
this . displayReadyPromise . resolve ( transparency ) ;
} ,
/ * *
* For internal use only .
* /
_renderPageChunk : function PDFPageProxy _renderPageChunk ( operatorListChunk ) {
// Add the new chunk to the current operator list.
for ( var i = 0 , ii = operatorListChunk . length ; i < ii ; i ++ ) {
this . operatorList . fnArray . push ( operatorListChunk . fnArray [ i ] ) ;
this . operatorList . argsArray . push ( operatorListChunk . argsArray [ i ] ) ;
}
this . operatorList . lastChunk = operatorListChunk . lastChunk ;
// Notify all the rendering tasks there are more operators to be consumed.
for ( var i = 0 ; i < this . renderTasks . length ; i ++ ) {
this . renderTasks [ i ] . operatorListChanged ( ) ;
}
if ( operatorListChunk . lastChunk ) {
this . receivingOperatorList = false ;
this . _tryDestroy ( ) ;
}
}
} ;
return PDFPageProxy ;
} ) ( ) ;
/ * *
* For internal use only .
* /
var WorkerTransport = ( function WorkerTransportClosure ( ) {
function WorkerTransport ( workerInitializedPromise , workerReadyPromise ,
pdfDataRangeTransport , progressCallback ) {
this . pdfDataRangeTransport = pdfDataRangeTransport ;
this . workerReadyPromise = workerReadyPromise ;
this . progressCallback = progressCallback ;
this . commonObjs = new PDFObjects ( ) ;
this . pageCache = [ ] ;
this . pagePromises = [ ] ;
this . embeddedFontsUsed = false ;
this . passwordCallback = null ;
// If worker support isn't disabled explicit and the browser has worker
// support, create a new web worker and test if it/the browser fullfills
// all requirements to run parts of pdf.js in a web worker.
// Right now, the requirement is, that an Uint8Array is still an Uint8Array
// as it arrives on the worker. Chrome added this with version 15.
if ( ! globalScope . PDFJS . disableWorker && typeof Worker !== 'undefined' ) {
var workerSrc = PDFJS . workerSrc ;
if ( ! workerSrc ) {
error ( 'No PDFJS.workerSrc specified' ) ;
}
try {
// Some versions of FF can't create a worker on localhost, see:
// https://bugzilla.mozilla.org/show_bug.cgi?id=683280
var worker = new Worker ( workerSrc ) ;
var messageHandler = new MessageHandler ( 'main' , worker ) ;
this . messageHandler = messageHandler ;
messageHandler . on ( 'test' , function transportTest ( data ) {
var supportTypedArray = data && data . supportTypedArray ;
if ( supportTypedArray ) {
this . worker = worker ;
if ( ! data . supportTransfers ) {
PDFJS . postMessageTransfers = false ;
}
this . setupMessageHandler ( messageHandler ) ;
workerInitializedPromise . resolve ( ) ;
} else {
globalScope . PDFJS . disableWorker = true ;
this . loadFakeWorkerFiles ( ) . then ( function ( ) {
this . setupFakeWorker ( ) ;
workerInitializedPromise . resolve ( ) ;
} . bind ( this ) ) ;
}
} . bind ( this ) ) ;
var testObj = new Uint8Array ( [ PDFJS . postMessageTransfers ? 255 : 0 ] ) ;
// Some versions of Opera throw a DATA_CLONE_ERR on serializing the
// typed array. Also, checking if we can use transfers.
try {
messageHandler . send ( 'test' , testObj , null , [ testObj . buffer ] ) ;
} catch ( ex ) {
info ( 'Cannot use postMessage transfers' ) ;
testObj [ 0 ] = 0 ;
messageHandler . send ( 'test' , testObj ) ;
}
return ;
} catch ( e ) {
info ( 'The worker has been disabled.' ) ;
}
}
// Either workers are disabled, not supported or have thrown an exception.
// Thus, we fallback to a faked worker.
globalScope . PDFJS . disableWorker = true ;
this . loadFakeWorkerFiles ( ) . then ( function ( ) {
this . setupFakeWorker ( ) ;
workerInitializedPromise . resolve ( ) ;
} . bind ( this ) ) ;
}
WorkerTransport . prototype = {
destroy : function WorkerTransport _destroy ( ) {
this . pageCache = [ ] ;
this . pagePromises = [ ] ;
var self = this ;
this . messageHandler . send ( 'Terminate' , null , function ( ) {
if ( self . worker ) {
self . worker . terminate ( ) ;
}
} ) ;
} ,
loadFakeWorkerFiles : function WorkerTransport _loadFakeWorkerFiles ( ) {
if ( ! PDFJS . fakeWorkerFilesLoadedPromise ) {
PDFJS . fakeWorkerFilesLoadedPromise = new Promise ( ) ;
// In the developer build load worker_loader which in turn loads all the
// other files and resolves the promise. In production only the
// pdf.worker.js file is needed.
Util . loadScript ( PDFJS . workerSrc , function ( ) {
PDFJS . fakeWorkerFilesLoadedPromise . resolve ( ) ;
} ) ;
}
return PDFJS . fakeWorkerFilesLoadedPromise ;
} ,
setupFakeWorker : function WorkerTransport _setupFakeWorker ( ) {
warn ( 'Setting up fake worker.' ) ;
// If we don't use a worker, just post/sendMessage to the main thread.
var fakeWorker = {
postMessage : function WorkerTransport _postMessage ( obj ) {
fakeWorker . onmessage ( { data : obj } ) ;
} ,
terminate : function WorkerTransport _terminate ( ) { }
} ;
var messageHandler = new MessageHandler ( 'main' , fakeWorker ) ;
this . setupMessageHandler ( messageHandler ) ;
// If the main thread is our worker, setup the handling for the messages
// the main thread sends to it self.
PDFJS . WorkerMessageHandler . setup ( messageHandler ) ;
} ,
setupMessageHandler :
function WorkerTransport _setupMessageHandler ( messageHandler ) {
this . messageHandler = messageHandler ;
function updatePassword ( password ) {
messageHandler . send ( 'UpdatePassword' , password ) ;
}
var pdfDataRangeTransport = this . pdfDataRangeTransport ;
if ( pdfDataRangeTransport ) {
pdfDataRangeTransport . addRangeListener ( function ( begin , chunk ) {
messageHandler . send ( 'OnDataRange' , {
begin : begin ,
chunk : chunk
} ) ;
} ) ;
pdfDataRangeTransport . addProgressListener ( function ( loaded ) {
messageHandler . send ( 'OnDataProgress' , {
loaded : loaded
} ) ;
} ) ;
messageHandler . on ( 'RequestDataRange' ,
function transportDataRange ( data ) {
pdfDataRangeTransport . requestDataRange ( data . begin , data . end ) ;
} , this ) ;
}
messageHandler . on ( 'GetDoc' , function transportDoc ( data ) {
var pdfInfo = data . pdfInfo ;
var pdfDocument = new PDFDocumentProxy ( pdfInfo , this ) ;
this . pdfDocument = pdfDocument ;
this . workerReadyPromise . resolve ( pdfDocument ) ;
} , this ) ;
messageHandler . on ( 'NeedPassword' , function transportPassword ( data ) {
if ( this . passwordCallback ) {
return this . passwordCallback ( updatePassword ,
PasswordResponses . NEED _PASSWORD ) ;
}
this . workerReadyPromise . reject ( data . exception . message , data . exception ) ;
} , this ) ;
messageHandler . on ( 'IncorrectPassword' , function transportBadPass ( data ) {
if ( this . passwordCallback ) {
return this . passwordCallback ( updatePassword ,
PasswordResponses . INCORRECT _PASSWORD ) ;
}
this . workerReadyPromise . reject ( data . exception . message , data . exception ) ;
} , this ) ;
messageHandler . on ( 'InvalidPDF' , function transportInvalidPDF ( data ) {
this . workerReadyPromise . reject ( data . exception . name , data . exception ) ;
} , this ) ;
messageHandler . on ( 'MissingPDF' , function transportMissingPDF ( data ) {
this . workerReadyPromise . reject ( data . exception . message , data . exception ) ;
} , this ) ;
messageHandler . on ( 'UnknownError' , function transportUnknownError ( data ) {
this . workerReadyPromise . reject ( data . exception . message , data . exception ) ;
} , this ) ;
messageHandler . on ( 'GetPage' , function transportPage ( data ) {
var pageInfo = data . pageInfo ;
var page = new PDFPageProxy ( pageInfo , this ) ;
this . pageCache [ pageInfo . pageIndex ] = page ;
var promise = this . pagePromises [ pageInfo . pageIndex ] ;
promise . resolve ( page ) ;
} , this ) ;
messageHandler . on ( 'GetAnnotations' , function transportAnnotations ( data ) {
var annotations = data . annotations ;
var promise = this . pageCache [ data . pageIndex ] . annotationsPromise ;
promise . resolve ( annotations ) ;
} , this ) ;
messageHandler . on ( 'StartRenderPage' , function transportRender ( data ) {
var page = this . pageCache [ data . pageIndex ] ;
page . stats . timeEnd ( 'Page Request' ) ;
page . _startRenderPage ( data . transparency ) ;
} , this ) ;
messageHandler . on ( 'RenderPageChunk' , function transportRender ( data ) {
var page = this . pageCache [ data . pageIndex ] ;
page . _renderPageChunk ( data . operatorList ) ;
} , this ) ;
messageHandler . on ( 'commonobj' , function transportObj ( data ) {
var id = data [ 0 ] ;
var type = data [ 1 ] ;
if ( this . commonObjs . hasData ( id ) )
return ;
switch ( type ) {
case 'Font' :
var exportedData = data [ 2 ] ;
var font ;
if ( 'error' in exportedData ) {
var error = exportedData . error ;
warn ( 'Error during font loading: ' + error ) ;
this . commonObjs . resolve ( id , error ) ;
break ;
} else {
font = new FontFace ( exportedData ) ;
}
FontLoader . bind (
[ font ] ,
function fontReady ( fontObjs ) {
this . commonObjs . resolve ( id , font ) ;
} . bind ( this )
) ;
break ;
case 'FontPath' :
this . commonObjs . resolve ( id , data [ 2 ] ) ;
break ;
default :
error ( 'Got unknown common object type ' + type ) ;
}
} , this ) ;
messageHandler . on ( 'obj' , function transportObj ( data ) {
var id = data [ 0 ] ;
var pageIndex = data [ 1 ] ;
var type = data [ 2 ] ;
var pageProxy = this . pageCache [ pageIndex ] ;
if ( pageProxy . objs . hasData ( id ) )
return ;
switch ( type ) {
case 'JpegStream' :
var imageData = data [ 3 ] ;
loadJpegStream ( id , imageData , pageProxy . objs ) ;
break ;
case 'Image' :
var imageData = data [ 3 ] ;
pageProxy . objs . resolve ( id , imageData ) ;
// heuristics that will allow not to store large data
var MAX _IMAGE _SIZE _TO _STORE = 8000000 ;
if ( 'data' in imageData &&
imageData . data . length > MAX _IMAGE _SIZE _TO _STORE ) {
pageProxy . cleanupAfterRender = true ;
}
break ;
default :
error ( 'Got unknown object type ' + type ) ;
}
} , this ) ;
messageHandler . on ( 'DocProgress' , function transportDocProgress ( data ) {
if ( this . progressCallback ) {
this . progressCallback ( {
loaded : data . loaded ,
total : data . total
} ) ;
}
} , this ) ;
messageHandler . on ( 'DocError' , function transportDocError ( data ) {
this . workerReadyPromise . reject ( data ) ;
} , this ) ;
messageHandler . on ( 'PageError' , function transportError ( data ) {
var page = this . pageCache [ data . pageNum - 1 ] ;
if ( page . displayReadyPromise )
page . displayReadyPromise . reject ( data . error ) ;
else
error ( data . error ) ;
} , this ) ;
messageHandler . on ( 'JpegDecode' , function ( data , promise ) {
var imageUrl = data [ 0 ] ;
var components = data [ 1 ] ;
if ( components != 3 && components != 1 )
error ( 'Only 3 component or 1 component can be returned' ) ;
var img = new Image ( ) ;
img . onload = ( function messageHandler _onloadClosure ( ) {
var width = img . width ;
var height = img . height ;
var size = width * height ;
var rgbaLength = size * 4 ;
var buf = new Uint8Array ( size * components ) ;
var tmpCanvas = createScratchCanvas ( width , height ) ;
var tmpCtx = tmpCanvas . getContext ( '2d' ) ;
tmpCtx . drawImage ( img , 0 , 0 ) ;
var data = tmpCtx . getImageData ( 0 , 0 , width , height ) . data ;
if ( components == 3 ) {
for ( var i = 0 , j = 0 ; i < rgbaLength ; i += 4 , j += 3 ) {
buf [ j ] = data [ i ] ;
buf [ j + 1 ] = data [ i + 1 ] ;
buf [ j + 2 ] = data [ i + 2 ] ;
}
} else if ( components == 1 ) {
for ( var i = 0 , j = 0 ; i < rgbaLength ; i += 4 , j ++ ) {
buf [ j ] = data [ i ] ;
}
}
promise . resolve ( { data : buf , width : width , height : height } ) ;
} ) . bind ( this ) ;
img . src = imageUrl ;
} ) ;
} ,
fetchDocument : function WorkerTransport _fetchDocument ( source ) {
source . disableAutoFetch = PDFJS . disableAutoFetch ;
source . chunkedViewerLoading = ! ! this . pdfDataRangeTransport ;
this . messageHandler . send ( 'GetDocRequest' , {
source : source ,
disableRange : PDFJS . disableRange ,
maxImageSize : PDFJS . maxImageSize ,
disableFontFace : PDFJS . disableFontFace
} ) ;
} ,
getData : function WorkerTransport _getData ( promise ) {
this . messageHandler . send ( 'GetData' , null , function ( data ) {
promise . resolve ( data ) ;
} ) ;
} ,
dataLoaded : function WorkerTransport _dataLoaded ( ) {
var promise = new PDFJS . Promise ( ) ;
this . messageHandler . send ( 'DataLoaded' , null , function ( args ) {
promise . resolve ( args ) ;
} ) ;
return promise ;
} ,
getPage : function WorkerTransport _getPage ( pageNumber , promise ) {
var pageIndex = pageNumber - 1 ;
if ( pageIndex in this . pagePromises )
return this . pagePromises [ pageIndex ] ;
var promise = new PDFJS . Promise ( 'Page ' + pageNumber ) ;
this . pagePromises [ pageIndex ] = promise ;
this . messageHandler . send ( 'GetPageRequest' , { pageIndex : pageIndex } ) ;
return promise ;
} ,
getPageIndex : function WorkerTransport _getPageIndexByRef ( ref ) {
var promise = new PDFJS . Promise ( ) ;
this . messageHandler . send ( 'GetPageIndex' , { ref : ref } ,
function ( pageIndex ) {
promise . resolve ( pageIndex ) ;
}
) ;
return promise ;
} ,
getAnnotations : function WorkerTransport _getAnnotations ( pageIndex ) {
this . messageHandler . send ( 'GetAnnotationsRequest' ,
{ pageIndex : pageIndex } ) ;
} ,
getDestinations : function WorkerTransport _getDestinations ( ) {
var promise = new PDFJS . Promise ( ) ;
this . messageHandler . send ( 'GetDestinations' , null ,
function transportDestinations ( destinations ) {
promise . resolve ( destinations ) ;
}
) ;
return promise ;
} ,
startCleanup : function WorkerTransport _startCleanup ( ) {
this . messageHandler . send ( 'Cleanup' , null ,
function endCleanup ( ) {
for ( var i = 0 , ii = this . pageCache . length ; i < ii ; i ++ ) {
var page = this . pageCache [ i ] ;
if ( page ) {
page . destroy ( ) ;
}
}
this . commonObjs . clear ( ) ;
FontLoader . clear ( ) ;
} . bind ( this )
) ;
}
} ;
return WorkerTransport ;
} ) ( ) ;
/ * *
* A PDF document and page is built of many objects . E . g . there are objects
* for fonts , images , rendering code and such . These objects might get processed
* inside of a worker . The ` PDFObjects ` implements some basic functions to
* manage these objects .
* /
var PDFObjects = ( function PDFObjectsClosure ( ) {
function PDFObjects ( ) {
this . objs = { } ;
}
PDFObjects . prototype = {
/ * *
* Internal function .
* Ensures there is an object defined for ` objId ` .
* /
ensureObj : function PDFObjects _ensureObj ( objId ) {
if ( this . objs [ objId ] )
return this . objs [ objId ] ;
var obj = {
promise : new Promise ( objId ) ,
data : null ,
resolved : false
} ;
this . objs [ objId ] = obj ;
return obj ;
} ,
/ * *
* If called * without * callback , this returns the data of ` objId ` but the
* object needs to be resolved . If it isn ' t , this function throws .
*
* If called * with * a callback , the callback is called with the data of the
* object once the object is resolved . That means , if you call this
* function and the object is already resolved , the callback gets called
* right away .
* /
get : function PDFObjects _get ( objId , callback ) {
// If there is a callback, then the get can be async and the object is
// not required to be resolved right now
if ( callback ) {
this . ensureObj ( objId ) . promise . then ( callback ) ;
return null ;
}
// If there isn't a callback, the user expects to get the resolved data
// directly.
var obj = this . objs [ objId ] ;
// If there isn't an object yet or the object isn't resolved, then the
// data isn't ready yet!
if ( ! obj || ! obj . resolved )
error ( 'Requesting object that isn\'t resolved yet ' + objId ) ;
return obj . data ;
} ,
/ * *
* Resolves the object ` objId ` with optional ` data ` .
* /
resolve : function PDFObjects _resolve ( objId , data ) {
var obj = this . ensureObj ( objId ) ;
obj . resolved = true ;
obj . data = data ;
obj . promise . resolve ( data ) ;
} ,
isResolved : function PDFObjects _isResolved ( objId ) {
var objs = this . objs ;
if ( ! objs [ objId ] ) {
return false ;
} else {
return objs [ objId ] . resolved ;
}
} ,
hasData : function PDFObjects _hasData ( objId ) {
return this . isResolved ( objId ) ;
} ,
/ * *
* Returns the data of ` objId ` if object exists , null otherwise .
* /
getData : function PDFObjects _getData ( objId ) {
var objs = this . objs ;
if ( ! objs [ objId ] || ! objs [ objId ] . resolved ) {
return null ;
} else {
return objs [ objId ] . data ;
}
} ,
clear : function PDFObjects _clear ( ) {
this . objs = { } ;
}
} ;
return PDFObjects ;
} ) ( ) ;
/ *
* RenderTask is basically a promise but adds a cancel function to terminate it .
* /
var RenderTask = ( function RenderTaskClosure ( ) {
function RenderTask ( internalRenderTask ) {
this . internalRenderTask = internalRenderTask ;
Promise . call ( this ) ;
}
RenderTask . prototype = Object . create ( Promise . prototype ) ;
/ * *
* Cancel the rendering task . If the task is curently rendering it will not be
* cancelled until graphics pauses with a timeout . The promise that this
* object extends will resolved when cancelled .
* /
RenderTask . prototype . cancel = function RenderTask _cancel ( ) {
this . internalRenderTask . cancel ( ) ;
} ;
return RenderTask ;
} ) ( ) ;
var InternalRenderTask = ( function InternalRenderTaskClosure ( ) {
function InternalRenderTask ( callback , params , objs , commonObjs , operatorList ,
pageNumber ) {
this . callback = callback ;
this . params = params ;
this . objs = objs ;
this . commonObjs = commonObjs ;
this . operatorListIdx = null ;
this . operatorList = operatorList ;
this . pageNumber = pageNumber ;
this . running = false ;
this . graphicsReadyCallback = null ;
this . graphicsReady = false ;
this . cancelled = false ;
}
InternalRenderTask . prototype = {
initalizeGraphics :
function InternalRenderTask _initalizeGraphics ( transparency ) {
if ( this . cancelled ) {
return ;
}
if ( PDFJS . pdfBug && 'StepperManager' in globalScope &&
globalScope . StepperManager . enabled ) {
this . stepper = globalScope . StepperManager . create ( this . pageNumber - 1 ) ;
this . stepper . init ( this . operatorList ) ;
this . stepper . nextBreakPoint = this . stepper . getNextBreakPoint ( ) ;
}
var params = this . params ;
this . gfx = new CanvasGraphics ( params . canvasContext , this . commonObjs ,
this . objs , params . textLayer ,
params . imageLayer ) ;
this . gfx . beginDrawing ( params . viewport , transparency ) ;
this . operatorListIdx = 0 ;
this . graphicsReady = true ;
if ( this . graphicsReadyCallback ) {
this . graphicsReadyCallback ( ) ;
}
} ,
cancel : function InternalRenderTask _cancel ( ) {
this . running = false ;
this . cancelled = true ;
this . callback ( 'cancelled' ) ;
} ,
operatorListChanged : function InternalRenderTask _operatorListChanged ( ) {
if ( ! this . graphicsReady ) {
if ( ! this . graphicsReadyCallback ) {
this . graphicsReadyCallback = this . _continue . bind ( this ) ;
}
return ;
}
if ( this . stepper ) {
this . stepper . updateOperatorList ( this . operatorList ) ;
}
if ( this . running ) {
return ;
}
this . _continue ( ) ;
} ,
_continue : function InternalRenderTask _ _continue ( ) {
this . running = true ;
if ( this . cancelled ) {
return ;
}
if ( this . params . continueCallback ) {
this . params . continueCallback ( this . _next . bind ( this ) ) ;
} else {
this . _next ( ) ;
}
} ,
_next : function InternalRenderTask _ _next ( ) {
if ( this . cancelled ) {
return ;
}
this . operatorListIdx = this . gfx . executeOperatorList ( this . operatorList ,
this . operatorListIdx ,
this . _continue . bind ( this ) ,
this . stepper ) ;
if ( this . operatorListIdx === this . operatorList . argsArray . length ) {
this . running = false ;
if ( this . operatorList . lastChunk ) {
this . gfx . endDrawing ( ) ;
this . callback ( ) ;
}
}
}
} ;
return InternalRenderTask ;
} ) ( ) ;
var Metadata = PDFJS . Metadata = ( function MetadataClosure ( ) {
function fixMetadata ( meta ) {
return meta . replace ( />\\376\\377([^<]+)/g , function ( all , codes ) {
var bytes = codes . replace ( /\\([0-3])([0-7])([0-7])/g ,
function ( code , d1 , d2 , d3 ) {
return String . fromCharCode ( d1 * 64 + d2 * 8 + d3 * 1 ) ;
} ) ;
var chars = '' ;
for ( var i = 0 ; i < bytes . length ; i += 2 ) {
var code = bytes . charCodeAt ( i ) * 256 + bytes . charCodeAt ( i + 1 ) ;
chars += code >= 32 && code < 127 && code != 60 && code != 62 &&
code != 38 && false ? String . fromCharCode ( code ) :
'&#x' + ( 0x10000 + code ) . toString ( 16 ) . substring ( 1 ) + ';' ;
}
return '>' + chars ;
} ) ;
}
function Metadata ( meta ) {
if ( typeof meta === 'string' ) {
// Ghostscript produces invalid metadata
meta = fixMetadata ( meta ) ;
var parser = new DOMParser ( ) ;
meta = parser . parseFromString ( meta , 'application/xml' ) ;
} else if ( ! ( meta instanceof Document ) ) {
error ( 'Metadata: Invalid metadata object' ) ;
}
this . metaDocument = meta ;
this . metadata = { } ;
this . parse ( ) ;
}
Metadata . prototype = {
parse : function Metadata _parse ( ) {
var doc = this . metaDocument ;
var rdf = doc . documentElement ;
if ( rdf . nodeName . toLowerCase ( ) !== 'rdf:rdf' ) { // Wrapped in <xmpmeta>
rdf = rdf . firstChild ;
while ( rdf && rdf . nodeName . toLowerCase ( ) !== 'rdf:rdf' )
rdf = rdf . nextSibling ;
}
var nodeName = ( rdf ) ? rdf . nodeName . toLowerCase ( ) : null ;
if ( ! rdf || nodeName !== 'rdf:rdf' || ! rdf . hasChildNodes ( ) )
return ;
var children = rdf . childNodes , desc , entry , name , i , ii , length , iLength ;
for ( i = 0 , length = children . length ; i < length ; i ++ ) {
desc = children [ i ] ;
if ( desc . nodeName . toLowerCase ( ) !== 'rdf:description' )
continue ;
for ( ii = 0 , iLength = desc . childNodes . length ; ii < iLength ; ii ++ ) {
if ( desc . childNodes [ ii ] . nodeName . toLowerCase ( ) !== '#text' ) {
entry = desc . childNodes [ ii ] ;
name = entry . nodeName . toLowerCase ( ) ;
this . metadata [ name ] = entry . textContent . trim ( ) ;
}
}
}
} ,
get : function Metadata _get ( name ) {
return this . metadata [ name ] || null ;
} ,
has : function Metadata _has ( name ) {
return typeof this . metadata [ name ] !== 'undefined' ;
}
} ;
return Metadata ;
} ) ( ) ;
// <canvas> contexts store most of the state we need natively.
// However, PDF needs a bit more state, which we store here.
// Minimal font size that would be used during canvas fillText operations.
var MIN _FONT _SIZE = 16 ;
var COMPILE _TYPE3 _GLYPHS = true ;
function createScratchCanvas ( width , height ) {
var canvas = document . createElement ( 'canvas' ) ;
canvas . width = width ;
canvas . height = height ;
return canvas ;
}
function addContextCurrentTransform ( ctx ) {
// If the context doesn't expose a `mozCurrentTransform`, add a JS based on.
if ( ! ctx . mozCurrentTransform ) {
// Store the original context
ctx . _scaleX = ctx . _scaleX || 1.0 ;
ctx . _scaleY = ctx . _scaleY || 1.0 ;
ctx . _originalSave = ctx . save ;
ctx . _originalRestore = ctx . restore ;
ctx . _originalRotate = ctx . rotate ;
ctx . _originalScale = ctx . scale ;
ctx . _originalTranslate = ctx . translate ;
ctx . _originalTransform = ctx . transform ;
ctx . _originalSetTransform = ctx . setTransform ;
ctx . _transformMatrix = [ ctx . _scaleX , 0 , 0 , ctx . _scaleY , 0 , 0 ] ;
ctx . _transformStack = [ ] ;
Object . defineProperty ( ctx , 'mozCurrentTransform' , {
get : function getCurrentTransform ( ) {
return this . _transformMatrix ;
}
} ) ;
Object . defineProperty ( ctx , 'mozCurrentTransformInverse' , {
get : function getCurrentTransformInverse ( ) {
// Calculation done using WolframAlpha:
// http://www.wolframalpha.com/input/?
// i=Inverse+{{a%2C+c%2C+e}%2C+{b%2C+d%2C+f}%2C+{0%2C+0%2C+1}}
var m = this . _transformMatrix ;
var a = m [ 0 ] , b = m [ 1 ] , c = m [ 2 ] , d = m [ 3 ] , e = m [ 4 ] , f = m [ 5 ] ;
var ad _bc = a * d - b * c ;
var bc _ad = b * c - a * d ;
return [
d / ad _bc ,
b / bc _ad ,
c / bc _ad ,
a / ad _bc ,
( d * e - c * f ) / bc _ad ,
( b * e - a * f ) / ad _bc
] ;
}
} ) ;
ctx . save = function ctxSave ( ) {
var old = this . _transformMatrix ;
this . _transformStack . push ( old ) ;
this . _transformMatrix = old . slice ( 0 , 6 ) ;
this . _originalSave ( ) ;
} ;
ctx . restore = function ctxRestore ( ) {
var prev = this . _transformStack . pop ( ) ;
if ( prev ) {
this . _transformMatrix = prev ;
this . _originalRestore ( ) ;
}
} ;
ctx . translate = function ctxTranslate ( x , y ) {
var m = this . _transformMatrix ;
m [ 4 ] = m [ 0 ] * x + m [ 2 ] * y + m [ 4 ] ;
m [ 5 ] = m [ 1 ] * x + m [ 3 ] * y + m [ 5 ] ;
this . _originalTranslate ( x , y ) ;
} ;
ctx . scale = function ctxScale ( x , y ) {
var m = this . _transformMatrix ;
m [ 0 ] = m [ 0 ] * x ;
m [ 1 ] = m [ 1 ] * x ;
m [ 2 ] = m [ 2 ] * y ;
m [ 3 ] = m [ 3 ] * y ;
this . _originalScale ( x , y ) ;
} ;
ctx . transform = function ctxTransform ( a , b , c , d , e , f ) {
var m = this . _transformMatrix ;
this . _transformMatrix = [
m [ 0 ] * a + m [ 2 ] * b ,
m [ 1 ] * a + m [ 3 ] * b ,
m [ 0 ] * c + m [ 2 ] * d ,
m [ 1 ] * c + m [ 3 ] * d ,
m [ 0 ] * e + m [ 2 ] * f + m [ 4 ] ,
m [ 1 ] * e + m [ 3 ] * f + m [ 5 ]
] ;
ctx . _originalTransform ( a , b , c , d , e , f ) ;
} ;
ctx . setTransform = function ctxSetTransform ( a , b , c , d , e , f ) {
this . _transformMatrix = [ a , b , c , d , e , f ] ;
ctx . _originalSetTransform ( a , b , c , d , e , f ) ;
} ;
ctx . rotate = function ctxRotate ( angle ) {
var cosValue = Math . cos ( angle ) ;
var sinValue = Math . sin ( angle ) ;
var m = this . _transformMatrix ;
this . _transformMatrix = [
m [ 0 ] * cosValue + m [ 2 ] * sinValue ,
m [ 1 ] * cosValue + m [ 3 ] * sinValue ,
m [ 0 ] * ( - sinValue ) + m [ 2 ] * cosValue ,
m [ 1 ] * ( - sinValue ) + m [ 3 ] * cosValue ,
m [ 4 ] ,
m [ 5 ]
] ;
this . _originalRotate ( angle ) ;
} ;
}
}
var CachedCanvases = ( function CachedCanvasesClosure ( ) {
var cache = { } ;
return {
getCanvas : function CachedCanvases _getCanvas ( id , width , height ,
trackTransform ) {
var canvasEntry ;
if ( id in cache ) {
canvasEntry = cache [ id ] ;
canvasEntry . canvas . width = width ;
canvasEntry . canvas . height = height ;
// reset canvas transform for emulated mozCurrentTransform, if needed
canvasEntry . context . setTransform ( 1 , 0 , 0 , 1 , 0 , 0 ) ;
} else {
var canvas = createScratchCanvas ( width , height ) ;
var ctx = canvas . getContext ( '2d' ) ;
if ( trackTransform ) {
addContextCurrentTransform ( ctx ) ;
}
cache [ id ] = canvasEntry = { canvas : canvas , context : ctx } ;
}
return canvasEntry ;
} ,
clear : function ( ) {
cache = { } ;
}
} ;
} ) ( ) ;
function compileType3Glyph ( imgData ) {
var POINT _TO _PROCESS _LIMIT = 1000 ;
var width = imgData . width , height = imgData . height ;
var i , j , j0 , width1 = width + 1 ;
var points = new Uint8Array ( width1 * ( height + 1 ) ) ;
var POINT _TYPES =
new Uint8Array ( [ 0 , 2 , 4 , 0 , 1 , 0 , 5 , 4 , 8 , 10 , 0 , 8 , 0 , 2 , 1 , 0 ] ) ;
// finding iteresting points: every point is located between mask pixels,
// so there will be points of the (width + 1)x(height + 1) grid. Every point
// will have flags assigned based on neighboring mask pixels:
// 4 | 8
// --P--
// 2 | 1
// We are interested only in points with the flags:
// - outside corners: 1, 2, 4, 8;
// - inside corners: 7, 11, 13, 14;
// - and, intersections: 5, 10.
var pos = 3 , data = imgData . data , lineSize = width * 4 , count = 0 ;
if ( data [ 3 ] !== 0 ) {
points [ 0 ] = 1 ;
++ count ;
}
for ( j = 1 ; j < width ; j ++ ) {
if ( data [ pos ] !== data [ pos + 4 ] ) {
points [ j ] = data [ pos ] ? 2 : 1 ;
++ count ;
}
pos += 4 ;
}
if ( data [ pos ] !== 0 ) {
points [ j ] = 2 ;
++ count ;
}
pos += 4 ;
for ( i = 1 ; i < height ; i ++ ) {
j0 = i * width1 ;
if ( data [ pos - lineSize ] !== data [ pos ] ) {
points [ j0 ] = data [ pos ] ? 1 : 8 ;
++ count ;
}
// 'sum' is the position of the current pixel configuration in the 'TYPES'
// array (in order 8-1-2-4, so we can use '>>2' to shift the column).
var sum = ( data [ pos ] ? 4 : 0 ) + ( data [ pos - lineSize ] ? 8 : 0 ) ;
for ( j = 1 ; j < width ; j ++ ) {
sum = ( sum >> 2 ) + ( data [ pos + 4 ] ? 4 : 0 ) +
( data [ pos - lineSize + 4 ] ? 8 : 0 ) ;
if ( POINT _TYPES [ sum ] ) {
points [ j0 + j ] = POINT _TYPES [ sum ] ;
++ count ;
}
pos += 4 ;
}
if ( data [ pos - lineSize ] !== data [ pos ] ) {
points [ j0 + j ] = data [ pos ] ? 2 : 4 ;
++ count ;
}
pos += 4 ;
if ( count > POINT _TO _PROCESS _LIMIT ) {
return null ;
}
}
pos -= lineSize ;
j0 = i * width1 ;
if ( data [ pos ] !== 0 ) {
points [ j0 ] = 8 ;
++ count ;
}
for ( j = 1 ; j < width ; j ++ ) {
if ( data [ pos ] !== data [ pos + 4 ] ) {
points [ j0 + j ] = data [ pos ] ? 4 : 8 ;
++ count ;
}
pos += 4 ;
}
if ( data [ pos ] !== 0 ) {
points [ j0 + j ] = 4 ;
++ count ;
}
if ( count > POINT _TO _PROCESS _LIMIT ) {
return null ;
}
// building outlines
var steps = new Int32Array ( [ 0 , width1 , - 1 , 0 , - width1 , 0 , 0 , 0 , 1 ] ) ;
var outlines = [ ] ;
for ( i = 0 ; count && i <= height ; i ++ ) {
var p = i * width1 ;
var end = p + width ;
while ( p < end && ! points [ p ] ) {
p ++ ;
}
if ( p === end ) {
continue ;
}
var coords = [ p % width1 , i ] ;
var type = points [ p ] , p0 = p , pp ;
do {
var step = steps [ type ] ;
do { p += step ; } while ( ! points [ p ] ) ;
pp = points [ p ] ;
if ( pp !== 5 && pp !== 10 ) {
// set new direction
type = pp ;
// delete mark
points [ p ] = 0 ;
} else { // type is 5 or 10, ie, a crossing
// set new direction
type = pp & ( ( 0x33 * type ) >> 4 ) ;
// set new type for "future hit"
points [ p ] &= ( type >> 2 | type << 2 ) ;
}
coords . push ( p % width1 ) ;
coords . push ( ( p / width1 ) | 0 ) ;
-- count ;
} while ( p0 !== p ) ;
outlines . push ( coords ) ;
-- i ;
}
var drawOutline = function ( c ) {
c . save ( ) ;
// the path shall be painted in [0..1]x[0..1] space
c . scale ( 1 / width , - 1 / height ) ;
c . translate ( 0 , - height ) ;
c . beginPath ( ) ;
for ( var i = 0 , ii = outlines . length ; i < ii ; i ++ ) {
var o = outlines [ i ] ;
c . moveTo ( o [ 0 ] , o [ 1 ] ) ;
for ( var j = 2 , jj = o . length ; j < jj ; j += 2 ) {
c . lineTo ( o [ j ] , o [ j + 1 ] ) ;
}
}
c . fill ( ) ;
c . beginPath ( ) ;
c . restore ( ) ;
} ;
return drawOutline ;
}
var CanvasExtraState = ( function CanvasExtraStateClosure ( ) {
function CanvasExtraState ( old ) {
// Are soft masks and alpha values shapes or opacities?
this . alphaIsShape = false ;
this . fontSize = 0 ;
this . fontSizeScale = 1 ;
this . textMatrix = IDENTITY _MATRIX ;
this . fontMatrix = FONT _IDENTITY _MATRIX ;
this . leading = 0 ;
// Current point (in user coordinates)
this . x = 0 ;
this . y = 0 ;
// Start of text line (in text coordinates)
this . lineX = 0 ;
this . lineY = 0 ;
// Character and word spacing
this . charSpacing = 0 ;
this . wordSpacing = 0 ;
this . textHScale = 1 ;
this . textRenderingMode = TextRenderingMode . FILL ;
this . textRise = 0 ;
// Color spaces
this . fillColorSpace = ColorSpace . singletons . gray ;
this . fillColorSpaceObj = null ;
this . strokeColorSpace = ColorSpace . singletons . gray ;
this . strokeColorSpaceObj = null ;
this . fillColorObj = null ;
this . strokeColorObj = null ;
// Default fore and background colors
this . fillColor = '#000000' ;
this . strokeColor = '#000000' ;
// Note: fill alpha applies to all non-stroking operations
this . fillAlpha = 1 ;
this . strokeAlpha = 1 ;
this . lineWidth = 1 ;
this . paintFormXObjectDepth = 0 ;
this . old = old ;
}
CanvasExtraState . prototype = {
clone : function CanvasExtraState _clone ( ) {
return Object . create ( this ) ;
} ,
setCurrentPoint : function CanvasExtraState _setCurrentPoint ( x , y ) {
this . x = x ;
this . y = y ;
}
} ;
return CanvasExtraState ;
} ) ( ) ;
var CanvasGraphics = ( function CanvasGraphicsClosure ( ) {
// Defines the time the executeOperatorList is going to be executing
// before it stops and shedules a continue of execution.
var EXECUTION _TIME = 15 ;
function CanvasGraphics ( canvasCtx , commonObjs , objs , textLayer , imageLayer ) {
this . ctx = canvasCtx ;
this . current = new CanvasExtraState ( ) ;
this . stateStack = [ ] ;
this . pendingClip = null ;
this . pendingEOFill = false ;
this . res = null ;
this . xobjs = null ;
this . commonObjs = commonObjs ;
this . objs = objs ;
this . textLayer = textLayer ;
this . imageLayer = imageLayer ;
this . groupStack = [ ] ;
this . processingType3 = null ;
// Patterns are painted relative to the initial page/form transform, see pdf
// spec 8.7.2 NOTE 1.
this . baseTransform = null ;
this . baseTransformStack = [ ] ;
this . groupLevel = 0 ;
if ( canvasCtx ) {
addContextCurrentTransform ( canvasCtx ) ;
}
}
function putBinaryImageData ( ctx , imgData ) {
if ( typeof ImageData !== 'undefined' && imgData instanceof ImageData ) {
ctx . putImageData ( imgData , 0 , 0 ) ;
return ;
}
var tmpImgData = ctx . createImageData ( imgData . width , imgData . height ) ;
var data = imgData . data ;
var tmpImgDataPixels = tmpImgData . data ;
if ( 'set' in tmpImgDataPixels )
tmpImgDataPixels . set ( data ) ;
else {
// Copy over the imageData pixel by pixel.
for ( var i = 0 , ii = tmpImgDataPixels . length ; i < ii ; i ++ )
tmpImgDataPixels [ i ] = data [ i ] ;
}
ctx . putImageData ( tmpImgData , 0 , 0 ) ;
}
function copyCtxState ( sourceCtx , destCtx ) {
var properties = [ 'strokeStyle' , 'fillStyle' , 'fillRule' , 'globalAlpha' ,
'lineWidth' , 'lineCap' , 'lineJoin' , 'miterLimit' ,
'globalCompositeOperation' , 'font' ] ;
for ( var i = 0 , ii = properties . length ; i < ii ; i ++ ) {
var property = properties [ i ] ;
if ( property in sourceCtx ) {
destCtx [ property ] = sourceCtx [ property ] ;
}
}
if ( 'setLineDash' in sourceCtx ) {
destCtx . setLineDash ( sourceCtx . getLineDash ( ) ) ;
destCtx . lineDashOffset = sourceCtx . lineDashOffset ;
} else if ( 'mozDash' in sourceCtx ) {
destCtx . mozDash = sourceCtx . mozDash ;
destCtx . mozDashOffset = sourceCtx . mozDashOffset ;
}
}
var LINE _CAP _STYLES = [ 'butt' , 'round' , 'square' ] ;
var LINE _JOIN _STYLES = [ 'miter' , 'round' , 'bevel' ] ;
var NORMAL _CLIP = { } ;
var EO _CLIP = { } ;
CanvasGraphics . prototype = {
beginDrawing : function CanvasGraphics _beginDrawing ( viewport , transparency ) {
// For pdfs that use blend modes we have to clear the canvas else certain
// blend modes can look wrong since we'd be blending with a white
// backdrop. The problem with a transparent backdrop though is we then
// don't get sub pixel anti aliasing on text, so we fill with white if
// we can.
var width = this . ctx . canvas . width ;
var height = this . ctx . canvas . height ;
if ( transparency ) {
this . ctx . clearRect ( 0 , 0 , width , height ) ;
} else {
this . ctx . mozOpaque = true ;
this . ctx . save ( ) ;
this . ctx . fillStyle = 'rgb(255, 255, 255)' ;
this . ctx . fillRect ( 0 , 0 , width , height ) ;
this . ctx . restore ( ) ;
}
var transform = viewport . transform ;
this . baseTransform = transform . slice ( ) ;
this . ctx . save ( ) ;
this . ctx . transform . apply ( this . ctx , transform ) ;
if ( this . textLayer ) {
this . textLayer . beginLayout ( ) ;
}
if ( this . imageLayer ) {
this . imageLayer . beginLayout ( ) ;
}
} ,
executeOperatorList : function CanvasGraphics _executeOperatorList (
operatorList ,
executionStartIdx , continueCallback ,
stepper ) {
var argsArray = operatorList . argsArray ;
var fnArray = operatorList . fnArray ;
var i = executionStartIdx || 0 ;
var argsArrayLen = argsArray . length ;
// Sometimes the OperatorList to execute is empty.
if ( argsArrayLen == i ) {
return i ;
}
var executionEndIdx ;
var endTime = Date . now ( ) + EXECUTION _TIME ;
var commonObjs = this . commonObjs ;
var objs = this . objs ;
var fnId ;
while ( true ) {
if ( stepper && i === stepper . nextBreakPoint ) {
stepper . breakIt ( i , continueCallback ) ;
return i ;
}
fnId = fnArray [ i ] ;
if ( fnId !== OPS . dependency ) {
this [ fnId ] . apply ( this , argsArray [ i ] ) ;
} else {
var deps = argsArray [ i ] ;
for ( var n = 0 , nn = deps . length ; n < nn ; n ++ ) {
var depObjId = deps [ n ] ;
var common = depObjId . substring ( 0 , 2 ) == 'g_' ;
// If the promise isn't resolved yet, add the continueCallback
// to the promise and bail out.
if ( ! common && ! objs . isResolved ( depObjId ) ) {
objs . get ( depObjId , continueCallback ) ;
return i ;
}
if ( common && ! commonObjs . isResolved ( depObjId ) ) {
commonObjs . get ( depObjId , continueCallback ) ;
return i ;
}
}
}
i ++ ;
// If the entire operatorList was executed, stop as were done.
if ( i == argsArrayLen ) {
return i ;
}
// If the execution took longer then a certain amount of time, schedule
// to continue exeution after a short delay.
// However, this is only possible if a 'continueCallback' is passed in.
if ( continueCallback && Date . now ( ) > endTime ) {
setTimeout ( continueCallback , 0 ) ;
return i ;
}
// If the operatorList isn't executed completely yet OR the execution
// time was short enough, do another execution round.
}
} ,
endDrawing : function CanvasGraphics _endDrawing ( ) {
this . ctx . restore ( ) ;
CachedCanvases . clear ( ) ;
if ( this . textLayer ) {
this . textLayer . endLayout ( ) ;
}
if ( this . imageLayer ) {
this . imageLayer . endLayout ( ) ;
}
} ,
// Graphics state
setLineWidth : function CanvasGraphics _setLineWidth ( width ) {
this . current . lineWidth = width ;
this . ctx . lineWidth = width ;
} ,
setLineCap : function CanvasGraphics _setLineCap ( style ) {
this . ctx . lineCap = LINE _CAP _STYLES [ style ] ;
} ,
setLineJoin : function CanvasGraphics _setLineJoin ( style ) {
this . ctx . lineJoin = LINE _JOIN _STYLES [ style ] ;
} ,
setMiterLimit : function CanvasGraphics _setMiterLimit ( limit ) {
this . ctx . miterLimit = limit ;
} ,
setDash : function CanvasGraphics _setDash ( dashArray , dashPhase ) {
var ctx = this . ctx ;
if ( 'setLineDash' in ctx ) {
ctx . setLineDash ( dashArray ) ;
ctx . lineDashOffset = dashPhase ;
} else {
ctx . mozDash = dashArray ;
ctx . mozDashOffset = dashPhase ;
}
} ,
setRenderingIntent : function CanvasGraphics _setRenderingIntent ( intent ) {
// Maybe if we one day fully support color spaces this will be important
// for now we can ignore.
// TODO set rendering intent?
} ,
setFlatness : function CanvasGraphics _setFlatness ( flatness ) {
// There's no way to control this with canvas, but we can safely ignore.
// TODO set flatness?
} ,
setGState : function CanvasGraphics _setGState ( states ) {
for ( var i = 0 , ii = states . length ; i < ii ; i ++ ) {
var state = states [ i ] ;
var key = state [ 0 ] ;
var value = state [ 1 ] ;
switch ( key ) {
case 'LW' :
this . setLineWidth ( value ) ;
break ;
case 'LC' :
this . setLineCap ( value ) ;
break ;
case 'LJ' :
this . setLineJoin ( value ) ;
break ;
case 'ML' :
this . setMiterLimit ( value ) ;
break ;
case 'D' :
this . setDash ( value [ 0 ] , value [ 1 ] ) ;
break ;
case 'RI' :
this . setRenderingIntent ( value ) ;
break ;
case 'FL' :
this . setFlatness ( value ) ;
break ;
case 'Font' :
this . setFont ( value [ 0 ] , value [ 1 ] ) ;
break ;
case 'CA' :
this . current . strokeAlpha = state [ 1 ] ;
break ;
case 'ca' :
this . current . fillAlpha = state [ 1 ] ;
this . ctx . globalAlpha = state [ 1 ] ;
break ;
case 'BM' :
if ( value && value . name && ( value . name !== 'Normal' ) ) {
var mode = value . name . replace ( /([A-Z])/g ,
function ( c ) {
return '-' + c . toLowerCase ( ) ;
}
) . substring ( 1 ) ;
this . ctx . globalCompositeOperation = mode ;
if ( this . ctx . globalCompositeOperation !== mode ) {
warn ( 'globalCompositeOperation "' + mode +
'" is not supported' ) ;
}
} else {
this . ctx . globalCompositeOperation = 'source-over' ;
}
break ;
}
}
} ,
save : function CanvasGraphics _save ( ) {
this . ctx . save ( ) ;
var old = this . current ;
this . stateStack . push ( old ) ;
this . current = old . clone ( ) ;
} ,
restore : function CanvasGraphics _restore ( ) {
var prev = this . stateStack . pop ( ) ;
if ( prev ) {
this . current = prev ;
this . ctx . restore ( ) ;
}
} ,
transform : function CanvasGraphics _transform ( a , b , c , d , e , f ) {
this . ctx . transform ( a , b , c , d , e , f ) ;
} ,
// Path
moveTo : function CanvasGraphics _moveTo ( x , y ) {
this . ctx . moveTo ( x , y ) ;
this . current . setCurrentPoint ( x , y ) ;
} ,
lineTo : function CanvasGraphics _lineTo ( x , y ) {
this . ctx . lineTo ( x , y ) ;
this . current . setCurrentPoint ( x , y ) ;
} ,
curveTo : function CanvasGraphics _curveTo ( x1 , y1 , x2 , y2 , x3 , y3 ) {
this . ctx . bezierCurveTo ( x1 , y1 , x2 , y2 , x3 , y3 ) ;
this . current . setCurrentPoint ( x3 , y3 ) ;
} ,
curveTo2 : function CanvasGraphics _curveTo2 ( x2 , y2 , x3 , y3 ) {
var current = this . current ;
this . ctx . bezierCurveTo ( current . x , current . y , x2 , y2 , x3 , y3 ) ;
current . setCurrentPoint ( x3 , y3 ) ;
} ,
curveTo3 : function CanvasGraphics _curveTo3 ( x1 , y1 , x3 , y3 ) {
this . curveTo ( x1 , y1 , x3 , y3 , x3 , y3 ) ;
this . current . setCurrentPoint ( x3 , y3 ) ;
} ,
closePath : function CanvasGraphics _closePath ( ) {
this . ctx . closePath ( ) ;
} ,
rectangle : function CanvasGraphics _rectangle ( x , y , width , height ) {
this . ctx . rect ( x , y , width , height ) ;
} ,
stroke : function CanvasGraphics _stroke ( consumePath ) {
consumePath = typeof consumePath !== 'undefined' ? consumePath : true ;
var ctx = this . ctx ;
var strokeColor = this . current . strokeColor ;
if ( this . current . lineWidth === 0 )
ctx . lineWidth = this . getSinglePixelWidth ( ) ;
// For stroke we want to temporarily change the global alpha to the
// stroking alpha.
ctx . globalAlpha = this . current . strokeAlpha ;
if ( strokeColor && strokeColor . hasOwnProperty ( 'type' ) &&
strokeColor . type === 'Pattern' ) {
// for patterns, we transform to pattern space, calculate
// the pattern, call stroke, and restore to user space
ctx . save ( ) ;
ctx . strokeStyle = strokeColor . getPattern ( ctx , this ) ;
ctx . stroke ( ) ;
ctx . restore ( ) ;
} else {
ctx . stroke ( ) ;
}
if ( consumePath )
this . consumePath ( ) ;
// Restore the global alpha to the fill alpha
ctx . globalAlpha = this . current . fillAlpha ;
} ,
closeStroke : function CanvasGraphics _closeStroke ( ) {
this . closePath ( ) ;
this . stroke ( ) ;
} ,
fill : function CanvasGraphics _fill ( consumePath ) {
consumePath = typeof consumePath !== 'undefined' ? consumePath : true ;
var ctx = this . ctx ;
var fillColor = this . current . fillColor ;
var needRestore = false ;
if ( fillColor && fillColor . hasOwnProperty ( 'type' ) &&
fillColor . type === 'Pattern' ) {
ctx . save ( ) ;
ctx . fillStyle = fillColor . getPattern ( ctx , this ) ;
needRestore = true ;
}
if ( this . pendingEOFill ) {
if ( 'mozFillRule' in this . ctx ) {
this . ctx . mozFillRule = 'evenodd' ;
this . ctx . fill ( ) ;
this . ctx . mozFillRule = 'nonzero' ;
} else {
try {
this . ctx . fill ( 'evenodd' ) ;
} catch ( ex ) {
// shouldn't really happen, but browsers might think differently
this . ctx . fill ( ) ;
}
}
this . pendingEOFill = false ;
} else {
this . ctx . fill ( ) ;
}
if ( needRestore ) {
ctx . restore ( ) ;
}
if ( consumePath ) {
this . consumePath ( ) ;
}
} ,
eoFill : function CanvasGraphics _eoFill ( ) {
this . pendingEOFill = true ;
this . fill ( ) ;
} ,
fillStroke : function CanvasGraphics _fillStroke ( ) {
this . fill ( false ) ;
this . stroke ( false ) ;
this . consumePath ( ) ;
} ,
eoFillStroke : function CanvasGraphics _eoFillStroke ( ) {
this . pendingEOFill = true ;
this . fillStroke ( ) ;
} ,
closeFillStroke : function CanvasGraphics _closeFillStroke ( ) {
this . closePath ( ) ;
this . fillStroke ( ) ;
} ,
closeEOFillStroke : function CanvasGraphics _closeEOFillStroke ( ) {
this . pendingEOFill = true ;
this . closePath ( ) ;
this . fillStroke ( ) ;
} ,
endPath : function CanvasGraphics _endPath ( ) {
this . consumePath ( ) ;
} ,
// Clipping
clip : function CanvasGraphics _clip ( ) {
this . pendingClip = NORMAL _CLIP ;
} ,
eoClip : function CanvasGraphics _eoClip ( ) {
this . pendingClip = EO _CLIP ;
} ,
// Text
beginText : function CanvasGraphics _beginText ( ) {
this . current . textMatrix = IDENTITY _MATRIX ;
this . current . x = this . current . lineX = 0 ;
this . current . y = this . current . lineY = 0 ;
} ,
endText : function CanvasGraphics _endText ( ) {
if ( ! ( 'pendingTextPaths' in this ) ) {
this . ctx . beginPath ( ) ;
return ;
}
var paths = this . pendingTextPaths ;
var ctx = this . ctx ;
ctx . save ( ) ;
ctx . beginPath ( ) ;
for ( var i = 0 ; i < paths . length ; i ++ ) {
var path = paths [ i ] ;
ctx . setTransform . apply ( ctx , path . transform ) ;
ctx . translate ( path . x , path . y ) ;
path . addToPath ( ctx , path . fontSize ) ;
}
ctx . restore ( ) ;
ctx . clip ( ) ;
ctx . beginPath ( ) ;
delete this . pendingTextPaths ;
} ,
setCharSpacing : function CanvasGraphics _setCharSpacing ( spacing ) {
this . current . charSpacing = spacing ;
} ,
setWordSpacing : function CanvasGraphics _setWordSpacing ( spacing ) {
this . current . wordSpacing = spacing ;
} ,
setHScale : function CanvasGraphics _setHScale ( scale ) {
this . current . textHScale = scale / 100 ;
} ,
setLeading : function CanvasGraphics _setLeading ( leading ) {
this . current . leading = - leading ;
} ,
setFont : function CanvasGraphics _setFont ( fontRefName , size ) {
var fontObj = this . commonObjs . get ( fontRefName ) ;
var current = this . current ;
if ( ! fontObj )
error ( 'Can\'t find font for ' + fontRefName ) ;
current . fontMatrix = fontObj . fontMatrix ? fontObj . fontMatrix :
FONT _IDENTITY _MATRIX ;
// A valid matrix needs all main diagonal elements to be non-zero
// This also ensures we bypass FF bugzilla bug #719844.
if ( current . fontMatrix [ 0 ] === 0 ||
current . fontMatrix [ 3 ] === 0 ) {
warn ( 'Invalid font matrix for font ' + fontRefName ) ;
}
// The spec for Tf (setFont) says that 'size' specifies the font 'scale',
// and in some docs this can be negative (inverted x-y axes).
if ( size < 0 ) {
size = - size ;
current . fontDirection = - 1 ;
} else {
current . fontDirection = 1 ;
}
this . current . font = fontObj ;
this . current . fontSize = size ;
if ( fontObj . coded )
return ; // we don't need ctx.font for Type3 fonts
var name = fontObj . loadedName || 'sans-serif' ;
var bold = fontObj . black ? ( fontObj . bold ? 'bolder' : 'bold' ) :
( fontObj . bold ? 'bold' : 'normal' ) ;
var italic = fontObj . italic ? 'italic' : 'normal' ;
var typeface = '"' + name + '", ' + fontObj . fallbackName ;
// Some font backends cannot handle fonts below certain size.
// Keeping the font at minimal size and using the fontSizeScale to change
// the current transformation matrix before the fillText/strokeText.
// See https://bugzilla.mozilla.org/show_bug.cgi?id=726227
var browserFontSize = size >= MIN _FONT _SIZE ? size : MIN _FONT _SIZE ;
this . current . fontSizeScale = browserFontSize != MIN _FONT _SIZE ? 1.0 :
size / MIN _FONT _SIZE ;
var rule = italic + ' ' + bold + ' ' + browserFontSize + 'px ' + typeface ;
this . ctx . font = rule ;
} ,
setTextRenderingMode : function CanvasGraphics _setTextRenderingMode ( mode ) {
this . current . textRenderingMode = mode ;
} ,
setTextRise : function CanvasGraphics _setTextRise ( rise ) {
this . current . textRise = rise ;
} ,
moveText : function CanvasGraphics _moveText ( x , y ) {
this . current . x = this . current . lineX += x ;
this . current . y = this . current . lineY += y ;
} ,
setLeadingMoveText : function CanvasGraphics _setLeadingMoveText ( x , y ) {
this . setLeading ( - y ) ;
this . moveText ( x , y ) ;
} ,
setTextMatrix : function CanvasGraphics _setTextMatrix ( a , b , c , d , e , f ) {
this . current . textMatrix = [ a , b , c , d , e , f ] ;
this . current . x = this . current . lineX = 0 ;
this . current . y = this . current . lineY = 0 ;
} ,
nextLine : function CanvasGraphics _nextLine ( ) {
this . moveText ( 0 , this . current . leading ) ;
} ,
applyTextTransforms : function CanvasGraphics _applyTextTransforms ( ) {
var ctx = this . ctx ;
var current = this . current ;
ctx . transform . apply ( ctx , current . textMatrix ) ;
ctx . translate ( current . x , current . y + current . textRise ) ;
if ( current . fontDirection > 0 ) {
ctx . scale ( current . textHScale , - 1 ) ;
} else {
ctx . scale ( - current . textHScale , 1 ) ;
}
} ,
createTextGeometry : function CanvasGraphics _createTextGeometry ( ) {
var geometry = { } ;
var ctx = this . ctx ;
var font = this . current . font ;
var ctxMatrix = ctx . mozCurrentTransform ;
var a = ctxMatrix [ 0 ] , b = ctxMatrix [ 1 ] , c = ctxMatrix [ 2 ] ;
var d = ctxMatrix [ 3 ] , e = ctxMatrix [ 4 ] , f = ctxMatrix [ 5 ] ;
var sx = ( a >= 0 ) ?
Math . sqrt ( ( a * a ) + ( b * b ) ) : - Math . sqrt ( ( a * a ) + ( b * b ) ) ;
var sy = ( d >= 0 ) ?
Math . sqrt ( ( c * c ) + ( d * d ) ) : - Math . sqrt ( ( c * c ) + ( d * d ) ) ;
var angle = Math . atan2 ( b , a ) ;
var x = e ;
var y = f ;
geometry . x = x ;
geometry . y = y ;
geometry . hScale = sx ;
geometry . vScale = sy ;
geometry . angle = angle ;
geometry . spaceWidth = font . spaceWidth ;
geometry . fontName = font . loadedName ;
geometry . fontFamily = font . fallbackName ;
geometry . fontSize = this . current . fontSize ;
return geometry ;
} ,
paintChar : function ( character , x , y ) {
var ctx = this . ctx ;
var current = this . current ;
var font = current . font ;
var fontSize = current . fontSize / current . fontSizeScale ;
var textRenderingMode = current . textRenderingMode ;
var fillStrokeMode = textRenderingMode &
TextRenderingMode . FILL _STROKE _MASK ;
var isAddToPathSet = ! ! ( textRenderingMode &
TextRenderingMode . ADD _TO _PATH _FLAG ) ;
var addToPath ;
if ( font . disableFontFace || isAddToPathSet ) {
addToPath = font . getPathGenerator ( this . commonObjs , character ) ;
}
if ( font . disableFontFace ) {
ctx . save ( ) ;
ctx . translate ( x , y ) ;
ctx . beginPath ( ) ;
addToPath ( ctx , fontSize ) ;
if ( fillStrokeMode === TextRenderingMode . FILL ||
fillStrokeMode === TextRenderingMode . FILL _STROKE ) {
ctx . fill ( ) ;
}
if ( fillStrokeMode === TextRenderingMode . STROKE ||
fillStrokeMode === TextRenderingMode . FILL _STROKE ) {
ctx . stroke ( ) ;
}
ctx . restore ( ) ;
} else {
if ( fillStrokeMode === TextRenderingMode . FILL ||
fillStrokeMode === TextRenderingMode . FILL _STROKE ) {
ctx . fillText ( character , x , y ) ;
}
if ( fillStrokeMode === TextRenderingMode . STROKE ||
fillStrokeMode === TextRenderingMode . FILL _STROKE ) {
ctx . strokeText ( character , x , y ) ;
}
}
if ( isAddToPathSet ) {
var paths = this . pendingTextPaths || ( this . pendingTextPaths = [ ] ) ;
paths . push ( {
transform : ctx . mozCurrentTransform ,
x : x ,
y : y ,
fontSize : fontSize ,
addToPath : addToPath
} ) ;
}
} ,
showText : function CanvasGraphics _showText ( glyphs , skipTextSelection ) {
var ctx = this . ctx ;
var current = this . current ;
var font = current . font ;
var fontSize = current . fontSize ;
var fontSizeScale = current . fontSizeScale ;
var charSpacing = current . charSpacing ;
var wordSpacing = current . wordSpacing ;
var textHScale = current . textHScale * current . fontDirection ;
var fontMatrix = current . fontMatrix || FONT _IDENTITY _MATRIX ;
var glyphsLength = glyphs . length ;
var textLayer = this . textLayer ;
var geom ;
var textSelection = textLayer && ! skipTextSelection ? true : false ;
var canvasWidth = 0.0 ;
var vertical = font . vertical ;
var defaultVMetrics = font . defaultVMetrics ;
// Type3 fonts - each glyph is a "mini-PDF"
if ( font . coded ) {
ctx . save ( ) ;
ctx . transform . apply ( ctx , current . textMatrix ) ;
ctx . translate ( current . x , current . y ) ;
ctx . scale ( textHScale , 1 ) ;
if ( textSelection ) {
this . save ( ) ;
ctx . scale ( 1 , - 1 ) ;
geom = this . createTextGeometry ( ) ;
this . restore ( ) ;
}
for ( var i = 0 ; i < glyphsLength ; ++ i ) {
var glyph = glyphs [ i ] ;
if ( glyph === null ) {
// word break
this . ctx . translate ( wordSpacing , 0 ) ;
current . x += wordSpacing * textHScale ;
continue ;
}
this . processingType3 = glyph ;
this . save ( ) ;
ctx . scale ( fontSize , fontSize ) ;
ctx . transform . apply ( ctx , fontMatrix ) ;
this . executeOperatorList ( glyph . operatorList ) ;
this . restore ( ) ;
var transformed = Util . applyTransform ( [ glyph . width , 0 ] , fontMatrix ) ;
var width = ( transformed [ 0 ] * fontSize + charSpacing ) *
current . fontDirection ;
ctx . translate ( width , 0 ) ;
current . x += width * textHScale ;
canvasWidth += width ;
}
ctx . restore ( ) ;
this . processingType3 = null ;
} else {
ctx . save ( ) ;
this . applyTextTransforms ( ) ;
var lineWidth = current . lineWidth ;
var a1 = current . textMatrix [ 0 ] , b1 = current . textMatrix [ 1 ] ;
var scale = Math . sqrt ( a1 * a1 + b1 * b1 ) ;
if ( scale === 0 || lineWidth === 0 )
lineWidth = this . getSinglePixelWidth ( ) ;
else
lineWidth /= scale ;
if ( textSelection )
geom = this . createTextGeometry ( ) ;
if ( fontSizeScale != 1.0 ) {
ctx . scale ( fontSizeScale , fontSizeScale ) ;
lineWidth /= fontSizeScale ;
}
ctx . lineWidth = lineWidth ;
var x = 0 ;
for ( var i = 0 ; i < glyphsLength ; ++ i ) {
var glyph = glyphs [ i ] ;
if ( glyph === null ) {
// word break
x += current . fontDirection * wordSpacing ;
continue ;
}
var restoreNeeded = false ;
var character = glyph . fontChar ;
var vmetric = glyph . vmetric || defaultVMetrics ;
if ( vertical ) {
var vx = glyph . vmetric ? vmetric [ 1 ] : glyph . width * 0.5 ;
vx = - vx * fontSize * current . fontMatrix [ 0 ] ;
var vy = vmetric [ 2 ] * fontSize * current . fontMatrix [ 0 ] ;
}
var width = vmetric ? - vmetric [ 0 ] : glyph . width ;
var charWidth = width * fontSize * current . fontMatrix [ 0 ] +
charSpacing * current . fontDirection ;
var accent = glyph . accent ;
var scaledX , scaledY , scaledAccentX , scaledAccentY ;
if ( ! glyph . disabled ) {
if ( vertical ) {
scaledX = vx / fontSizeScale ;
scaledY = ( x + vy ) / fontSizeScale ;
} else {
scaledX = x / fontSizeScale ;
scaledY = 0 ;
}
if ( font . remeasure && width > 0 ) {
// some standard fonts may not have the exact width, trying to
// rescale per character
var measuredWidth = ctx . measureText ( character ) . width * 1000 /
current . fontSize * current . fontSizeScale ;
var characterScaleX = width / measuredWidth ;
restoreNeeded = true ;
ctx . save ( ) ;
ctx . scale ( characterScaleX , 1 ) ;
scaledX /= characterScaleX ;
if ( accent ) {
scaledAccentX /= characterScaleX ;
}
}
this . paintChar ( character , scaledX , scaledY ) ;
if ( accent ) {
scaledAccentX = scaledX + accent . offset . x / fontSizeScale ;
scaledAccentY = scaledY - accent . offset . y / fontSizeScale ;
this . paintChar ( accent . fontChar , scaledAccentX , scaledAccentY ) ;
}
}
x += charWidth ;
canvasWidth += charWidth ;
if ( restoreNeeded ) {
ctx . restore ( ) ;
}
}
if ( vertical ) {
current . y -= x * textHScale ;
} else {
current . x += x * textHScale ;
}
ctx . restore ( ) ;
}
if ( textSelection ) {
geom . canvasWidth = canvasWidth ;
if ( vertical ) {
var VERTICAL _TEXT _ROTATION = Math . PI / 2 ;
geom . angle += VERTICAL _TEXT _ROTATION ;
}
this . textLayer . appendText ( geom ) ;
}
return canvasWidth ;
} ,
showSpacedText : function CanvasGraphics _showSpacedText ( arr ) {
var ctx = this . ctx ;
var current = this . current ;
var font = current . font ;
var fontSize = current . fontSize ;
// TJ array's number is independent from fontMatrix
var textHScale = current . textHScale * 0.001 * current . fontDirection ;
var arrLength = arr . length ;
var textLayer = this . textLayer ;
var geom ;
var canvasWidth = 0.0 ;
var textSelection = textLayer ? true : false ;
var vertical = font . vertical ;
var spacingAccumulator = 0 ;
if ( textSelection ) {
ctx . save ( ) ;
this . applyTextTransforms ( ) ;
geom = this . createTextGeometry ( ) ;
ctx . restore ( ) ;
}
for ( var i = 0 ; i < arrLength ; ++ i ) {
var e = arr [ i ] ;
if ( isNum ( e ) ) {
var spacingLength = - e * fontSize * textHScale ;
if ( vertical ) {
current . y += spacingLength ;
} else {
current . x += spacingLength ;
}
if ( textSelection )
spacingAccumulator += spacingLength ;
} else {
var shownCanvasWidth = this . showText ( e , true ) ;
if ( textSelection ) {
canvasWidth += spacingAccumulator + shownCanvasWidth ;
spacingAccumulator = 0 ;
}
}
}
if ( textSelection ) {
geom . canvasWidth = canvasWidth ;
if ( vertical ) {
var VERTICAL _TEXT _ROTATION = Math . PI / 2 ;
geom . angle += VERTICAL _TEXT _ROTATION ;
}
this . textLayer . appendText ( geom ) ;
}
} ,
nextLineShowText : function CanvasGraphics _nextLineShowText ( text ) {
this . nextLine ( ) ;
this . showText ( text ) ;
} ,
nextLineSetSpacingShowText :
function CanvasGraphics _nextLineSetSpacingShowText ( wordSpacing ,
charSpacing ,
text ) {
this . setWordSpacing ( wordSpacing ) ;
this . setCharSpacing ( charSpacing ) ;
this . nextLineShowText ( text ) ;
} ,
// Type3 fonts
setCharWidth : function CanvasGraphics _setCharWidth ( xWidth , yWidth ) {
// We can safely ignore this since the width should be the same
// as the width in the Widths array.
} ,
setCharWidthAndBounds : function CanvasGraphics _setCharWidthAndBounds ( xWidth ,
yWidth ,
llx ,
lly ,
urx ,
ury ) {
// TODO According to the spec we're also suppose to ignore any operators
// that set color or include images while processing this type3 font.
this . rectangle ( llx , lly , urx - llx , ury - lly ) ;
this . clip ( ) ;
this . endPath ( ) ;
} ,
// Color
setStrokeColorSpace : function CanvasGraphics _setStrokeColorSpace ( raw ) {
this . current . strokeColorSpace = ColorSpace . fromIR ( raw ) ;
} ,
setFillColorSpace : function CanvasGraphics _setFillColorSpace ( raw ) {
this . current . fillColorSpace = ColorSpace . fromIR ( raw ) ;
} ,
setStrokeColor : function CanvasGraphics _setStrokeColor ( /*...*/ ) {
var cs = this . current . strokeColorSpace ;
var rgbColor = cs . getRgb ( arguments , 0 ) ;
var color = Util . makeCssRgb ( rgbColor ) ;
this . ctx . strokeStyle = color ;
this . current . strokeColor = color ;
} ,
getColorN _Pattern : function CanvasGraphics _getColorN _Pattern ( IR , cs ) {
if ( IR [ 0 ] == 'TilingPattern' ) {
var args = IR [ 1 ] ;
var base = cs . base ;
var color ;
if ( base ) {
var baseComps = base . numComps ;
color = base . getRgb ( args , 0 ) ;
}
var pattern = new TilingPattern ( IR , color , this . ctx , this . objs ,
this . commonObjs , this . baseTransform ) ;
} else if ( IR [ 0 ] == 'RadialAxial' || IR [ 0 ] == 'Dummy' ) {
var pattern = Pattern . shadingFromIR ( IR ) ;
} else {
error ( 'Unkown IR type ' + IR [ 0 ] ) ;
}
return pattern ;
} ,
setStrokeColorN : function CanvasGraphics _setStrokeColorN ( /*...*/ ) {
var cs = this . current . strokeColorSpace ;
if ( cs . name == 'Pattern' ) {
this . current . strokeColor = this . getColorN _Pattern ( arguments , cs ) ;
} else {
this . setStrokeColor . apply ( this , arguments ) ;
}
} ,
setFillColor : function CanvasGraphics _setFillColor ( /*...*/ ) {
var cs = this . current . fillColorSpace ;
var rgbColor = cs . getRgb ( arguments , 0 ) ;
var color = Util . makeCssRgb ( rgbColor ) ;
this . ctx . fillStyle = color ;
this . current . fillColor = color ;
} ,
setFillColorN : function CanvasGraphics _setFillColorN ( /*...*/ ) {
var cs = this . current . fillColorSpace ;
if ( cs . name == 'Pattern' ) {
this . current . fillColor = this . getColorN _Pattern ( arguments , cs ) ;
} else {
this . setFillColor . apply ( this , arguments ) ;
}
} ,
setStrokeGray : function CanvasGraphics _setStrokeGray ( gray ) {
this . current . strokeColorSpace = ColorSpace . singletons . gray ;
var rgbColor = this . current . strokeColorSpace . getRgb ( arguments , 0 ) ;
var color = Util . makeCssRgb ( rgbColor ) ;
this . ctx . strokeStyle = color ;
this . current . strokeColor = color ;
} ,
setFillGray : function CanvasGraphics _setFillGray ( gray ) {
this . current . fillColorSpace = ColorSpace . singletons . gray ;
var rgbColor = this . current . fillColorSpace . getRgb ( arguments , 0 ) ;
var color = Util . makeCssRgb ( rgbColor ) ;
this . ctx . fillStyle = color ;
this . current . fillColor = color ;
} ,
setStrokeRGBColor : function CanvasGraphics _setStrokeRGBColor ( r , g , b ) {
this . current . strokeColorSpace = ColorSpace . singletons . rgb ;
var rgbColor = this . current . strokeColorSpace . getRgb ( arguments , 0 ) ;
var color = Util . makeCssRgb ( rgbColor ) ;
this . ctx . strokeStyle = color ;
this . current . strokeColor = color ;
} ,
setFillRGBColor : function CanvasGraphics _setFillRGBColor ( r , g , b ) {
this . current . fillColorSpace = ColorSpace . singletons . rgb ;
var rgbColor = this . current . fillColorSpace . getRgb ( arguments , 0 ) ;
var color = Util . makeCssRgb ( rgbColor ) ;
this . ctx . fillStyle = color ;
this . current . fillColor = color ;
} ,
setStrokeCMYKColor : function CanvasGraphics _setStrokeCMYKColor ( c , m , y , k ) {
this . current . strokeColorSpace = ColorSpace . singletons . cmyk ;
var color = Util . makeCssCmyk ( arguments ) ;
this . ctx . strokeStyle = color ;
this . current . strokeColor = color ;
} ,
setFillCMYKColor : function CanvasGraphics _setFillCMYKColor ( c , m , y , k ) {
this . current . fillColorSpace = ColorSpace . singletons . cmyk ;
var color = Util . makeCssCmyk ( arguments ) ;
this . ctx . fillStyle = color ;
this . current . fillColor = color ;
} ,
shadingFill : function CanvasGraphics _shadingFill ( patternIR ) {
var ctx = this . ctx ;
this . save ( ) ;
var pattern = Pattern . shadingFromIR ( patternIR ) ;
ctx . fillStyle = pattern . getPattern ( ctx , this ) ;
var inv = ctx . mozCurrentTransformInverse ;
if ( inv ) {
var canvas = ctx . canvas ;
var width = canvas . width ;
var height = canvas . height ;
var bl = Util . applyTransform ( [ 0 , 0 ] , inv ) ;
var br = Util . applyTransform ( [ 0 , height ] , inv ) ;
var ul = Util . applyTransform ( [ width , 0 ] , inv ) ;
var ur = Util . applyTransform ( [ width , height ] , inv ) ;
var x0 = Math . min ( bl [ 0 ] , br [ 0 ] , ul [ 0 ] , ur [ 0 ] ) ;
var y0 = Math . min ( bl [ 1 ] , br [ 1 ] , ul [ 1 ] , ur [ 1 ] ) ;
var x1 = Math . max ( bl [ 0 ] , br [ 0 ] , ul [ 0 ] , ur [ 0 ] ) ;
var y1 = Math . max ( bl [ 1 ] , br [ 1 ] , ul [ 1 ] , ur [ 1 ] ) ;
this . ctx . fillRect ( x0 , y0 , x1 - x0 , y1 - y0 ) ;
} else {
// HACK to draw the gradient onto an infinite rectangle.
// PDF gradients are drawn across the entire image while
// Canvas only allows gradients to be drawn in a rectangle
// The following bug should allow us to remove this.
// https://bugzilla.mozilla.org/show_bug.cgi?id=664884
this . ctx . fillRect ( - 1e10 , - 1e10 , 2e10 , 2e10 ) ;
}
this . restore ( ) ;
} ,
// Images
beginInlineImage : function CanvasGraphics _beginInlineImage ( ) {
error ( 'Should not call beginInlineImage' ) ;
} ,
beginImageData : function CanvasGraphics _beginImageData ( ) {
error ( 'Should not call beginImageData' ) ;
} ,
paintFormXObjectBegin : function CanvasGraphics _paintFormXObjectBegin ( matrix ,
bbox ) {
this . save ( ) ;
this . current . paintFormXObjectDepth ++ ;
this . baseTransformStack . push ( this . baseTransform ) ;
if ( matrix && isArray ( matrix ) && 6 == matrix . length )
this . transform . apply ( this , matrix ) ;
this . baseTransform = this . ctx . mozCurrentTransform ;
if ( bbox && isArray ( bbox ) && 4 == bbox . length ) {
var width = bbox [ 2 ] - bbox [ 0 ] ;
var height = bbox [ 3 ] - bbox [ 1 ] ;
this . rectangle ( bbox [ 0 ] , bbox [ 1 ] , width , height ) ;
this . clip ( ) ;
this . endPath ( ) ;
}
} ,
paintFormXObjectEnd : function CanvasGraphics _paintFormXObjectEnd ( ) {
var depth = this . current . paintFormXObjectDepth ;
do {
this . restore ( ) ;
// some pdf don't close all restores inside object
// closing those for them
} while ( this . current . paintFormXObjectDepth >= depth ) ;
this . baseTransform = this . baseTransformStack . pop ( ) ;
} ,
beginGroup : function CanvasGraphics _beginGroup ( group ) {
this . save ( ) ;
var currentCtx = this . ctx ;
// TODO non-isolated groups - according to Rik at adobe non-isolated
// group results aren't usually that different and they even have tools
// that ignore this setting. Notes from Rik on implmenting:
// - When you encounter an transparency group, create a new canvas with
// the dimensions of the bbox
// - copy the content from the previous canvas to the new canvas
// - draw as usual
// - remove the backdrop alpha:
// alphaNew = 1 - (1 - alpha)/(1 - alphaBackdrop) with 'alpha' the alpha
// value of your transparency group and 'alphaBackdrop' the alpha of the
// backdrop
// - remove background color:
// colorNew = color - alphaNew *colorBackdrop /(1 - alphaNew)
if ( ! group . isolated ) {
info ( 'TODO: Support non-isolated groups.' ) ;
}
// TODO knockout - supposedly possible with the clever use of compositing
// modes.
if ( group . knockout ) {
TODO ( 'Support knockout groups.' ) ;
}
var currentTransform = currentCtx . mozCurrentTransform ;
if ( group . matrix ) {
currentCtx . transform . apply ( currentCtx , group . matrix ) ;
}
assert ( group . bbox , 'Bounding box is required.' ) ;
// Based on the current transform figure out how big the bounding box
// will actually be.
var bounds = Util . getAxialAlignedBoundingBox (
group . bbox ,
currentCtx . mozCurrentTransform ) ;
// Clip the bounding box to the current canvas.
var canvasBounds = [ 0 ,
0 ,
currentCtx . canvas . width ,
currentCtx . canvas . height ] ;
bounds = Util . intersect ( bounds , canvasBounds ) || [ 0 , 0 , 0 , 0 ] ;
// Use ceil in case we're between sizes so we don't create canvas that is
// too small and make the canvas at least 1x1 pixels.
var drawnWidth = Math . max ( Math . ceil ( bounds [ 2 ] - bounds [ 0 ] ) , 1 ) ;
var drawnHeight = Math . max ( Math . ceil ( bounds [ 3 ] - bounds [ 1 ] ) , 1 ) ;
var scratchCanvas = CachedCanvases . getCanvas (
'groupAt' + this . groupLevel , drawnWidth , drawnHeight , true ) ;
var groupCtx = scratchCanvas . context ;
// Since we created a new canvas that is just the size of the bounding box
// we have to translate the group ctx.
var offsetX = bounds [ 0 ] ;
var offsetY = bounds [ 1 ] ;
groupCtx . translate ( - offsetX , - offsetY ) ;
groupCtx . transform . apply ( groupCtx , currentTransform ) ;
// Setup the current ctx so when the group is popped we draw it the right
// location.
currentCtx . setTransform ( 1 , 0 , 0 , 1 , 0 , 0 ) ;
currentCtx . translate ( offsetX , offsetY ) ;
// The transparency group inherits all off the current graphics state
// except the blend mode, soft mask, and alpha constants.
copyCtxState ( currentCtx , groupCtx ) ;
this . ctx = groupCtx ;
this . setGState ( [
[ 'SMask' , 'None' ] ,
[ 'BM' , 'Normal' ] ,
[ 'ca' , 1 ] ,
[ 'CA' , 1 ]
] ) ;
this . groupStack . push ( currentCtx ) ;
this . groupLevel ++ ;
} ,
endGroup : function CanvasGraphics _endGroup ( group ) {
this . groupLevel -- ;
var groupCtx = this . ctx ;
this . ctx = this . groupStack . pop ( ) ;
// Turn off image smoothing to avoid sub pixel interpolation which can
// look kind of blurry for some pdfs.
if ( 'imageSmoothingEnabled' in this . ctx ) {
this . ctx . imageSmoothingEnabled = false ;
} else {
this . ctx . mozImageSmoothingEnabled = false ;
}
this . ctx . drawImage ( groupCtx . canvas , 0 , 0 ) ;
this . restore ( ) ;
} ,
beginAnnotations : function CanvasGraphics _beginAnnotations ( ) {
this . save ( ) ;
this . current = new CanvasExtraState ( ) ;
} ,
endAnnotations : function CanvasGraphics _endAnnotations ( ) {
this . restore ( ) ;
} ,
beginAnnotation : function CanvasGraphics _beginAnnotation ( rect , transform ,
matrix ) {
this . save ( ) ;
if ( rect && isArray ( rect ) && 4 == rect . length ) {
var width = rect [ 2 ] - rect [ 0 ] ;
var height = rect [ 3 ] - rect [ 1 ] ;
this . rectangle ( rect [ 0 ] , rect [ 1 ] , width , height ) ;
this . clip ( ) ;
this . endPath ( ) ;
}
this . transform . apply ( this , transform ) ;
this . transform . apply ( this , matrix ) ;
} ,
endAnnotation : function CanvasGraphics _endAnnotation ( ) {
this . restore ( ) ;
} ,
paintJpegXObject : function CanvasGraphics _paintJpegXObject ( objId , w , h ) {
var domImage = this . objs . get ( objId ) ;
if ( ! domImage ) {
error ( 'Dependent image isn\'t ready yet' ) ;
}
this . save ( ) ;
var ctx = this . ctx ;
// scale the image to the unit square
ctx . scale ( 1 / w , - 1 / h ) ;
ctx . drawImage ( domImage , 0 , 0 , domImage . width , domImage . height ,
0 , - h , w , h ) ;
if ( this . imageLayer ) {
var currentTransform = ctx . mozCurrentTransformInverse ;
var position = this . getCanvasPosition ( 0 , 0 ) ;
this . imageLayer . appendImage ( {
objId : objId ,
left : position [ 0 ] ,
top : position [ 1 ] ,
width : w / currentTransform [ 0 ] ,
height : h / currentTransform [ 3 ]
} ) ;
}
this . restore ( ) ;
} ,
paintImageMaskXObject : function CanvasGraphics _paintImageMaskXObject ( img ) {
var ctx = this . ctx ;
var width = img . width , height = img . height ;
var glyph = this . processingType3 ;
if ( COMPILE _TYPE3 _GLYPHS && glyph && ! ( 'compiled' in glyph ) ) {
var MAX _SIZE _TO _COMPILE = 1000 ;
if ( width <= MAX _SIZE _TO _COMPILE && height <= MAX _SIZE _TO _COMPILE ) {
glyph . compiled =
compileType3Glyph ( { data : img . data , width : width , height : height } ) ;
} else {
glyph . compiled = null ;
}
}
if ( glyph && glyph . compiled ) {
glyph . compiled ( ctx ) ;
return ;
}
var maskCanvas = CachedCanvases . getCanvas ( 'maskCanvas' , width , height ) ;
var maskCtx = maskCanvas . context ;
maskCtx . save ( ) ;
putBinaryImageData ( maskCtx , img ) ;
maskCtx . globalCompositeOperation = 'source-in' ;
var fillColor = this . current . fillColor ;
maskCtx . fillStyle = ( fillColor && fillColor . hasOwnProperty ( 'type' ) &&
fillColor . type === 'Pattern' ) ?
fillColor . getPattern ( maskCtx , this ) : fillColor ;
maskCtx . fillRect ( 0 , 0 , width , height ) ;
maskCtx . restore ( ) ;
this . paintInlineImageXObject ( maskCanvas . canvas ) ;
} ,
paintImageMaskXObjectGroup :
function CanvasGraphics _paintImageMaskXObjectGroup ( images ) {
var ctx = this . ctx ;
for ( var i = 0 , ii = images . length ; i < ii ; i ++ ) {
var image = images [ i ] ;
var width = image . width , height = image . height ;
var maskCanvas = CachedCanvases . getCanvas ( 'maskCanvas' , width , height ) ;
var maskCtx = maskCanvas . context ;
maskCtx . save ( ) ;
putBinaryImageData ( maskCtx , image ) ;
maskCtx . globalCompositeOperation = 'source-in' ;
var fillColor = this . current . fillColor ;
maskCtx . fillStyle = ( fillColor && fillColor . hasOwnProperty ( 'type' ) &&
fillColor . type === 'Pattern' ) ?
fillColor . getPattern ( maskCtx , this ) : fillColor ;
maskCtx . fillRect ( 0 , 0 , width , height ) ;
maskCtx . restore ( ) ;
ctx . save ( ) ;
ctx . transform . apply ( ctx , image . transform ) ;
ctx . scale ( 1 , - 1 ) ;
ctx . drawImage ( maskCanvas . canvas , 0 , 0 , width , height ,
0 , - 1 , 1 , 1 ) ;
ctx . restore ( ) ;
}
} ,
paintImageXObject : function CanvasGraphics _paintImageXObject ( objId ) {
var imgData = this . objs . get ( objId ) ;
if ( ! imgData )
error ( 'Dependent image isn\'t ready yet' ) ;
this . paintInlineImageXObject ( imgData ) ;
} ,
paintInlineImageXObject :
function CanvasGraphics _paintInlineImageXObject ( imgData ) {
var width = imgData . width ;
var height = imgData . height ;
var ctx = this . ctx ;
this . save ( ) ;
// scale the image to the unit square
ctx . scale ( 1 / width , - 1 / height ) ;
var currentTransform = ctx . mozCurrentTransformInverse ;
var a = currentTransform [ 0 ] , b = currentTransform [ 1 ] ;
var widthScale = Math . max ( Math . sqrt ( a * a + b * b ) , 1 ) ;
var c = currentTransform [ 2 ] , d = currentTransform [ 3 ] ;
var heightScale = Math . max ( Math . sqrt ( c * c + d * d ) , 1 ) ;
var imgToPaint ;
// instanceof HTMLElement does not work in jsdom node.js module
if ( imgData instanceof HTMLElement || ! imgData . data ) {
imgToPaint = imgData ;
} else {
var tmpCanvas = CachedCanvases . getCanvas ( 'inlineImage' , width , height ) ;
var tmpCtx = tmpCanvas . context ;
putBinaryImageData ( tmpCtx , imgData ) ;
imgToPaint = tmpCanvas . canvas ;
}
var paintWidth = width , paintHeight = height ;
var tmpCanvasId = 'prescale1' ;
// Vertial or horizontal scaling shall not be more than 2 to not loose the
// pixels during drawImage operation, painting on the temporary canvas(es)
// that are twice smaller in size
while ( ( widthScale > 2 && paintWidth > 1 ) ||
( heightScale > 2 && paintHeight > 1 ) ) {
var newWidth = paintWidth , newHeight = paintHeight ;
if ( widthScale > 2 && paintWidth > 1 ) {
newWidth = Math . ceil ( paintWidth / 2 ) ;
widthScale /= paintWidth / newWidth ;
}
if ( heightScale > 2 && paintHeight > 1 ) {
newHeight = Math . ceil ( paintHeight / 2 ) ;
heightScale /= paintHeight / newHeight ;
}
var tmpCanvas = CachedCanvases . getCanvas ( tmpCanvasId ,
newWidth , newHeight ) ;
tmpCtx = tmpCanvas . context ;
tmpCtx . clearRect ( 0 , 0 , newWidth , newHeight ) ;
tmpCtx . drawImage ( imgToPaint , 0 , 0 , paintWidth , paintHeight ,
0 , 0 , newWidth , newHeight ) ;
imgToPaint = tmpCanvas . canvas ;
paintWidth = newWidth ;
paintHeight = newHeight ;
tmpCanvasId = tmpCanvasId === 'prescale1' ? 'prescale2' : 'prescale1' ;
}
ctx . drawImage ( imgToPaint , 0 , 0 , paintWidth , paintHeight ,
0 , - height , width , height ) ;
if ( this . imageLayer ) {
var position = this . getCanvasPosition ( 0 , - height ) ;
this . imageLayer . appendImage ( {
imgData : imgData ,
left : position [ 0 ] ,
top : position [ 1 ] ,
width : width / currentTransform [ 0 ] ,
height : height / currentTransform [ 3 ]
} ) ;
}
this . restore ( ) ;
} ,
paintInlineImageXObjectGroup :
function CanvasGraphics _paintInlineImageXObjectGroup ( imgData , map ) {
var ctx = this . ctx ;
var w = imgData . width ;
var h = imgData . height ;
var tmpCanvas = CachedCanvases . getCanvas ( 'inlineImage' , w , h ) ;
var tmpCtx = tmpCanvas . context ;
putBinaryImageData ( tmpCtx , imgData ) ;
for ( var i = 0 , ii = map . length ; i < ii ; i ++ ) {
var entry = map [ i ] ;
ctx . save ( ) ;
ctx . transform . apply ( ctx , entry . transform ) ;
ctx . scale ( 1 , - 1 ) ;
ctx . drawImage ( tmpCanvas . canvas , entry . x , entry . y , entry . w , entry . h ,
0 , - 1 , 1 , 1 ) ;
if ( this . imageLayer ) {
var position = this . getCanvasPosition ( entry . x , entry . y ) ;
this . imageLayer . appendImage ( {
imgData : imgData ,
left : position [ 0 ] ,
top : position [ 1 ] ,
width : w ,
height : h
} ) ;
}
ctx . restore ( ) ;
}
} ,
// Marked content
markPoint : function CanvasGraphics _markPoint ( tag ) {
// TODO Marked content.
} ,
markPointProps : function CanvasGraphics _markPointProps ( tag , properties ) {
// TODO Marked content.
} ,
beginMarkedContent : function CanvasGraphics _beginMarkedContent ( tag ) {
// TODO Marked content.
} ,
beginMarkedContentProps : function CanvasGraphics _beginMarkedContentProps (
tag , properties ) {
// TODO Marked content.
} ,
endMarkedContent : function CanvasGraphics _endMarkedContent ( ) {
// TODO Marked content.
} ,
// Compatibility
beginCompat : function CanvasGraphics _beginCompat ( ) {
// TODO ignore undefined operators (should we do that anyway?)
} ,
endCompat : function CanvasGraphics _endCompat ( ) {
// TODO stop ignoring undefined operators
} ,
// Helper functions
consumePath : function CanvasGraphics _consumePath ( ) {
if ( this . pendingClip ) {
if ( this . pendingClip == EO _CLIP ) {
if ( 'mozFillRule' in this . ctx ) {
this . ctx . mozFillRule = 'evenodd' ;
this . ctx . clip ( ) ;
this . ctx . mozFillRule = 'nonzero' ;
} else {
try {
this . ctx . clip ( 'evenodd' ) ;
} catch ( ex ) {
// shouldn't really happen, but browsers might think differently
this . ctx . clip ( ) ;
}
}
} else {
this . ctx . clip ( ) ;
}
this . pendingClip = null ;
}
this . ctx . beginPath ( ) ;
} ,
getSinglePixelWidth : function CanvasGraphics _getSinglePixelWidth ( scale ) {
var inverse = this . ctx . mozCurrentTransformInverse ;
// max of the current horizontal and vertical scale
return Math . sqrt ( Math . max (
( inverse [ 0 ] * inverse [ 0 ] + inverse [ 1 ] * inverse [ 1 ] ) ,
( inverse [ 2 ] * inverse [ 2 ] + inverse [ 3 ] * inverse [ 3 ] ) ) ) ;
} ,
getCanvasPosition : function CanvasGraphics _getCanvasPosition ( x , y ) {
var transform = this . ctx . mozCurrentTransform ;
return [
transform [ 0 ] * x + transform [ 2 ] * y + transform [ 4 ] ,
transform [ 1 ] * x + transform [ 3 ] * y + transform [ 5 ]
] ;
}
} ;
for ( var op in OPS ) {
CanvasGraphics . prototype [ OPS [ op ] ] = CanvasGraphics . prototype [ op ] ;
}
return CanvasGraphics ;
} ) ( ) ;
PDFJS . disableFontFace = false ;
var FontLoader = {
insertRule : function fontLoaderInsertRule ( rule ) {
var styleElement = document . getElementById ( 'PDFJS_FONT_STYLE_TAG' ) ;
if ( ! styleElement ) {
styleElement = document . createElement ( 'style' ) ;
styleElement . id = 'PDFJS_FONT_STYLE_TAG' ;
document . documentElement . getElementsByTagName ( 'head' ) [ 0 ] . appendChild (
styleElement ) ;
}
var styleSheet = styleElement . sheet ;
styleSheet . insertRule ( rule , styleSheet . cssRules . length ) ;
} ,
clear : function fontLoaderClear ( ) {
var styleElement = document . getElementById ( 'PDFJS_FONT_STYLE_TAG' ) ;
if ( styleElement ) {
styleElement . parentNode . removeChild ( styleElement ) ;
}
} ,
get loadTestFont ( ) {
// This is a CFF font with 1 glyph for '.' that fills its entire width and
// height.
return shadow ( this , 'loadTestFont' , atob (
'T1RUTwALAIAAAwAwQ0ZGIDHtZg4AAAOYAAAAgUZGVE1lkzZwAAAEHAAAABxHREVGABQAFQ' +
'AABDgAAAAeT1MvMlYNYwkAAAEgAAAAYGNtYXABDQLUAAACNAAAAUJoZWFk/xVFDQAAALwA' +
'AAA2aGhlYQdkA+oAAAD0AAAAJGhtdHgD6AAAAAAEWAAAAAZtYXhwAAJQAAAAARgAAAAGbm' +
'FtZVjmdH4AAAGAAAAAsXBvc3T/hgAzAAADeAAAACAAAQAAAAEAALZRFsRfDzz1AAsD6AAA' +
'AADOBOTLAAAAAM4KHDwAAAAAA+gDIQAAAAgAAgAAAAAAAAABAAADIQAAAFoD6AAAAAAD6A' +
'ABAAAAAAAAAAAAAAAAAAAAAQAAUAAAAgAAAAQD6AH0AAUAAAKKArwAAACMAooCvAAAAeAA' +
'MQECAAACAAYJAAAAAAAAAAAAAQAAAAAAAAAAAAAAAFBmRWQAwAAuAC4DIP84AFoDIQAAAA' +
'AAAQAAAAAAAAAAACAAIAABAAAADgCuAAEAAAAAAAAAAQAAAAEAAAAAAAEAAQAAAAEAAAAA' +
'AAIAAQAAAAEAAAAAAAMAAQAAAAEAAAAAAAQAAQAAAAEAAAAAAAUAAQAAAAEAAAAAAAYAAQ' +
'AAAAMAAQQJAAAAAgABAAMAAQQJAAEAAgABAAMAAQQJAAIAAgABAAMAAQQJAAMAAgABAAMA' +
'AQQJAAQAAgABAAMAAQQJAAUAAgABAAMAAQQJAAYAAgABWABYAAAAAAAAAwAAAAMAAAAcAA' +
'EAAAAAADwAAwABAAAAHAAEACAAAAAEAAQAAQAAAC7//wAAAC7////TAAEAAAAAAAABBgAA' +
'AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAA' +
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' +
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' +
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' +
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAA' +
'AAAAD/gwAyAAAAAQAAAAAAAAAAAAAAAAAAAAABAAQEAAEBAQJYAAEBASH4DwD4GwHEAvgc' +
'A/gXBIwMAYuL+nz5tQXkD5j3CBLnEQACAQEBIVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWF' +
'hYWFhYWFhYAAABAQAADwACAQEEE/t3Dov6fAH6fAT+fPp8+nwHDosMCvm1Cvm1DAz6fBQA' +
'AAAAAAABAAAAAMmJbzEAAAAAzgTjFQAAAADOBOQpAAEAAAAAAAAADAAUAAQAAAABAAAAAg' +
'ABAAAAAAAAAAAD6AAAAAAAAA=='
) ) ;
} ,
loadTestFontId : 0 ,
loadingContext : {
requests : [ ] ,
nextRequestId : 0
} ,
isSyncFontLoadingSupported : ( function detectSyncFontLoadingSupport ( ) {
if ( isWorker )
return false ;
// User agent string sniffing is bad, but there is no reliable way to tell
// if font is fully loaded and ready to be used with canvas.
var userAgent = window . navigator . userAgent ;
var m = /Mozilla\/5.0.*?rv:(\d+).*? Gecko/ . exec ( userAgent ) ;
if ( m && m [ 1 ] >= 14 )
return true ;
// TODO other browsers
return false ;
} ) ( ) ,
bind : function fontLoaderBind ( fonts , callback ) {
assert ( ! isWorker , 'bind() shall be called from main thread' ) ;
var rules = [ ] , fontsToLoad = [ ] ;
for ( var i = 0 , ii = fonts . length ; i < ii ; i ++ ) {
var font = fonts [ i ] ;
// Add the font to the DOM only once or skip if the font
// is already loaded.
if ( font . attached || font . loading === false ) {
continue ;
}
font . attached = true ;
var rule = font . bindDOM ( ) ;
if ( rule ) {
rules . push ( rule ) ;
fontsToLoad . push ( font ) ;
}
}
var request = FontLoader . queueLoadingCallback ( callback ) ;
if ( rules . length > 0 && ! this . isSyncFontLoadingSupported ) {
FontLoader . prepareFontLoadEvent ( rules , fontsToLoad , request ) ;
} else {
request . complete ( ) ;
}
} ,
queueLoadingCallback : function FontLoader _queueLoadingCallback ( callback ) {
function LoadLoader _completeRequest ( ) {
assert ( ! request . end , 'completeRequest() cannot be called twice' ) ;
request . end = Date . now ( ) ;
// sending all completed requests in order how they were queued
while ( context . requests . length > 0 && context . requests [ 0 ] . end ) {
var otherRequest = context . requests . shift ( ) ;
setTimeout ( otherRequest . callback , 0 ) ;
}
}
var context = FontLoader . loadingContext ;
var requestId = 'pdfjs-font-loading-' + ( context . nextRequestId ++ ) ;
var request = {
id : requestId ,
complete : LoadLoader _completeRequest ,
callback : callback ,
started : Date . now ( )
} ;
context . requests . push ( request ) ;
return request ;
} ,
prepareFontLoadEvent : function fontLoaderPrepareFontLoadEvent ( rules ,
fonts ,
request ) {
/** Hack begin */
// There's currently no event when a font has finished downloading so the
// following code is a dirty hack to 'guess' when a font is
// ready. It's assumed fonts are loaded in order, so add a known test
// font after the desired fonts and then test for the loading of that
// test font.
function int32 ( data , offset ) {
return ( data . charCodeAt ( offset ) << 24 ) |
( data . charCodeAt ( offset + 1 ) << 16 ) |
( data . charCodeAt ( offset + 2 ) << 8 ) |
( data . charCodeAt ( offset + 3 ) & 0xff ) ;
}
function string32 ( value ) {
return String . fromCharCode ( ( value >> 24 ) & 0xff ) +
String . fromCharCode ( ( value >> 16 ) & 0xff ) +
String . fromCharCode ( ( value >> 8 ) & 0xff ) +
String . fromCharCode ( value & 0xff ) ;
}
function spliceString ( s , offset , remove , insert ) {
var chunk1 = data . substr ( 0 , offset ) ;
var chunk2 = data . substr ( offset + remove ) ;
return chunk1 + insert + chunk2 ;
}
var i , ii ;
var canvas = document . createElement ( 'canvas' ) ;
canvas . width = 1 ;
canvas . height = 1 ;
var ctx = canvas . getContext ( '2d' ) ;
var called = 0 ;
function isFontReady ( name , callback ) {
called ++ ;
// With setTimeout clamping this gives the font ~100ms to load.
if ( called > 30 ) {
warn ( 'Load test font never loaded.' ) ;
callback ( ) ;
return ;
}
ctx . font = '30px ' + name ;
ctx . fillText ( '.' , 0 , 20 ) ;
var imageData = ctx . getImageData ( 0 , 0 , 1 , 1 ) ;
if ( imageData . data [ 3 ] > 0 ) {
callback ( ) ;
return ;
}
setTimeout ( isFontReady . bind ( null , name , callback ) ) ;
}
var loadTestFontId = 'lt' + Date . now ( ) + this . loadTestFontId ++ ;
// Chromium seems to cache fonts based on a hash of the actual font data,
// so the font must be modified for each load test else it will appear to
// be loaded already.
// TODO: This could maybe be made faster by avoiding the btoa of the full
// font by splitting it in chunks before hand and padding the font id.
var data = this . loadTestFont ;
var COMMENT _OFFSET = 976 ; // has to be on 4 byte boundary (for checksum)
data = spliceString ( data , COMMENT _OFFSET , loadTestFontId . length ,
loadTestFontId ) ;
// CFF checksum is important for IE, adjusting it
var CFF _CHECKSUM _OFFSET = 16 ;
var XXXX _VALUE = 0x58585858 ; // the "comment" filled with 'X'
var checksum = int32 ( data , CFF _CHECKSUM _OFFSET ) ;
for ( i = 0 , ii = loadTestFontId . length - 3 ; i < ii ; i += 4 ) {
checksum = ( checksum - XXXX _VALUE + int32 ( loadTestFontId , i ) ) | 0 ;
}
if ( i < loadTestFontId . length ) { // align to 4 bytes boundary
checksum = ( checksum - XXXX _VALUE +
int32 ( loadTestFontId + 'XXX' , i ) ) | 0 ;
}
data = spliceString ( data , CFF _CHECKSUM _OFFSET , 4 , string32 ( checksum ) ) ;
var url = 'url(data:font/opentype;base64,' + btoa ( data ) + ');' ;
var rule = '@font-face { font-family:"' + loadTestFontId + '";src:' +
url + '}' ;
FontLoader . insertRule ( rule ) ;
var names = [ ] ;
for ( i = 0 , ii = fonts . length ; i < ii ; i ++ ) {
names . push ( fonts [ i ] . loadedName ) ;
}
names . push ( loadTestFontId ) ;
var div = document . createElement ( 'div' ) ;
div . setAttribute ( 'style' ,
'visibility: hidden;' +
'width: 10px; height: 10px;' +
'position: absolute; top: 0px; left: 0px;' ) ;
for ( i = 0 , ii = names . length ; i < ii ; ++ i ) {
var span = document . createElement ( 'span' ) ;
span . textContent = 'Hi' ;
span . style . fontFamily = names [ i ] ;
div . appendChild ( span ) ;
}
document . body . appendChild ( div ) ;
isFontReady ( loadTestFontId , function ( ) {
document . body . removeChild ( div ) ;
request . complete ( ) ;
} ) ;
/** Hack end */
}
} ;
var FontFace = ( function FontFaceClosure ( ) {
function FontFace ( name , file , properties ) {
this . compiledGlyphs = { } ;
if ( arguments . length === 1 ) {
// importing translated data
var data = arguments [ 0 ] ;
for ( var i in data ) {
this [ i ] = data [ i ] ;
}
return ;
}
}
FontFace . prototype = {
bindDOM : function FontFace _bindDOM ( ) {
if ( ! this . data )
return null ;
if ( PDFJS . disableFontFace ) {
this . disableFontFace = true ;
return null ;
}
var data = bytesToString ( this . data ) ;
var fontName = this . loadedName ;
// Add the font-face rule to the document
var url = ( 'url(data:' + this . mimetype + ';base64,' +
window . btoa ( data ) + ');' ) ;
var rule = '@font-face { font-family:"' + fontName + '";src:' + url + '}' ;
FontLoader . insertRule ( rule ) ;
if ( PDFJS . pdfBug && 'FontInspector' in globalScope &&
globalScope [ 'FontInspector' ] . enabled )
globalScope [ 'FontInspector' ] . fontAdded ( this , url ) ;
return rule ;
} ,
getPathGenerator : function ( objs , character ) {
if ( ! ( character in this . compiledGlyphs ) ) {
var js = objs . get ( this . loadedName + '_path_' + character ) ;
/*jshint -W054 */
this . compiledGlyphs [ character ] = new Function ( 'c' , 'size' , js ) ;
}
return this . compiledGlyphs [ character ] ;
}
} ;
return FontFace ;
} ) ( ) ;
} ) . call ( ( typeof window === 'undefined' ) ? this : window ) ;
if ( ! PDFJS . workerSrc && typeof document !== 'undefined' ) {
// workerSrc is not set -- using last script url to define default location
PDFJS . workerSrc = ( function ( ) {
'use strict' ;
var scriptTagContainer = document . body ||
document . getElementsByTagName ( 'head' ) [ 0 ] ;
var pdfjsSrc = scriptTagContainer . lastChild . src ;
return pdfjsSrc && pdfjsSrc . replace ( /\.js$/i , '.worker.js' ) ;
} ) ( ) ;
}
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/ * C o p y r i g h t 2 0 1 2 M o z i l l a F o u n d a t i o n
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
* /
/* globals VBArray, PDFJS */
'use strict' ;
// Initializing PDFJS global object here, it case if we need to change/disable
// some PDF.js features, e.g. range requests
if ( typeof PDFJS === 'undefined' ) {
( typeof window !== 'undefined' ? window : this ) . PDFJS = { } ;
}
// Checking if the typed arrays are supported
( function checkTypedArrayCompatibility ( ) {
if ( typeof Uint8Array !== 'undefined' ) {
// some mobile versions do not support subarray (e.g. safari 5 / iOS)
if ( typeof Uint8Array . prototype . subarray === 'undefined' ) {
Uint8Array . prototype . subarray = function subarray ( start , end ) {
return new Uint8Array ( this . slice ( start , end ) ) ;
} ;
Float32Array . prototype . subarray = function subarray ( start , end ) {
return new Float32Array ( this . slice ( start , end ) ) ;
} ;
}
// some mobile version might not support Float64Array
if ( typeof Float64Array === 'undefined' )
window . Float64Array = Float32Array ;
return ;
}
function subarray ( start , end ) {
return new TypedArray ( this . slice ( start , end ) ) ;
}
function setArrayOffset ( array , offset ) {
if ( arguments . length < 2 )
offset = 0 ;
for ( var i = 0 , n = array . length ; i < n ; ++ i , ++ offset )
this [ offset ] = array [ i ] & 0xFF ;
}
function TypedArray ( arg1 ) {
var result ;
if ( typeof arg1 === 'number' ) {
result = [ ] ;
for ( var i = 0 ; i < arg1 ; ++ i )
result [ i ] = 0 ;
} else if ( 'slice' in arg1 ) {
result = arg1 . slice ( 0 ) ;
} else {
result = [ ] ;
for ( var i = 0 , n = arg1 . length ; i < n ; ++ i ) {
result [ i ] = arg1 [ i ] ;
}
}
result . subarray = subarray ;
result . buffer = result ;
result . byteLength = result . length ;
result . set = setArrayOffset ;
if ( typeof arg1 === 'object' && arg1 . buffer )
result . buffer = arg1 . buffer ;
return result ;
}
window . Uint8Array = TypedArray ;
// we don't need support for set, byteLength for 32-bit array
// so we can use the TypedArray as well
window . Uint32Array = TypedArray ;
window . Int32Array = TypedArray ;
window . Uint16Array = TypedArray ;
window . Float32Array = TypedArray ;
window . Float64Array = TypedArray ;
} ) ( ) ;
// URL = URL || webkitURL
( function normalizeURLObject ( ) {
if ( ! window . URL ) {
window . URL = window . webkitURL ;
}
} ) ( ) ;
// Object.create() ?
( function checkObjectCreateCompatibility ( ) {
if ( typeof Object . create !== 'undefined' )
return ;
Object . create = function objectCreate ( proto ) {
function Constructor ( ) { }
Constructor . prototype = proto ;
return new Constructor ( ) ;
} ;
} ) ( ) ;
// Object.defineProperty() ?
( function checkObjectDefinePropertyCompatibility ( ) {
if ( typeof Object . defineProperty !== 'undefined' ) {
var definePropertyPossible = true ;
try {
// some browsers (e.g. safari) cannot use defineProperty() on DOM objects
// and thus the native version is not sufficient
Object . defineProperty ( new Image ( ) , 'id' , { value : 'test' } ) ;
// ... another test for android gb browser for non-DOM objects
var Test = function Test ( ) { } ;
Test . prototype = { get id ( ) { } } ;
Object . defineProperty ( new Test ( ) , 'id' ,
{ value : '' , configurable : true , enumerable : true , writable : false } ) ;
} catch ( e ) {
definePropertyPossible = false ;
}
if ( definePropertyPossible ) return ;
}
Object . defineProperty = function objectDefineProperty ( obj , name , def ) {
delete obj [ name ] ;
if ( 'get' in def )
obj . _ _defineGetter _ _ ( name , def [ 'get' ] ) ;
if ( 'set' in def )
obj . _ _defineSetter _ _ ( name , def [ 'set' ] ) ;
if ( 'value' in def ) {
obj . _ _defineSetter _ _ ( name , function objectDefinePropertySetter ( value ) {
this . _ _defineGetter _ _ ( name , function objectDefinePropertyGetter ( ) {
return value ;
} ) ;
return value ;
} ) ;
obj [ name ] = def . value ;
}
} ;
} ) ( ) ;
// Object.keys() ?
( function checkObjectKeysCompatibility ( ) {
if ( typeof Object . keys !== 'undefined' )
return ;
Object . keys = function objectKeys ( obj ) {
var result = [ ] ;
for ( var i in obj ) {
if ( obj . hasOwnProperty ( i ) )
result . push ( i ) ;
}
return result ;
} ;
} ) ( ) ;
// No readAsArrayBuffer ?
( function checkFileReaderReadAsArrayBuffer ( ) {
if ( typeof FileReader === 'undefined' )
return ; // FileReader is not implemented
var frPrototype = FileReader . prototype ;
// Older versions of Firefox might not have readAsArrayBuffer
if ( 'readAsArrayBuffer' in frPrototype )
return ; // readAsArrayBuffer is implemented
Object . defineProperty ( frPrototype , 'readAsArrayBuffer' , {
value : function fileReaderReadAsArrayBuffer ( blob ) {
var fileReader = new FileReader ( ) ;
var originalReader = this ;
fileReader . onload = function fileReaderOnload ( evt ) {
var data = evt . target . result ;
var buffer = new ArrayBuffer ( data . length ) ;
var uint8Array = new Uint8Array ( buffer ) ;
for ( var i = 0 , ii = data . length ; i < ii ; i ++ )
uint8Array [ i ] = data . charCodeAt ( i ) ;
Object . defineProperty ( originalReader , 'result' , {
value : buffer ,
enumerable : true ,
writable : false ,
configurable : true
} ) ;
var event = document . createEvent ( 'HTMLEvents' ) ;
event . initEvent ( 'load' , false , false ) ;
originalReader . dispatchEvent ( event ) ;
} ;
fileReader . readAsBinaryString ( blob ) ;
}
} ) ;
} ) ( ) ;
// No XMLHttpRequest.response ?
( function checkXMLHttpRequestResponseCompatibility ( ) {
var xhrPrototype = XMLHttpRequest . prototype ;
if ( ! ( 'overrideMimeType' in xhrPrototype ) ) {
// IE10 might have response, but not overrideMimeType
Object . defineProperty ( xhrPrototype , 'overrideMimeType' , {
value : function xmlHttpRequestOverrideMimeType ( mimeType ) { }
} ) ;
}
if ( 'response' in xhrPrototype ||
'mozResponseArrayBuffer' in xhrPrototype ||
'mozResponse' in xhrPrototype ||
'responseArrayBuffer' in xhrPrototype )
return ;
// IE9 ?
if ( typeof VBArray !== 'undefined' ) {
Object . defineProperty ( xhrPrototype , 'response' , {
get : function xmlHttpRequestResponseGet ( ) {
return new Uint8Array ( new VBArray ( this . responseBody ) . toArray ( ) ) ;
}
} ) ;
return ;
}
// other browsers
function responseTypeSetter ( ) {
// will be only called to set "arraybuffer"
this . overrideMimeType ( 'text/plain; charset=x-user-defined' ) ;
}
if ( typeof xhrPrototype . overrideMimeType === 'function' ) {
Object . defineProperty ( xhrPrototype , 'responseType' ,
{ set : responseTypeSetter } ) ;
}
function responseGetter ( ) {
var text = this . responseText ;
var i , n = text . length ;
var result = new Uint8Array ( n ) ;
for ( i = 0 ; i < n ; ++ i )
result [ i ] = text . charCodeAt ( i ) & 0xFF ;
return result ;
}
Object . defineProperty ( xhrPrototype , 'response' , { get : responseGetter } ) ;
} ) ( ) ;
// window.btoa (base64 encode function) ?
( function checkWindowBtoaCompatibility ( ) {
if ( 'btoa' in window )
return ;
var digits =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' ;
window . btoa = function windowBtoa ( chars ) {
var buffer = '' ;
var i , n ;
for ( i = 0 , n = chars . length ; i < n ; i += 3 ) {
var b1 = chars . charCodeAt ( i ) & 0xFF ;
var b2 = chars . charCodeAt ( i + 1 ) & 0xFF ;
var b3 = chars . charCodeAt ( i + 2 ) & 0xFF ;
var d1 = b1 >> 2 , d2 = ( ( b1 & 3 ) << 4 ) | ( b2 >> 4 ) ;
var d3 = i + 1 < n ? ( ( b2 & 0xF ) << 2 ) | ( b3 >> 6 ) : 64 ;
var d4 = i + 2 < n ? ( b3 & 0x3F ) : 64 ;
buffer += ( digits . charAt ( d1 ) + digits . charAt ( d2 ) +
digits . charAt ( d3 ) + digits . charAt ( d4 ) ) ;
}
return buffer ;
} ;
} ) ( ) ;
// window.atob (base64 encode function) ?
( function checkWindowAtobCompatibility ( ) {
if ( 'atob' in window )
return ;
// https://github.com/davidchambers/Base64.js
var digits =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' ;
window . atob = function ( input ) {
input = input . replace ( /=+$/ , '' ) ;
if ( input . length % 4 == 1 ) throw new Error ( 'bad atob input' ) ;
for (
// initialize result and counters
var bc = 0 , bs , buffer , idx = 0 , output = '' ;
// get next character
buffer = input . charAt ( idx ++ ) ;
// character found in table?
// initialize bit storage and add its ascii value
~ buffer && ( bs = bc % 4 ? bs * 64 + buffer : buffer ,
// and if not first of each 4 characters,
// convert the first 8 bits to one ascii character
bc ++ % 4 ) ? output += String . fromCharCode ( 255 & bs >> ( - 2 * bc & 6 ) ) : 0
) {
// try to find character in table (0-63, not found => -1)
buffer = digits . indexOf ( buffer ) ;
}
return output ;
} ;
} ) ( ) ;
// Function.prototype.bind ?
( function checkFunctionPrototypeBindCompatibility ( ) {
if ( typeof Function . prototype . bind !== 'undefined' )
return ;
Function . prototype . bind = function functionPrototypeBind ( obj ) {
var fn = this , headArgs = Array . prototype . slice . call ( arguments , 1 ) ;
var bound = function functionPrototypeBindBound ( ) {
var args = Array . prototype . concat . apply ( headArgs , arguments ) ;
return fn . apply ( obj , args ) ;
} ;
return bound ;
} ;
} ) ( ) ;
// HTMLElement dataset property
( function checkDatasetProperty ( ) {
var div = document . createElement ( 'div' ) ;
if ( 'dataset' in div )
return ; // dataset property exists
Object . defineProperty ( HTMLElement . prototype , 'dataset' , {
get : function ( ) {
if ( this . _dataset )
return this . _dataset ;
var dataset = { } ;
for ( var j = 0 , jj = this . attributes . length ; j < jj ; j ++ ) {
var attribute = this . attributes [ j ] ;
if ( attribute . name . substring ( 0 , 5 ) != 'data-' )
continue ;
var key = attribute . name . substring ( 5 ) . replace ( /\-([a-z])/g ,
function ( all , ch ) { return ch . toUpperCase ( ) ; } ) ;
dataset [ key ] = attribute . value ;
}
Object . defineProperty ( this , '_dataset' , {
value : dataset ,
writable : false ,
enumerable : false
} ) ;
return dataset ;
} ,
enumerable : true
} ) ;
} ) ( ) ;
// HTMLElement classList property
( function checkClassListProperty ( ) {
var div = document . createElement ( 'div' ) ;
if ( 'classList' in div )
return ; // classList property exists
function changeList ( element , itemName , add , remove ) {
var s = element . className || '' ;
var list = s . split ( /\s+/g ) ;
if ( list [ 0 ] === '' ) list . shift ( ) ;
var index = list . indexOf ( itemName ) ;
if ( index < 0 && add )
list . push ( itemName ) ;
if ( index >= 0 && remove )
list . splice ( index , 1 ) ;
element . className = list . join ( ' ' ) ;
return ( index >= 0 ) ;
}
var classListPrototype = {
add : function ( name ) {
changeList ( this . element , name , true , false ) ;
} ,
contains : function ( name ) {
return changeList ( this . element , name , false , false ) ;
} ,
remove : function ( name ) {
changeList ( this . element , name , false , true ) ;
} ,
toggle : function ( name ) {
changeList ( this . element , name , true , true ) ;
}
} ;
Object . defineProperty ( HTMLElement . prototype , 'classList' , {
get : function ( ) {
if ( this . _classList )
return this . _classList ;
var classList = Object . create ( classListPrototype , {
element : {
value : this ,
writable : false ,
enumerable : true
}
} ) ;
Object . defineProperty ( this , '_classList' , {
value : classList ,
writable : false ,
enumerable : false
} ) ;
return classList ;
} ,
enumerable : true
} ) ;
} ) ( ) ;
// Check console compatibility
( function checkConsoleCompatibility ( ) {
if ( ! ( 'console' in window ) ) {
window . console = {
log : function ( ) { } ,
error : function ( ) { } ,
warn : function ( ) { }
} ;
} else if ( ! ( 'bind' in console . log ) ) {
// native functions in IE9 might not have bind
console . log = ( function ( fn ) {
return function ( msg ) { return fn ( msg ) ; } ;
} ) ( console . log ) ;
console . error = ( function ( fn ) {
return function ( msg ) { return fn ( msg ) ; } ;
} ) ( console . error ) ;
console . warn = ( function ( fn ) {
return function ( msg ) { return fn ( msg ) ; } ;
} ) ( console . warn ) ;
}
} ) ( ) ;
// Check onclick compatibility in Opera
( function checkOnClickCompatibility ( ) {
// workaround for reported Opera bug DSK-354448:
// onclick fires on disabled buttons with opaque content
function ignoreIfTargetDisabled ( event ) {
if ( isDisabled ( event . target ) ) {
event . stopPropagation ( ) ;
}
}
function isDisabled ( node ) {
return node . disabled || ( node . parentNode && isDisabled ( node . parentNode ) ) ;
}
if ( navigator . userAgent . indexOf ( 'Opera' ) != - 1 ) {
// use browser detection since we cannot feature-check this bug
document . addEventListener ( 'click' , ignoreIfTargetDisabled , true ) ;
}
} ) ( ) ;
// Checks if navigator.language is supported
( function checkNavigatorLanguage ( ) {
if ( 'language' in navigator )
return ;
Object . defineProperty ( navigator , 'language' , {
get : function navigatorLanguage ( ) {
var language = navigator . userLanguage || 'en-US' ;
return language . substring ( 0 , 2 ) . toLowerCase ( ) +
language . substring ( 2 ) . toUpperCase ( ) ;
} ,
enumerable : true
} ) ;
} ) ( ) ;
( function checkRangeRequests ( ) {
// Safari has issues with cached range requests see:
// https://github.com/mozilla/pdf.js/issues/3260
// Last tested with version 6.0.4.
var isSafari = Object . prototype . toString . call (
window . HTMLElement ) . indexOf ( 'Constructor' ) > 0 ;
// Older versions of Android (pre 3.0) has issues with range requests, see:
// https://github.com/mozilla/pdf.js/issues/3381.
// Make sure that we only match webkit-based Android browsers,
// since Firefox/Fennec works as expected.
var regex = /Android\s[0-2][^\d]/ ;
var isOldAndroid = regex . test ( navigator . userAgent ) ;
if ( isSafari || isOldAndroid ) {
PDFJS . disableRange = true ;
}
} ) ( ) ;
// Check if the browser supports manipulation of the history.
( function checkHistoryManipulation ( ) {
if ( ! window . history . pushState ) {
PDFJS . disableHistory = true ;
}
} ) ( ) ;
2015-11-04 08:48:47 +01:00
! function ( t ) { function e ( r ) { if ( n [ r ] ) return n [ r ] . exports ; var i = n [ r ] = { exports : { } , id : r , loaded : ! 1 } ; return t [ r ] . call ( i . exports , i , i . exports , e ) , i . loaded = ! 0 , i . exports } var n = { } ; return e . m = t , e . c = n , e . p = "" , e ( 0 ) } ( [ function ( t , e , n ) { ( function ( e ) { t . exports = e . pdfMake = n ( 1 ) } ) . call ( e , function ( ) { return this } ( ) ) } , function ( t , e , n ) { ( function ( e ) { "use strict" ; function r ( t , e , n ) { this . docDefinition = t , this . fonts = e || s , this . vfs = n } var i = n ( 6 ) , o = n ( 105 ) , a = o . saveAs , s = { Roboto : { normal : "Roboto-Regular.ttf" , bold : "Roboto-Medium.ttf" , italics : "Roboto-Italic.ttf" , bolditalics : "Roboto-Italic.ttf" } } ; r . prototype . _createDoc = function ( t , n ) { var r = new i ( this . fonts ) ; r . fs . bindFS ( this . vfs ) ; var o , a = r . createPdfKitDocument ( this . docDefinition , t ) , s = [ ] ; a . on ( "data" , function ( t ) { s . push ( t ) } ) , a . on ( "end" , function ( ) { o = e . concat ( s ) , n ( o , a . _pdfMakePages ) } ) , a . end ( ) } , r . prototype . _getPages = function ( t , e ) { if ( ! e ) throw "getBuffer is an async method and needs a callback argument" ; this . _createDoc ( t , function ( t , n ) { e ( n ) } ) } , r . prototype . open = function ( t ) { var e = window . open ( "" , "_blank" ) ; try { this . getDataUrl ( function ( t ) { e . location . href = t } ) } catch ( n ) { throw e . close ( ) , n } } , r . prototype . print = function ( ) { this . getDataUrl ( function ( t ) { var e = document . createElement ( "iframe" ) ; e . style . position = "absolute" , e . style . left = "-99999px" , e . src = t , e . onload = function ( ) { function t ( ) { document . body . removeChild ( e ) , document . removeEventListener ( "click" , t ) } document . addEventListener ( "click" , t , ! 1 ) } , document . body . appendChild ( e ) } , { autoPrint : ! 0 } ) } , r . prototype . download = function ( t , e ) { "function" == typeof t && ( e = t , t = null ) , t = t || "file.pdf" , this . getBuffer ( function ( n ) { var r ; try { r = new Blob ( [ n ] , { type : "application/pdf" } ) } catch ( i ) { if ( "InvalidStateError" == i . name ) { var o = new Uint8Array ( n ) ; r = new Blob ( [ o . buffer ] , { type : "application/pdf" } ) } } if ( ! r ) throw "Could not generate blob" ; a ( r , t ) , "function" == typeof e && e ( ) } ) } , r . prototype . getBase64 = function ( t , e ) { if ( ! t ) throw "getBase64 is an async method and needs a callback argument" ; this . _createDoc ( e , function ( e ) { t ( e . toString ( "base64" ) ) } ) } , r . prototype . getDataUrl = function ( t , e ) { if ( ! t ) throw "getDataUrl is an async method and needs a callback argument" ; this . _createDoc ( e , function ( e ) { t ( "data:application/pdf;base64," + e . toString ( "base64" ) ) } ) } , r . prototype . getBuffer = function ( t , e ) { if ( ! t ) throw "getBuffer is an async method and needs a callback argument" ; this . _createDoc ( e , function ( e ) { t ( e ) } ) } , t . exports = { createPdf : function ( t ) { return new r ( t , window . pdfMake . fonts , window . pdfMake . vfs ) } } } ) . call ( e , n ( 2 ) . Buffer ) } , function ( t , e , n ) { ( function ( t , r ) { function i ( ) { function t ( ) { } try { var e = new Uint8Array ( 1 ) ; return e . foo = function ( ) { return 42 } , e . constructor = t , 42 === e . foo ( ) && e . constructor === t && "function" == typeof e . subarray && 0 === e . subarray ( 1 , 1 ) . byteLength } catch ( n ) { return ! 1 } } function o ( ) { return t . TYPED _ARRAY _SUPPORT ? 2147483647 : 1073741823 } function t ( e ) { return this instanceof t ? ( this . length = 0 , this . parent = void 0 , "number" == typeof e ? a ( this , e ) : "string" == typeof e ? s ( this , e , arguments . length > 1 ? arguments [ 1 ] : "utf8" ) : h ( this , e ) ) : arguments . length > 1 ? new t ( e , arguments [ 1 ] ) : new t ( e ) } function a ( e , n ) { if ( e = g ( e , 0 > n ? 0 : 0 | v ( n ) ) , ! t . TYPED _ARRAY _SUPPORT ) for ( var r = 0 ; n > r ; r ++ ) e [ r ] = 0 ; return e } function s ( t , e , n ) { ( "string" != typeof n || "" === n ) && ( n = "utf8" ) ; var r = 0 | y ( e , n ) ; return t = g ( t , r ) , t . write ( e , n ) , t } function h ( e , n ) { if ( t . isBuffer ( n ) ) return u ( e , n ) ; if ( V ( n ) ) return c ( e , n ) ; if ( null == n ) throw new TypeError ( "must start with number, buffer, array or string" ) ; if ( "undefined" != typeof ArrayBuffer ) { if ( n . buffer instanceof ArrayBuffer ) return l ( e , n ) ; if ( n instanceof ArrayBuffer ) return f ( e , n ) } return n . length ? d ( e , n ) : p ( e , n ) } function u ( t , e ) { var n = 0 | v ( e . length ) ; return t = g ( t , n ) , e . copy ( t , 0 , 0 , n ) , t } function c ( t , e ) { var n = 0 | v ( e . length ) ; t = g ( t , n ) ; for ( var r = 0 ; n > r ; r += 1 ) t [ r ] = 255 & e [ r ] ; return t } function l ( t , e ) { var n = 0 | v ( e . length ) ; t = g ( t , n ) ; for ( var r = 0 ; n > r ; r += 1 ) t [ r ] = 255 & e [ r ] ; return t } function f ( e , n ) { return t . TYPED _ARRAY _SUPPORT ? ( n . byteLength , e = t . _augment ( new Uint8Array ( n ) ) ) : e = l ( e , new Uint8Array ( n ) ) , e } function d ( t , e ) { var n = 0 | v ( e . length ) ; t = g ( t , n ) ; for ( var r = 0 ; n > r ; r += 1 ) t [ r ] = 255 & e [ r ] ; return t } function p ( t , e ) { var n , r = 0 ; "Buffer" === e . type && V ( e . data ) && ( n = e . data , r = 0 | v ( n . length ) ) , t = g ( t , r ) ; for ( var i = 0 ; r > i ; i += 1 ) t [ i ] = 255 & n [ i ] ; return t } function g ( e , n ) { t . TYPED _ARRAY _SUPPOR
2015-10-18 09:30:28 +02:00
* The buffer module from node . js , for the browser .
*
* @ author Feross Aboukhadijeh < feross @ feross . org > < http : //feross.org>
* @ license MIT
* /
2015-11-04 08:48:47 +01:00
var K = n ( 3 ) , X = n ( 4 ) , V = n ( 5 ) ; e . Buffer = t , e . SlowBuffer = m , e . INSPECT _MAX _BYTES = 50 , t . poolSize = 8192 ; var $ = { } ; t . TYPED _ARRAY _SUPPORT = void 0 !== r . TYPED _ARRAY _SUPPORT ? r . TYPED _ARRAY _SUPPORT : i ( ) , t . TYPED _ARRAY _SUPPORT && ( t . prototype . _ _proto _ _ = Uint8Array . prototype , t . _ _proto _ _ = Uint8Array ) , t . isBuffer = function ( t ) { return ! ( null == t || ! t . _isBuffer ) } , t . compare = function ( e , n ) { if ( ! t . isBuffer ( e ) || ! t . isBuffer ( n ) ) throw new TypeError ( "Arguments must be Buffers" ) ; if ( e === n ) return 0 ; for ( var r = e . length , i = n . length , o = 0 , a = Math . min ( r , i ) ; a > o && e [ o ] === n [ o ] ; ) ++ o ; return o !== a && ( r = e [ o ] , i = n [ o ] ) , i > r ? - 1 : r > i ? 1 : 0 } , t . isEncoding = function ( t ) { switch ( String ( t ) . toLowerCase ( ) ) { case "hex" : case "utf8" : case "utf-8" : case "ascii" : case "binary" : case "base64" : case "raw" : case "ucs2" : case "ucs-2" : case "utf16le" : case "utf-16le" : return ! 0 ; default : return ! 1 } } , t . concat = function ( e , n ) { if ( ! V ( e ) ) throw new TypeError ( "list argument must be an Array of Buffers." ) ; if ( 0 === e . length ) return new t ( 0 ) ; var r ; if ( void 0 === n ) for ( n = 0 , r = 0 ; r < e . length ; r ++ ) n += e [ r ] . length ; var i = new t ( n ) , o = 0 ; for ( r = 0 ; r < e . length ; r ++ ) { var a = e [ r ] ; a . copy ( i , o ) , o += a . length } return i } , t . byteLength = y , t . prototype . length = void 0 , t . prototype . parent = void 0 , t . prototype . toString = function ( ) { var t = 0 | this . length ; return 0 === t ? "" : 0 === arguments . length ? I ( this , 0 , t ) : _ . apply ( this , arguments ) } , t . prototype . equals = function ( e ) { if ( ! t . isBuffer ( e ) ) throw new TypeError ( "Argument must be a Buffer" ) ; return this === e ? ! 0 : 0 === t . compare ( this , e ) } , t . prototype . inspect = function ( ) { var t = "" , n = e . INSPECT _MAX _BYTES ; return this . length > 0 && ( t = this . toString ( "hex" , 0 , n ) . match ( /.{2}/g ) . join ( " " ) , this . length > n && ( t += " ... " ) ) , "<Buffer " + t + ">" } , t . prototype . compare = function ( e ) { if ( ! t . isBuffer ( e ) ) throw new TypeError ( "Argument must be a Buffer" ) ; return this === e ? 0 : t . compare ( this , e ) } , t . prototype . indexOf = function ( e , n ) { function r ( t , e , n ) { for ( var r = - 1 , i = 0 ; n + i < t . length ; i ++ ) if ( t [ n + i ] === e [ - 1 === r ? 0 : i - r ] ) { if ( - 1 === r && ( r = i ) , i - r + 1 === e . length ) return n + r } else r = - 1 ; return - 1 } if ( n > 2147483647 ? n = 2147483647 : - 2147483648 > n && ( n = - 2147483648 ) , n >>= 0 , 0 === this . length ) return - 1 ; if ( n >= this . length ) return - 1 ; if ( 0 > n && ( n = Math . max ( this . length + n , 0 ) ) , "string" == typeof e ) return 0 === e . length ? - 1 : String . prototype . indexOf . call ( this , e , n ) ; if ( t . isBuffer ( e ) ) return r ( this , e , n ) ; if ( "number" == typeof e ) return t . TYPED _ARRAY _SUPPORT && "function" === Uint8Array . prototype . indexOf ? Uint8Array . prototype . indexOf . call ( this , e , n ) : r ( this , [ e ] , n ) ; throw new TypeError ( "val must be string, number or Buffer" ) } , t . prototype . get = function ( t ) { return this . readUInt8 ( t ) } , t . prototype . set = function ( t , e ) { return this . writeUInt8 ( t , e ) } , t . prototype . write = function ( t , e , n , r ) { if ( void 0 === e ) r = "utf8" , n = this . length , e = 0 ; else if ( void 0 === n && "string" == typeof e ) r = e , n = this . length , e = 0 ; else if ( isFinite ( e ) ) e = 0 | e , isFinite ( n ) ? ( n = 0 | n , void 0 === r && ( r = "utf8" ) ) : ( r = n , n = void 0 ) ; else { var i = r ; r = e , e = 0 | n , n = i } var o = this . length - e ; if ( ( void 0 === n || n > o ) && ( n = o ) , t . length > 0 && ( 0 > n || 0 > e ) || e > this . length ) throw new RangeError ( "attempt to write outside buffer bounds" ) ; r || ( r = "utf8" ) ; for ( var a = ! 1 ; ; ) switch ( r ) { case "hex" : return w ( this , t , e , n ) ; case "utf8" : case "utf-8" : return b ( this , t , e , n ) ; case "ascii" : return x ( this , t , e , n ) ; case "binary" : return S ( this , t , e , n ) ; case "base64" : return k ( this , t , e , n ) ; case "ucs2" : case "ucs-2" : case "utf16le" : case "utf-16le" : return E ( this , t , e , n ) ; default : if ( a ) throw new TypeError ( "Unknown encoding: " + r ) ; r = ( "" + r ) . toLowerCase ( ) , a = ! 0 } } , t . prototype . toJSON = function ( ) { return { type : "Buffer" , data : Array . prototype . slice . call ( this . _arr || this , 0 ) } } ; var J = 4096 ; t . prototype . slice = function ( e , n ) { var r = this . length ; e = ~ ~ e , n = void 0 === n ? r : ~ ~ n , 0 > e ? ( e += r , 0 > e && ( e = 0 ) ) : e > r && ( e = r ) , 0 > n ? ( n += r , 0 > n && ( n = 0 ) ) : n > r && ( n = r ) , e > n && ( n = e ) ; var i ; if ( t . TYPED _ARRAY _SUPPORT ) i = t . _augment ( this . subarray ( e , n ) ) ; else { var o = n - e ; i = new t ( o , void 0 ) ; for ( var a = 0 ; o > a ; a ++ ) i [ a ] = this [ a + e ] } return i . length && ( i . parent = this . parent || this ) , i } , t . prototype . readUIntLE = function ( t , e , n ) { t = 0 | t , e = 0 | e , n || O ( t , e , this . length ) ; for ( var r = this [ t ] , i = 1 , o = 0 ; ++ o < e && ( i *= 256 ) ; ) r += this [ t + o ] * i ; return r } , t . prototype . readUIntBE = function ( t , e , n ) { t = 0 | t , e = 0 | e , n || O ( t , e , this . length ) ; for ( var r = this [ t + -- e ] , i = 1 ; e > 0 && ( i *= 256 ) ; ) r += this [ t + -- e ] * i ; return r } , t . prototype . readUInt8 = function ( t , e ) { return e || O ( t , 1 , this . length ) , this [ t ] } , t . prototype . readUInt1
return new t ( e [ 0 ] , e [ 1 ] , e [ 2 ] , e [ 3 ] , e [ 4 ] ) ; case 6 : return new t ( e [ 0 ] , e [ 1 ] , e [ 2 ] , e [ 3 ] , e [ 4 ] , e [ 5 ] ) ; case 7 : return new t ( e [ 0 ] , e [ 1 ] , e [ 2 ] , e [ 3 ] , e [ 4 ] , e [ 5 ] , e [ 6 ] ) } var n = Da ( t . prototype ) , r = t . apply ( n , e ) ; return Mi ( r ) ? r : n } } function yn ( t ) { function e ( n , r , i ) { i && Qn ( n , r , i ) && ( r = I ) ; var o = Pn ( n , t , I , I , I , I , I , r ) ; return o . placeholder = e . placeholder , o } return e } function _n ( t , e ) { return mi ( function ( n ) { var r = n [ 0 ] ; return null == r ? r : ( n . push ( e ) , t . apply ( I , n ) ) } ) } function wn ( t , e ) { return function ( n , r , i ) { if ( i && Qn ( n , r , i ) && ( r = I ) , r = Nn ( r , i , 3 ) , 1 == r . length ) { n = Ls ( n ) ? n : cr ( n ) ; var o = ae ( n , r , t , e ) ; if ( ! n . length || o !== e ) return o } return Ee ( n , r , t , e ) } } function bn ( t , e ) { return function ( n , r , i ) { if ( r = Nn ( r , i , 3 ) , Ls ( n ) ) { var o = a ( n , r , e ) ; return o > - 1 ? n [ o ] : I } return Ae ( n , r , t ) } } function xn ( t ) { return function ( e , n , r ) { return e && e . length ? ( n = Nn ( n , r , 3 ) , a ( e , n , t ) ) : - 1 } } function Sn ( t ) { return function ( e , n , r ) { return n = Nn ( n , r , 3 ) , Ae ( e , n , t , ! 0 ) } } function kn ( t ) { return function ( ) { for ( var e , n = arguments . length , i = t ? n : - 1 , o = 0 , a = No ( n ) ; t ? i -- : ++ i < n ; ) { var s = a [ o ++ ] = arguments [ i ] ; if ( "function" != typeof s ) throw new Vo ( G ) ; ! e && r . prototype . thru && "wrapper" == jn ( s ) && ( e = new r ( [ ] , ! 0 ) ) } for ( i = e ? - 1 : n ; ++ i < n ; ) { s = a [ i ] ; var h = jn ( s ) , u = "wrapper" == h ? Na ( s ) : I ; e = u && er ( u [ 0 ] ) && u [ 1 ] == ( U | B | M | P ) && ! u [ 4 ] . length && 1 == u [ 9 ] ? e [ jn ( u [ 0 ] ) ] . apply ( e , u [ 3 ] ) : 1 == s . length && er ( s ) ? e [ h ] ( ) : e . thru ( s ) } return function ( ) { var t = arguments , r = t [ 0 ] ; if ( e && 1 == t . length && Ls ( r ) && r . length >= j ) return e . plant ( r ) . value ( ) ; for ( var i = 0 , o = n ? a [ i ] . apply ( this , t ) : r ; ++ i < n ; ) o = a [ i ] . call ( this , o ) ; return o } } } function En ( t , e ) { return function ( n , r , i ) { return "function" == typeof r && i === I && Ls ( n ) ? t ( n , r ) : e ( n , an ( r , i , 3 ) ) } } function Cn ( t ) { return function ( e , n , r ) { return ( "function" != typeof n || r !== I ) && ( n = an ( n , r , 3 ) ) , t ( e , n , to ) } } function In ( t ) { return function ( e , n , r ) { return ( "function" != typeof n || r !== I ) && ( n = an ( n , r , 3 ) ) , t ( e , n ) } } function An ( t ) { return function ( e , n , r ) { var i = { } ; return n = Nn ( n , r , 3 ) , Te ( e , function ( e , r , o ) { var a = n ( e , r , o ) ; r = t ? a : r , e = t ? e : a , i [ r ] = e } ) , i } } function Ln ( t ) { return function ( e , n , r ) { return e = u ( e ) , ( t ? e : "" ) + On ( e , n , r ) + ( t ? "" : e ) } } function Rn ( t ) { var e = mi ( function ( n , r ) { var i = b ( r , e . placeholder ) ; return Pn ( n , t , I , r , i ) } ) ; return e } function Tn ( t , e ) { return function ( n , r , i , o ) { var a = arguments . length < 3 ; return "function" == typeof r && o === I && Ls ( n ) ? t ( n , r , i , a ) : qe ( n , Nn ( r , o , 4 ) , i , a , e ) } } function Bn ( t , e , n , r , i , o , a , s , h , u ) { function c ( ) { for ( var y = arguments . length , _ = y , w = No ( y ) ; _ -- ; ) w [ _ ] = arguments [ _ ] ; if ( r && ( w = hn ( w , r , i ) ) , o && ( w = un ( w , o , a ) ) , p || v ) { var x = c . placeholder , S = b ( w , x ) ; if ( y -= S . length , u > y ) { var k = s ? te ( s ) : I , E = xa ( u - y , 0 ) , C = p ? S : I , A = p ? I : S , T = p ? w : I , B = p ? I : w ; e |= p ? M : D , e &= ~ ( p ? D : M ) , g || ( e &= ~ ( L | R ) ) ; var O = [ t , e , n , T , C , B , A , k , h , E ] , U = Bn . apply ( I , O ) ; return er ( t ) && Ha ( U , O ) , U . placeholder = x , U } } var P = f ? n : this , z = d ? P [ t ] : t ; return s && ( w = hr ( w , s ) ) , l && h < w . length && ( w . length = h ) , this && this !== re && this instanceof c && ( z = m || mn ( t ) ) , z . apply ( P , w ) } var l = e & U , f = e & L , d = e & R , p = e & B , g = e & T , v = e & O , m = d ? I : mn ( t ) ; return c } function On ( t , e , n ) { var r = t . length ; if ( e = + e , r >= e || ! wa ( e ) ) return "" ; var i = e - r ; return n = null == n ? " " : n + "" , mo ( n , va ( i / n . length ) ) . slice ( 0 , i ) } function Mn ( t , e , n , r ) { function i ( ) { for ( var e = - 1 , s = arguments . length , h = - 1 , u = r . length , c = No ( u + s ) ; ++ h < u ; ) c [ h ] = r [ h ] ; for ( ; s -- ; ) c [ h ++ ] = arguments [ ++ e ] ; var l = this && this !== re && this instanceof i ? a : t ; return l . apply ( o ? n : this , c ) } var o = e & L , a = mn ( t ) ; return i } function Dn ( t ) { var e = Go [ t ] ; return function ( t , n ) { return n = n === I ? 0 : + n || 0 , n ? ( n = ua ( 10 , n ) , e ( t * n ) / n ) : e ( t ) } } function Un ( t ) { return function ( e , n , r , i ) { var o = Nn ( r ) ; return null == r && o === we ? rn ( e , n , t ) : on ( e , n , o ( r , i , 1 ) , t ) } } function Pn ( t , e , n , r , i , o , a , s ) { var h = e & R ; if ( ! h && "function" != typeof t ) throw new Vo ( G ) ; var u = r ? r . length : 0 ; if ( u || ( e &= ~ ( M | D ) , r = i = I ) , u -= i ? i . length : 0 , e & D ) { var c = r , l = i ; r = i = I } var f = h ? I : Na ( t ) , d = [ t , e , n , r , i , c , l , o , a , s ] ; if ( f && ( ir ( d , f ) , e = d [ 1 ] , s = d [ 9 ] ) , d [ 9 ] = null == s ? h ? 0 : t . length : xa ( s - u , 0 ) || 0 , e == L ) var p = pn ( d [ 0 ] , d [ 2 ] ) ; else p = e != M && e != ( L | M ) || d [ 4 ] . length ? Bn . apply ( I , d ) : Mn . apply ( I , d ) ; var g = f ? Wa : Ha ; return g ( p , d ) } function zn ( t , e , n , r , i , o , a ) { var s = - 1 , h = t . length , u = e . length ; if ( h != u && ! ( i && u > h ) ) return ! 1 ; for ( ; ++ s < h ; ) { var c = t [ s ] , l = e [ s ] , f = r ? r ( i ? l : c , i ? c : l , s ) : I ; if ( f !== I ) { if ( f ) continue ; return ! 1 } if ( i ) { if ( ! fe ( e , function ( t ) { return c === t || n ( c , t , r , i , o , a ) } ) ) return ! 1 } else if ( c !== l && ! n ( c , l , r , i , o , a ) ) return ! 1 } return ! 0 } function Fn ( t , e , n ) { switch ( n ) { case X : case V : return + t == + e ; case $ : return
} } ) , ee ( [ "pluck" , "where" ] , function ( t , e ) { var n = e ? "filter" : "map" , r = e ? Fe : Mo ; i . prototype [ t ] = function ( t ) { return this [ n ] ( r ( t ) ) } } ) , i . prototype . compact = function ( ) { return this . filter ( Ao ) } , i . prototype . reject = function ( t , e ) { return t = Nn ( t , e , 1 ) , this . filter ( function ( e ) { return ! t ( e ) } ) } , i . prototype . slice = function ( t , e ) { t = null == t ? 0 : + t || 0 ; var n = this ; return n . _ _filtered _ _ && ( t > 0 || 0 > e ) ? new i ( n ) : ( 0 > t ? n = n . takeRight ( - t ) : t && ( n = n . drop ( t ) ) , e !== I && ( e = + e || 0 , n = 0 > e ? n . dropRight ( - e ) : n . take ( e - t ) ) , n ) } , i . prototype . takeRightWhile = function ( t , e ) { return this . reverse ( ) . takeWhile ( t , e ) . reverse ( ) } , i . prototype . toArray = function ( ) { return this . take ( Aa ) } , Te ( i . prototype , function ( t , n ) { var o = /^(?:filter|map|reject)|While$/ . test ( n ) , a = /^(?:first|last)$/ . test ( n ) , s = e [ a ? "take" + ( "last" == n ? "Right" : "" ) : n ] ; s && ( e . prototype [ n ] = function ( ) { var e = a ? [ 1 ] : arguments , n = this . _ _chain _ _ , h = this . _ _wrapped _ _ , u = ! ! this . _ _actions _ _ . length , c = h instanceof i , l = e [ 0 ] , f = c || Ls ( h ) ; f && o && "function" == typeof l && 1 != l . length && ( c = f = ! 1 ) ; var d = function ( t ) { return a && n ? s ( t , 1 ) [ 0 ] : s . apply ( I , ue ( [ t ] , e ) ) } , p = { func : Hr , args : [ d ] , thisArg : I } , g = c && ! u ; if ( a && ! n ) return g ? ( h = h . clone ( ) , h . _ _actions _ _ . push ( p ) , t . call ( h ) ) : s . call ( I , this . value ( ) ) [ 0 ] ; if ( ! a && f ) { h = g ? h : new i ( this ) ; var v = t . apply ( h , e ) ; return v . _ _actions _ _ . push ( p ) , new r ( v , n ) } return this . thru ( d ) } ) } ) , ee ( [ "join" , "pop" , "push" , "replace" , "shift" , "sort" , "splice" , "split" , "unshift" ] , function ( t ) { var n = ( /^(?:replace|split)$/ . test ( t ) ? Qo : $o ) [ t ] , r = /^(?:push|sort|unshift)$/ . test ( t ) ? "tap" : "thru" , i = /^(?:join|pop|replace|shift)$/ . test ( t ) ; e . prototype [ t ] = function ( ) { var t = arguments ; return i && ! this . _ _chain _ _ ? n . apply ( this . value ( ) , t ) : this [ r ] ( function ( e ) { return n . apply ( e , t ) } ) } } ) , Te ( i . prototype , function ( t , n ) { var r = e [ n ] ; if ( r ) { var i = r . name , o = Ma [ i ] || ( Ma [ i ] = [ ] ) ; o . push ( { name : n , func : r } ) } } ) , Ma [ Bn ( I , R ) . name ] = [ { name : "wrapper" , func : I } ] , i . prototype . clone = w , i . prototype . reverse = Q , i . prototype . value = rt , e . prototype . chain = Zr , e . prototype . commit = Gr , e . prototype . concat = es , e . prototype . plant = Yr , e . prototype . reverse = qr , e . prototype . toString = Kr , e . prototype . run = e . prototype . toJSON = e . prototype . valueOf = e . prototype . value = Xr , e . prototype . collect = e . prototype . map , e . prototype . head = e . prototype . first , e . prototype . select = e . prototype . filter , e . prototype . tail = e . prototype . rest , e } var I , A = "3.10.1" , L = 1 , R = 2 , T = 4 , B = 8 , O = 16 , M = 32 , D = 64 , U = 128 , P = 256 , z = 30 , F = "..." , W = 150 , N = 16 , j = 200 , H = 1 , Z = 2 , G = "Expected a function" , Y = "__lodash_placeholder__" , q = "[object Arguments]" , K = "[object Array]" , X = "[object Boolean]" , V = "[object Date]" , $ = "[object Error]" , J = "[object Function]" , Q = "[object Map]" , tt = "[object Number]" , et = "[object Object]" , nt = "[object RegExp]" , rt = "[object Set]" , it = "[object String]" , ot = "[object WeakMap]" , at = "[object ArrayBuffer]" , st = "[object Float32Array]" , ht = "[object Float64Array]" , ut = "[object Int8Array]" , ct = "[object Int16Array]" , lt = "[object Int32Array]" , ft = "[object Uint8Array]" , dt = "[object Uint8ClampedArray]" , pt = "[object Uint16Array]" , gt = "[object Uint32Array]" , vt = /\b__p \+= '';/g , mt = /\b(__p \+=) '' \+/g , yt = /(__e\(.*?\)|\b__t\)) \+\n'';/g , _t = /&(?:amp|lt|gt|quot|#39|#96);/g , wt = /[&<>"'`]/g , bt = RegExp ( _t . source ) , xt = RegExp ( wt . source ) , St = /<%-([\s\S]+?)%>/g , kt = /<%([\s\S]+?)%>/g , Et = /<%=([\s\S]+?)%>/g , Ct = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/ , It = /^\w*$/ , At = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g , Lt = /^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u2028\u2029])/g , Rt = RegExp ( Lt . source ) , Tt = /[\u0300-\u036f\ufe20-\ufe23]/g , Bt = /\\(\\)?/g , Ot = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g , Mt = /\w*$/ , Dt = /^0[xX]/ , Ut = /^\[object .+?Constructor\]$/ , Pt = /^\d+$/ , zt = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g , Ft = /($^)/ , Wt = /['\n\r\u2028\u2029\\]/g , Nt = function ( ) { var t = "[A-Z\\xc0-\\xd6\\xd8-\\xde]" , e = "[a-z\\xdf-\\xf6\\xf8-\\xff]+" ; return RegExp ( t + "+(?=" + t + e + ")|" + t + "?" + e + "|" + t + "+|[0-9]+" , "g" ) } ( ) , jt = [ "Array" , "ArrayBuffer" , "Date" , "Error" , "Float32Array" , "Float64Array" , "Function" , "Int8Array" , "Int16Array" , "Int32Array" , "Math" , "Number" , "Object" , "RegExp" , "Set" , "String" , "_" , "clearTimeout" , "isFinite" , "parseFloat" , "parseInt" , "setTimeout" , "TypeError" , "Uint8Array" , "Uint8ClampedArray" , "Uint16Array" , "Uint32Array" , "WeakMap" ] , Ht = - 1 , Zt = { } ; Zt [ st ] = Zt [ ht ] = Zt [ ut ] = Zt [ ct ] = Zt [ lt ] = Zt [ ft ] = Zt [
_ [ b ] = w , b = 2 * b ^ ( b >= 128 ? 285 : 0 ) ; for ( var x = [ [ ] ] , w = 0 ; 30 > w ; ++ w ) { for ( var S = x [ w ] , k = [ ] , E = 0 ; w >= E ; ++ E ) { var C = w > E ? y [ S [ E ] ] : 0 , I = y [ ( w + ( S [ E - 1 ] || 0 ) ) % 255 ] ; k . push ( _ [ C ^ I ] ) } x . push ( k ) } for ( var A = { } , w = 0 ; 45 > w ; ++ w ) A [ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:" . charAt ( w ) ] = w ; var L = [ function ( t , e ) { return ( t + e ) % 2 === 0 } , function ( t , e ) { return t % 2 === 0 } , function ( t , e ) { return e % 3 === 0 } , function ( t , e ) { return ( t + e ) % 3 === 0 } , function ( t , e ) { return ( ( t / 2 | 0 ) + ( e / 3 | 0 ) ) % 2 === 0 } , function ( t , e ) { return t * e % 2 + t * e % 3 === 0 } , function ( t , e ) { return ( t * e % 2 + t * e % 3 ) % 2 === 0 } , function ( t , e ) { return ( ( t + e ) % 2 + t * e % 3 ) % 2 === 0 } ] , R = function ( t ) { return t > 6 } , T = function ( t ) { return 4 * t + 17 } , B = function ( t ) { var e = o [ t ] , n = 16 * t * t + 128 * t + 64 ; return R ( t ) && ( n -= 36 ) , e [ 2 ] . length && ( n -= 25 * e [ 2 ] . length * e [ 2 ] . length - 10 * e [ 2 ] . length - 55 ) , n } , O = function ( t , e ) { var n = - 8 & B ( t ) , r = o [ t ] ; return n -= 8 * r [ 0 ] [ e ] * r [ 1 ] [ e ] } , M = function ( t , e ) { switch ( e ) { case s : return 10 > t ? 10 : 27 > t ? 12 : 14 ; case h : return 10 > t ? 9 : 27 > t ? 11 : 13 ; case u : return 10 > t ? 8 : 16 ; case c : return 10 > t ? 8 : 27 > t ? 10 : 12 } } , D = function ( t , e , n ) { var r = O ( t , n ) - 4 - M ( t , e ) ; switch ( e ) { case s : return 3 * ( r / 10 | 0 ) + ( 4 > r % 10 ? 0 : 7 > r % 10 ? 1 : 2 ) ; case h : return 2 * ( r / 11 | 0 ) + ( 6 > r % 11 ? 0 : 1 ) ; case u : return r / 8 | 0 ; case c : return r / 13 | 0 } } , U = function ( t , e ) { switch ( t ) { case s : return e . match ( l ) ? e : null ; case h : return e . match ( f ) ? e . toUpperCase ( ) : null ; case u : if ( "string" == typeof e ) { for ( var n = [ ] , r = 0 ; r < e . length ; ++ r ) { var i = e . charCodeAt ( r ) ; 128 > i ? n . push ( i ) : 2048 > i ? n . push ( 192 | i >> 6 , 128 | 63 & i ) : 65536 > i ? n . push ( 224 | i >> 12 , 128 | i >> 6 & 63 , 128 | 63 & i ) : n . push ( 240 | i >> 18 , 128 | i >> 12 & 63 , 128 | i >> 6 & 63 , 128 | 63 & i ) } return n } return e } } , P = function ( t , e , n , r ) { var i = [ ] , o = 0 , c = 8 , l = n . length , f = function ( t , e ) { if ( e >= c ) { for ( i . push ( o | t >> ( e -= c ) ) ; e >= 8 ; ) i . push ( t >> ( e -= 8 ) & 255 ) ; o = 0 , c = 8 } e > 0 && ( o |= ( t & ( 1 << e ) - 1 ) << ( c -= e ) ) } , d = M ( t , e ) ; switch ( f ( e , 4 ) , f ( l , d ) , e ) { case s : for ( var p = 2 ; l > p ; p += 3 ) f ( parseInt ( n . substring ( p - 2 , p + 1 ) , 10 ) , 10 ) ; f ( parseInt ( n . substring ( p - 2 ) , 10 ) , [ 0 , 4 , 7 ] [ l % 3 ] ) ; break ; case h : for ( var p = 1 ; l > p ; p += 2 ) f ( 45 * A [ n . charAt ( p - 1 ) ] + A [ n . charAt ( p ) ] , 11 ) ; l % 2 == 1 && f ( A [ n . charAt ( p - 1 ) ] , 6 ) ; break ; case u : for ( var p = 0 ; l > p ; ++ p ) f ( n [ p ] , 8 ) } for ( f ( a , 4 ) , 8 > c && i . push ( o ) ; i . length + 1 < r ; ) i . push ( 236 , 17 ) ; return i . length < r && i . push ( 236 ) , i } , z = function ( t , e ) { for ( var n = t . slice ( 0 ) , r = t . length , i = e . length , o = 0 ; i > o ; ++ o ) n . push ( 0 ) ; for ( var o = 0 ; r > o ; ) { var a = _ [ n [ o ++ ] ] ; if ( a >= 0 ) for ( var s = 0 ; i > s ; ++ s ) n [ o + s ] ^= y [ ( a + e [ s ] ) % 255 ] } return n . slice ( r ) } , F = function ( t , e , n ) { for ( var r = [ ] , i = t . length / e | 0 , o = 0 , a = e - t . length % e , s = 0 ; a > s ; ++ s ) r . push ( o ) , o += i ; for ( var s = a ; e > s ; ++ s ) r . push ( o ) , o += i + 1 ; r . push ( o ) ; for ( var h = [ ] , s = 0 ; e > s ; ++ s ) h . push ( z ( t . slice ( r [ s ] , r [ s + 1 ] ) , n ) ) ; for ( var u = [ ] , c = t . length / e | 0 , s = 0 ; c > s ; ++ s ) for ( var l = 0 ; e > l ; ++ l ) u . push ( t [ r [ l ] + s ] ) ; for ( var l = a ; e > l ; ++ l ) u . push ( t [ r [ l + 1 ] - 1 ] ) ; for ( var s = 0 ; s < n . length ; ++ s ) for ( var l = 0 ; e > l ; ++ l ) u . push ( h [ l ] [ s ] ) ; return u } , W = function ( t , e , n , r ) { for ( var i = t << r , o = e - 1 ; o >= 0 ; -- o ) i >> r + o & 1 && ( i ^= n << o ) ; return t << r | i } , N = function ( t ) { for ( var e = o [ t ] , n = T ( t ) , r = [ ] , i = [ ] , a = 0 ; n > a ; ++ a ) r . push ( [ ] ) , i . push ( [ ] ) ; var s = function ( t , e , n , o , a ) { for ( var s = 0 ; n > s ; ++ s ) for ( var h = 0 ; o > h ; ++ h ) r [ t + s ] [ e + h ] = a [ s ] >> h & 1 , i [ t + s ] [ e + h ] = 1 } ; s ( 0 , 0 , 9 , 9 , [ 127 , 65 , 93 , 93 , 93 , 65 , 383 , 0 , 64 ] ) , s ( n - 8 , 0 , 8 , 9 , [ 256 , 127 , 65 , 93 , 93 , 93 , 65 , 127 ] ) , s ( 0 , n - 8 , 9 , 8 , [ 254 , 130 , 186 , 186 , 186 , 130 , 254 , 0 , 0 ] ) ; for ( var a = 9 ; n - 8 > a ; ++ a ) r [ 6 ] [ a ] = r [ a ] [ 6 ] = 1 & ~ a , i [ 6 ] [ a ] = i [ a ] [ 6 ] = 1 ; for ( var h = e [ 2 ] , u = h . length , a = 0 ; u > a ; ++ a ) for ( var c = 0 === a || a === u - 1 ? 1 : 0 , l = 0 === a ? u - 1 : u , f = c ; l > f ; ++ f ) s ( h [ a ] , h [ f ] , 5 , 5 , [ 31 , 17 , 21 , 17 , 31 ] ) ; if ( R ( t ) ) for ( var d = W ( t , 6 , 7973 , 12 ) , p = 0 , a = 0 ; 6 > a ; ++ a ) for ( var f = 0 ; 3 > f ; ++ f ) r [ a ] [ n - 11 + f ] = r [ n - 11 + f ] [ a ] = d >> p ++ & 1 , i [ a ] [ n - 11 + f ] = i [ n - 11 + f ] [ a ] = 1 ; return { matrix : r , reserved : i } } , j = function ( t , e , n ) { for ( var r = t . length , i = 0 , o = - 1 , a = r - 1 ; a >= 0 ; a -= 2 ) { 6 == a && -- a ; for ( var s = 0 > o ? r - 1 : 0 , h = 0 ; r > h ; ++ h ) { for ( var u = a ; u > a - 2 ; -- u ) e [ s ] [ u ] || ( t [ s ] [ u ] = n [ i >> 3 ] >> ( 7 & ~ i ) & 1 , ++ i ) ; s += o } o = - o } return t } , H = function ( t , e , n ) { for ( var r = L [ n ] , i = t . length , o = 0 ; i > o ; ++ o ) for ( var a = 0 ; i > a ; ++ a ) e [ o ] [ a ] || ( t [ o ] [ a ] ^= r ( o , a ) ) ; return t } , Z = function ( t , e , n , r ) { for ( var i = t . length , o = 21522 ^ W ( n << 3 | r , 5 , 1335 , 10 ) , a = 0 ; 15 > a ; ++ a ) { var s = [ 0 , 1 , 2 , 3 , 4 , 5 , 7 , 8 , i - 7 , i - 6 , i - 5 , i - 4 , i - 3 , i - 2 , i - 1 ] [ a ] , h = [ i - 1 , i - 2 , i - 3 , i - 4 , i - 5 , i - 6 , i - 7 , i - 8 , 7 , 5 , 4 , 3 , 2 , 1 , 0 ] [ a ] ; t [ s ] [ 8 ] = t [ 8 ] [ h ] = o >> a & 1 } return t } , G = function ( t ) { for ( var e = 3 , n = 3 , r = 40 , i = 10 , o = function ( t ) { for ( var n = 0 , i = 0 ; i < t . length ; ++ i ) t [ i ] >= 5 && ( n += e + ( t [ i ] - 5 ) ) ; for ( var i = 5 ; i < t . length ; i += 2 ) { var o = t [ i ] ; t [ i - 1 ] == o && t [ i - 2 ] == 3 * o && t [ i - 3 ] == o && t [ i - 4 ] == o && ( t [ i - 5 ] >= 4 * o || t [ i +
L ( "pipeOnDrain" , e . awaitDrain ) , e . awaitDrain && e . awaitDrain -- , 0 === e . awaitDrain && E . listenerCount ( t , "data" ) && ( e . flowing = ! 0 , y ( t ) ) } } function v ( t , n ) { n . resumeScheduled || ( n . resumeScheduled = ! 0 , e . nextTick ( function ( ) { m ( t , n ) } ) ) } function m ( t , e ) { e . resumeScheduled = ! 1 , t . emit ( "resume" ) , y ( t ) , e . flowing && ! e . reading && t . read ( 0 ) } function y ( t ) { var e = t . _readableState ; if ( L ( "flow" , e . flowing ) , e . flowing ) do var n = t . read ( ) ; while ( null !== n && e . flowing ) } function _ ( t , e ) { var n , r = e . buffer , i = e . length , o = ! ! e . decoder , a = ! ! e . objectMode ; if ( 0 === r . length ) return null ; if ( 0 === i ) n = null ; else if ( a ) n = r . shift ( ) ; else if ( ! t || t >= i ) n = o ? r . join ( "" ) : k . concat ( r , i ) , r . length = 0 ; else if ( t < r [ 0 ] . length ) { var s = r [ 0 ] ; n = s . slice ( 0 , t ) , r [ 0 ] = s . slice ( t ) } else if ( t === r [ 0 ] . length ) n = r . shift ( ) ; else { n = o ? "" : new k ( t ) ; for ( var h = 0 , u = 0 , c = r . length ; c > u && t > h ; u ++ ) { var s = r [ 0 ] , l = Math . min ( t - h , s . length ) ; o ? n += s . slice ( 0 , l ) : s . copy ( n , h , 0 , l ) , l < s . length ? r [ 0 ] = s . slice ( l ) : r . shift ( ) , h += l } } return n } function w ( t ) { var n = t . _readableState ; if ( n . length > 0 ) throw new Error ( "endReadable called on non-empty stream" ) ; n . endEmitted || ( n . ended = ! 0 , e . nextTick ( function ( ) { n . endEmitted || 0 !== n . length || ( n . endEmitted = ! 0 , t . readable = ! 1 , t . emit ( "end" ) ) } ) ) } function b ( t , e ) { for ( var n = 0 , r = t . length ; r > n ; n ++ ) e ( t [ n ] , n ) } function x ( t , e ) { for ( var n = 0 , r = t . length ; r > n ; n ++ ) if ( t [ n ] === e ) return n ; return - 1 } t . exports = i ; var S = n ( 31 ) , k = n ( 2 ) . Buffer ; i . ReadableState = r ; var E = n ( 26 ) . EventEmitter ; E . listenerCount || ( E . listenerCount = function ( t , e ) { return t . listeners ( e ) . length } ) ; var C = n ( 25 ) , I = n ( 32 ) ; I . inherits = n ( 33 ) ; var A , L = n ( 34 ) ; L = L && L . debuglog ? L . debuglog ( "stream" ) : function ( ) { } , I . inherits ( i , C ) , i . prototype . push = function ( t , e ) { var n = this . _readableState ; return I . isString ( t ) && ! n . objectMode && ( e = e || n . defaultEncoding , e !== n . encoding && ( t = new k ( t , e ) , e = "" ) ) , o ( this , n , t , e , ! 1 ) } , i . prototype . unshift = function ( t ) { var e = this . _readableState ; return o ( this , e , t , "" , ! 0 ) } , i . prototype . setEncoding = function ( t ) { return A || ( A = n ( 37 ) . StringDecoder ) , this . _readableState . decoder = new A ( t ) , this . _readableState . encoding = t , this } ; var R = 8388608 ; i . prototype . read = function ( t ) { L ( "read" , t ) ; var e = this . _readableState , n = t ; if ( ( ! I . isNumber ( t ) || t > 0 ) && ( e . emittedReadable = ! 1 ) , 0 === t && e . needReadable && ( e . length >= e . highWaterMark || e . ended ) ) return L ( "read: emitReadable" , e . length , e . ended ) , 0 === e . length && e . ended ? w ( this ) : l ( this ) , null ; if ( t = h ( t , e ) , 0 === t && e . ended ) return 0 === e . length && w ( this ) , null ; var r = e . needReadable ; L ( "need readable" , r ) , ( 0 === e . length || e . length - t < e . highWaterMark ) && ( r = ! 0 , L ( "length less than watermark" , r ) ) , ( e . ended || e . reading ) && ( r = ! 1 , L ( "reading or ended" , r ) ) , r && ( L ( "do read" ) , e . reading = ! 0 , e . sync = ! 0 , 0 === e . length && ( e . needReadable = ! 0 ) , this . _read ( e . highWaterMark ) , e . sync = ! 1 ) , r && ! e . reading && ( t = h ( n , e ) ) ; var i ; return i = t > 0 ? _ ( t , e ) : null , I . isNull ( i ) && ( e . needReadable = ! 0 , t = 0 ) , e . length -= t , 0 !== e . length || e . ended || ( e . needReadable = ! 0 ) , n !== t && e . ended && 0 === e . length && w ( this ) , I . isNull ( i ) || this . emit ( "data" , i ) , i } , i . prototype . _read = function ( t ) { this . emit ( "error" , new Error ( "not implemented" ) ) } , i . prototype . pipe = function ( t , n ) { function r ( t ) { L ( "onunpipe" ) , t === l && o ( ) } function i ( ) { L ( "onend" ) , t . end ( ) } function o ( ) { L ( "cleanup" ) , t . removeListener ( "close" , h ) , t . removeListener ( "finish" , u ) , t . removeListener ( "drain" , v ) , t . removeListener ( "error" , s ) , t . removeListener ( "unpipe" , r ) , l . removeListener ( "end" , i ) , l . removeListener ( "end" , o ) , l . removeListener ( "data" , a ) , ! f . awaitDrain || t . _writableState && ! t . _writableState . needDrain || v ( ) } function a ( e ) { L ( "ondata" ) ; var n = t . write ( e ) ; ! 1 === n && ( L ( "false write response, pause" , l . _readableState . awaitDrain ) , l . _readableState . awaitDrain ++ , l . pause ( ) ) } function s ( e ) { L ( "onerror" , e ) , c ( ) , t . removeListener ( "error" , s ) , 0 === E . listenerCount ( t , "error" ) && t . emit ( "error" , e ) } function h ( ) { t . removeListener ( "finish" , u ) , c ( ) } function u ( ) { L ( "onfinish" ) , t . removeListener ( "close" , h ) , c ( ) } function c ( ) { L ( "unpipe" ) , l . unpipe ( t ) } var l = this , f = this . _readableState ; switch ( f . pipesCount ) { case 0 : f . pipes = t ; break ; case 1 : f . pipes = [ f . pipes , t ] ; break ; default : f . pipes . push ( t ) } f . pipesCount += 1 , L ( "pipe count=%d opts=%j" , f . pipesCount , n ) ; var d = ( ! n || n . end !== ! 1 ) && t !== e . stdout && t !== e . stderr , p = d ? i : o ; f . endEmitted ? e . nextTick ( p ) : l . once ( "end" , p ) , t . on ( "unpipe" , r ) ; var v = g ( l ) ; return t . on ( "drain" , v ) , l . on ( "data" , a ) , t . _events && t . _events . e
"use strict" ; function r ( t , e ) { return t . msg = B [ e ] , e } function i ( t ) { return ( t << 1 ) - ( t > 4 ? 9 : 0 ) } function o ( t ) { for ( var e = t . length ; -- e >= 0 ; ) t [ e ] = 0 } function a ( t ) { var e = t . state , n = e . pending ; n > t . avail _out && ( n = t . avail _out ) , 0 !== n && ( A . arraySet ( t . output , e . pending _buf , e . pending _out , n , t . next _out ) , t . next _out += n , e . pending _out += n , t . total _out += n , t . avail _out -= n , e . pending -= n , 0 === e . pending && ( e . pending _out = 0 ) ) } function s ( t , e ) { L . _tr _flush _block ( t , t . block _start >= 0 ? t . block _start : - 1 , t . strstart - t . block _start , e ) , t . block _start = t . strstart , a ( t . strm ) } function h ( t , e ) { t . pending _buf [ t . pending ++ ] = e } function u ( t , e ) { t . pending _buf [ t . pending ++ ] = e >>> 8 & 255 , t . pending _buf [ t . pending ++ ] = 255 & e } function c ( t , e , n , r ) { var i = t . avail _in ; return i > r && ( i = r ) , 0 === i ? 0 : ( t . avail _in -= i , A . arraySet ( e , t . input , t . next _in , i , n ) , 1 === t . state . wrap ? t . adler = R ( t . adler , e , i , n ) : 2 === t . state . wrap && ( t . adler = T ( t . adler , e , i , n ) ) , t . next _in += i , t . total _in += i , i ) } function l ( t , e ) { var n , r , i = t . max _chain _length , o = t . strstart , a = t . prev _length , s = t . nice _match , h = t . strstart > t . w _size - ut ? t . strstart - ( t . w _size - ut ) : 0 , u = t . window , c = t . w _mask , l = t . prev , f = t . strstart + ht , d = u [ o + a - 1 ] , p = u [ o + a ] ; t . prev _length >= t . good _match && ( i >>= 2 ) , s > t . lookahead && ( s = t . lookahead ) ; do if ( n = e , u [ n + a ] === p && u [ n + a - 1 ] === d && u [ n ] === u [ o ] && u [ ++ n ] === u [ o + 1 ] ) { o += 2 , n ++ ; do ; while ( u [ ++ o ] === u [ ++ n ] && u [ ++ o ] === u [ ++ n ] && u [ ++ o ] === u [ ++ n ] && u [ ++ o ] === u [ ++ n ] && u [ ++ o ] === u [ ++ n ] && u [ ++ o ] === u [ ++ n ] && u [ ++ o ] === u [ ++ n ] && u [ ++ o ] === u [ ++ n ] && f > o ) ; if ( r = ht - ( f - o ) , o = f - ht , r > a ) { if ( t . match _start = e , a = r , r >= s ) break ; d = u [ o + a - 1 ] , p = u [ o + a ] } } while ( ( e = l [ e & c ] ) > h && 0 !== -- i ) ; return a <= t . lookahead ? a : t . lookahead } function f ( t ) { var e , n , r , i , o , a = t . w _size ; do { if ( i = t . window _size - t . lookahead - t . strstart , t . strstart >= a + ( a - ut ) ) { A . arraySet ( t . window , t . window , a , a , 0 ) , t . match _start -= a , t . strstart -= a , t . block _start -= a , n = t . hash _size , e = n ; do r = t . head [ -- e ] , t . head [ e ] = r >= a ? r - a : 0 ; while ( -- n ) ; n = a , e = n ; do r = t . prev [ -- e ] , t . prev [ e ] = r >= a ? r - a : 0 ; while ( -- n ) ; i += a } if ( 0 === t . strm . avail _in ) break ; if ( n = c ( t . strm , t . window , t . strstart + t . lookahead , i ) , t . lookahead += n , t . lookahead + t . insert >= st ) for ( o = t . strstart - t . insert , t . ins _h = t . window [ o ] , t . ins _h = ( t . ins _h << t . hash _shift ^ t . window [ o + 1 ] ) & t . hash _mask ; t . insert && ( t . ins _h = ( t . ins _h << t . hash _shift ^ t . window [ o + st - 1 ] ) & t . hash _mask , t . prev [ o & t . w _mask ] = t . head [ t . ins _h ] , t . head [ t . ins _h ] = o , o ++ , t . insert -- , ! ( t . lookahead + t . insert < st ) ) ; ) ; } while ( t . lookahead < ut && 0 !== t . strm . avail _in ) } function d ( t , e ) { var n = 65535 ; for ( n > t . pending _buf _size - 5 && ( n = t . pending _buf _size - 5 ) ; ; ) { if ( t . lookahead <= 1 ) { if ( f ( t ) , 0 === t . lookahead && e === O ) return yt ; if ( 0 === t . lookahead ) break } t . strstart += t . lookahead , t . lookahead = 0 ; var r = t . block _start + n ; if ( ( 0 === t . strstart || t . strstart >= r ) && ( t . lookahead = t . strstart - r , t . strstart = r , s ( t , ! 1 ) , 0 === t . strm . avail _out ) ) return yt ; if ( t . strstart - t . block _start >= t . w _size - ut && ( s ( t , ! 1 ) , 0 === t . strm . avail _out ) ) return yt } return t . insert = 0 , e === U ? ( s ( t , ! 0 ) , 0 === t . strm . avail _out ? wt : bt ) : t . strstart > t . block _start && ( s ( t , ! 1 ) , 0 === t . strm . avail _out ) ? yt : yt } function p ( t , e ) { for ( var n , r ; ; ) { if ( t . lookahead < ut ) { if ( f ( t ) , t . lookahead < ut && e === O ) return yt ; if ( 0 === t . lookahead ) break } if ( n = 0 , t . lookahead >= st && ( t . ins _h = ( t . ins _h << t . hash _shift ^ t . window [ t . strstart + st - 1 ] ) & t . hash _mask , n = t . prev [ t . strstart & t . w _mask ] = t . head [ t . ins _h ] , t . head [ t . ins _h ] = t . strstart ) , 0 !== n && t . strstart - n <= t . w _size - ut && ( t . match _length = l ( t , n ) ) , t . match _length >= st ) if ( r = L . _tr _tally ( t , t . strstart - t . match _start , t . match _length - st ) , t . lookahead -= t . match _length , t . match _length <= t . max _lazy _match && t . lookahead >= st ) { t . match _length -- ; do t . strstart ++ , t . ins _h = ( t . ins _h << t . hash _shift ^ t . window [ t . strstart + st - 1 ] ) & t . hash _mask , n = t . prev [ t . strstart & t . w _mask ] = t . head [ t . ins _h ] , t . head [ t . ins _h ] = t . strstart ; while ( 0 !== -- t . match _length ) ; t . strstart ++ } else t . strstart += t . match _length , t . match _length = 0 , t . ins _h = t . window [ t . strstart ] , t . ins _h = ( t . ins _h << t . hash _shift ^ t . window [ t . strstart + 1 ] ) & t . hash _mask ; else r = L . _tr _tally ( t , 0 , t . window [ t . strstart ] ) , t . lookahead -- , t . strstart ++ ; if ( r && ( s ( t , ! 1 ) , 0 === t . strm . avail _out ) ) return yt } return t . insert = t . strstart < st - 1 ? t . strstart : st - 1 , e === U ? ( s ( t , ! 0 ) , 0 === t . strm . avail _out ? wt : bt ) : t . last _lit && ( s ( t , ! 1 ) , 0 === t . strm . avail _out ) ? yt : _t } function g ( t , e ) { for ( var n , r , i ; ; ) { if ( t . lookahead < ut ) { if ( f ( t ) , t . lookahead < ut && e === O ) return yt ; if ( 0 === t . lookahead ) break } if ( n = 0 , t . lookahead >= st &
t . next _in = a , t . avail _in = h , n . hold = f , n . bits = d , ( n . wsize || g !== t . avail _out && n . mode < lt && ( n . mode < ht || e !== E ) ) && l ( t , t . output , t . next _out , g - t . avail _out ) ? ( n . mode = ft , O ) : ( p -= t . avail _in , g -= t . avail _out , t . total _in += p , t . total _out += g , n . total += g , n . wrap && g && ( t . adler = n . check = n . flags ? _ ( n . check , o , g , t . next _out - g ) : y ( n . check , o , g , t . next _out - g ) ) , t . data _type = n . bits + ( n . last ? 64 : 0 ) + ( n . mode === q ? 128 : 0 ) + ( n . mode === et || n . mode === V ? 256 : 0 ) , ( 0 === p && 0 === g || e === E ) && St === A && ( St = M ) , St ) } function d ( t ) { if ( ! t || ! t . state ) return T ; var e = t . state ; return e . window && ( e . window = null ) , t . state = null , A } function p ( t , e ) { var n ; return t && t . state ? ( n = t . state , 0 === ( 2 & n . wrap ) ? T : ( n . head = e , e . done = ! 1 , A ) ) : T } var g , v , m = n ( 52 ) , y = n ( 54 ) , _ = n ( 55 ) , w = n ( 57 ) , b = n ( 58 ) , x = 0 , S = 1 , k = 2 , E = 4 , C = 5 , I = 6 , A = 0 , L = 1 , R = 2 , T = - 2 , B = - 3 , O = - 4 , M = - 5 , D = 8 , U = 1 , P = 2 , z = 3 , F = 4 , W = 5 , N = 6 , j = 7 , H = 8 , Z = 9 , G = 10 , Y = 11 , q = 12 , K = 13 , X = 14 , V = 15 , $ = 16 , J = 17 , Q = 18 , tt = 19 , et = 20 , nt = 21 , rt = 22 , it = 23 , ot = 24 , at = 25 , st = 26 , ht = 27 , ut = 28 , ct = 29 , lt = 30 , ft = 31 , dt = 32 , pt = 852 , gt = 592 , vt = 15 , mt = vt , yt = ! 0 ; e . inflateReset = a , e . inflateReset2 = s , e . inflateResetKeep = o , e . inflateInit = u , e . inflateInit2 = h , e . inflate = f , e . inflateEnd = d , e . inflateGetHeader = p , e . inflateInfo = "pako inflate (from Nodeca project)" } , function ( t , e ) { "use strict" ; var n = 30 , r = 12 ; t . exports = function ( t , e ) { var i , o , a , s , h , u , c , l , f , d , p , g , v , m , y , _ , w , b , x , S , k , E , C , I , A ; i = t . state , o = t . next _in , I = t . input , a = o + ( t . avail _in - 5 ) , s = t . next _out , A = t . output , h = s - ( e - t . avail _out ) , u = s + ( t . avail _out - 257 ) , c = i . dmax , l = i . wsize , f = i . whave , d = i . wnext , p = i . window , g = i . hold , v = i . bits , m = i . lencode , y = i . distcode , _ = ( 1 << i . lenbits ) - 1 , w = ( 1 << i . distbits ) - 1 ; t : do { 15 > v && ( g += I [ o ++ ] << v , v += 8 , g += I [ o ++ ] << v , v += 8 ) , b = m [ g & _ ] ; e : for ( ; ; ) { if ( x = b >>> 24 , g >>>= x , v -= x , x = b >>> 16 & 255 , 0 === x ) A [ s ++ ] = 65535 & b ; else { if ( ! ( 16 & x ) ) { if ( 0 === ( 64 & x ) ) { b = m [ ( 65535 & b ) + ( g & ( 1 << x ) - 1 ) ] ; continue e } if ( 32 & x ) { i . mode = r ; break t } t . msg = "invalid literal/length code" , i . mode = n ; break t } S = 65535 & b , x &= 15 , x && ( x > v && ( g += I [ o ++ ] << v , v += 8 ) , S += g & ( 1 << x ) - 1 , g >>>= x , v -= x ) , 15 > v && ( g += I [ o ++ ] << v , v += 8 , g += I [ o ++ ] << v , v += 8 ) , b = y [ g & w ] ; n : for ( ; ; ) { if ( x = b >>> 24 , g >>>= x , v -= x , x = b >>> 16 & 255 , ! ( 16 & x ) ) { if ( 0 === ( 64 & x ) ) { b = y [ ( 65535 & b ) + ( g & ( 1 << x ) - 1 ) ] ; continue n } t . msg = "invalid distance code" , i . mode = n ; break t } if ( k = 65535 & b , x &= 15 , x > v && ( g += I [ o ++ ] << v , v += 8 , x > v && ( g += I [ o ++ ] << v , v += 8 ) ) , k += g & ( 1 << x ) - 1 , k > c ) { t . msg = "invalid distance too far back" , i . mode = n ; break t } if ( g >>>= x , v -= x , x = s - h , k > x ) { if ( x = k - x , x > f && i . sane ) { t . msg = "invalid distance too far back" , i . mode = n ; break t } if ( E = 0 , C = p , 0 === d ) { if ( E += l - x , S > x ) { S -= x ; do A [ s ++ ] = p [ E ++ ] ; while ( -- x ) ; E = s - k , C = A } } else if ( x > d ) { if ( E += l + d - x , x -= d , S > x ) { S -= x ; do A [ s ++ ] = p [ E ++ ] ; while ( -- x ) ; if ( E = 0 , S > d ) { x = d , S -= x ; do A [ s ++ ] = p [ E ++ ] ; while ( -- x ) ; E = s - k , C = A } } } else if ( E += d - x , S > x ) { S -= x ; do A [ s ++ ] = p [ E ++ ] ; while ( -- x ) ; E = s - k , C = A } for ( ; S > 2 ; ) A [ s ++ ] = C [ E ++ ] , A [ s ++ ] = C [ E ++ ] , A [ s ++ ] = C [ E ++ ] , S -= 3 ; S && ( A [ s ++ ] = C [ E ++ ] , S > 1 && ( A [ s ++ ] = C [ E ++ ] ) ) } else { E = s - k ; do A [ s ++ ] = A [ E ++ ] , A [ s ++ ] = A [ E ++ ] , A [ s ++ ] = A [ E ++ ] , S -= 3 ; while ( S > 2 ) ; S && ( A [ s ++ ] = A [ E ++ ] , S > 1 && ( A [ s ++ ] = A [ E ++ ] ) ) } break } } break } } while ( a > o && u > s ) ; S = v >> 3 , o -= S , v -= S << 3 , g &= ( 1 << v ) - 1 , t . next _in = o , t . next _out = s , t . avail _in = a > o ? 5 + ( a - o ) : 5 - ( o - a ) , t . avail _out = u > s ? 257 + ( u - s ) : 257 - ( s - u ) , i . hold = g , i . bits = v } } , function ( t , e , n ) { "use strict" ; var r = n ( 52 ) , i = 15 , o = 852 , a = 592 , s = 0 , h = 1 , u = 2 , c = [ 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 13 , 15 , 17 , 19 , 23 , 27 , 31 , 35 , 43 , 51 , 59 , 67 , 83 , 99 , 115 , 131 , 163 , 195 , 227 , 258 , 0 , 0 ] , l = [ 16 , 16 , 16 , 16 , 16 , 16 , 16 , 16 , 17 , 17 , 17 , 17 , 18 , 18 , 18 , 18 , 19 , 19 , 19 , 19 , 20 , 20 , 20 , 20 , 21 , 21 , 21 , 21 , 16 , 72 , 78 ] , f = [ 1 , 2 , 3 , 4 , 5 , 7 , 9 , 13 , 17 , 25 , 33 , 49 , 65 , 97 , 129 , 193 , 257 , 385 , 513 , 769 , 1025 , 1537 , 2049 , 3073 , 4097 , 6145 , 8193 , 12289 , 16385 , 24577 , 0 , 0 ] , d = [ 16 , 16 , 16 , 16 , 17 , 17 , 18 , 18 , 19 , 19 , 20 , 20 , 21 , 21 , 22 , 22 , 23 , 23 , 24 , 24 , 25 , 25 , 26 , 26 , 27 , 27 , 28 , 28 , 29 , 29 , 64 , 64 ] ; t . exports = function ( t , e , n , p , g , v , m , y ) { var _ , w , b , x , S , k , E , C , I , A = y . bits , L = 0 , R = 0 , T = 0 , B = 0 , O = 0 , M = 0 , D = 0 , U = 0 , P = 0 , z = 0 , F = null , W = 0 , N = new r . Buf16 ( i + 1 ) , j = new r . Buf16 ( i + 1 ) , H = null , Z = 0 ; for ( L = 0 ; i >= L ; L ++ ) N [ L ] = 0 ; for ( R = 0 ; p > R ; R ++ ) N [ e [ n + R ] ] ++ ; for ( O = A , B = i ; B >= 1 && 0 === N [ B ] ; B -- ) ; if ( O > B && ( O = B ) , 0 === B ) return g [ v ++ ] = 20971520 , g [ v ++ ] = 20971520 , y . bits = 1 , 0 ; for ( T = 1 ; B > T && 0 === N [ T ] ; T ++ ) ; for ( T > O && ( O = T ) , U = 1 , L = 1 ; i >= L ; L ++ ) if ( U <<= 1 , U -= N [ L ] , 0 > U ) return - 1 ; if ( U > 0 && ( t === s || 1 !== B ) ) return - 1 ; for ( j [ 1 ] = 0 , L = 1 ; i > L ; L ++ ) j [ L + 1 ] = j [ L ] + N [ L ] ; for ( R = 0 ; p > R ; R ++ ) 0 !== e [ n + R ] && ( m [ j [ e [ n + R ] ] ++ ] = R ) ; if ( t === s ? ( F = H = m , k = 19 ) : t === h ? ( F = c , W -= 257 , H = l , Z -= 257 , k = 256 ) : ( F = f , H = d , k = - 1 ) , z = 0 , R = 0 , L = T , S = v , M = O , D = 0 , b = - 1 , P = 1 << O , x = P - 1 , t === h && P > o || t
} , V : function ( t , e ) { return i = e [ 0 ] , s = h = null , t . lineTo ( r , i ) } , v : function ( t , e ) { return i += e [ 0 ] , s = h = null , t . lineTo ( r , i ) } , Z : function ( t ) { return t . closePath ( ) , r = f , i = d } , z : function ( t ) { return t . closePath ( ) , r = f , i = d } } , l = function ( t , e , r , i ) { var o , a , s , h , u , l , f , d , p , g , v , m , y ; for ( l = i [ 0 ] , f = i [ 1 ] , u = i [ 2 ] , h = i [ 3 ] , g = i [ 4 ] , a = i [ 5 ] , s = i [ 6 ] , p = n ( a , s , l , f , h , g , u , e , r ) , y = [ ] , v = 0 , m = p . length ; m > v ; v ++ ) d = p [ v ] , o = c . apply ( null , d ) , y . push ( t . bezierCurveTo . apply ( t , o ) ) ; return y } , n = function ( t , e , n , r , i , o , a , u , c ) { var l , f , d , p , g , v , m , y , _ , w , b , x , S , k , E , C , I , A , L , R , T , B , O , M , D , U ; for ( k = a * ( Math . PI / 180 ) , S = Math . sin ( k ) , g = Math . cos ( k ) , n = Math . abs ( n ) , r = Math . abs ( r ) , s = g * ( u - t ) * . 5 + S * ( c - e ) * . 5 , h = g * ( c - e ) * . 5 - S * ( u - t ) * . 5 , y = s * s / ( n * n ) + h * h / ( r * r ) , y > 1 && ( y = Math . sqrt ( y ) , n *= y , r *= y ) , l = g / n , f = S / n , d = - S / r , p = g / r , R = l * u + f * c , O = d * u + p * c , T = l * t + f * e , M = d * t + p * e , v = ( T - R ) * ( T - R ) + ( M - O ) * ( M - O ) , x = 1 / v - . 25 , 0 > x && ( x = 0 ) , b = Math . sqrt ( x ) , o === i && ( b = - b ) , B = . 5 * ( R + T ) - b * ( M - O ) , D = . 5 * ( O + M ) + b * ( T - R ) , E = Math . atan2 ( O - D , R - B ) , C = Math . atan2 ( M - D , T - B ) , L = C - E , 0 > L && 1 === o ? L += 2 * Math . PI : L > 0 && 0 === o && ( L -= 2 * Math . PI ) , w = Math . ceil ( Math . abs ( L / ( . 5 * Math . PI + . 001 ) ) ) , _ = [ ] , m = U = 0 ; w >= 0 ? w > U : U > w ; m = w >= 0 ? ++ U : -- U ) I = E + m * L / w , A = E + ( m + 1 ) * L / w , _ [ m ] = [ B , D , I , A , n , r , S , g ] ; return _ } , c = function ( t , e , n , r , i , o , a , s ) { var h , u , c , l , f , d , p , g , v , m , y , _ ; return h = s * i , u = - a * o , c = a * i , l = s * o , d = . 5 * ( r - n ) , f = 8 / 3 * Math . sin ( . 5 * d ) * Math . sin ( . 5 * d ) / Math . sin ( d ) , p = t + Math . cos ( n ) - f * Math . sin ( n ) , m = e + Math . sin ( n ) + f * Math . cos ( n ) , v = t + Math . cos ( r ) , _ = e + Math . sin ( r ) , g = v + f * Math . sin ( r ) , y = _ - f * Math . cos ( r ) , [ h * p + u * m , c * p + l * m , h * g + u * y , c * g + l * y , h * v + u * _ , c * v + l * _ ] } , t } ( ) , t . exports = e } ) . call ( this ) } , function ( t , e , n ) { ( function ( ) { var e ; e = n ( 70 ) , t . exports = { initFonts : function ( ) { this . _fontFamilies = { } , this . _fontCount = 0 , this . _fontSize = 12 , this . _font = null , this . _registeredFonts = { } } , font : function ( t , n , r ) { var i , o , a , s ; return "number" == typeof n && ( r = n , n = null ) , "string" == typeof t && this . _registeredFonts [ t ] ? ( i = t , s = this . _registeredFonts [ t ] , t = s . src , n = s . family ) : ( i = n || t , "string" != typeof i && ( i = null ) ) , null != r && this . fontSize ( r ) , ( o = this . _fontFamilies [ i ] ) ? ( this . _font = o , this ) : ( a = "F" + ++ this . _fontCount , this . _font = new e ( this , t , n , a ) , ( o = this . _fontFamilies [ this . _font . name ] ) ? ( this . _font = o , this ) : ( i && ( this . _fontFamilies [ i ] = this . _font ) , this . _fontFamilies [ this . _font . name ] = this . _font , this ) ) } , fontSize : function ( t ) { return this . _fontSize = t , this } , currentLineHeight : function ( t ) { return null == t && ( t = ! 1 ) , this . _font . lineHeight ( this . _fontSize , t ) } , registerFont : function ( t , e , n ) { return this . _registeredFonts [ t ] = { src : e , family : n } , this } } } ) . call ( this ) } , function ( t , e , n ) { ( function ( e , r ) { ( function ( ) { var i , o , a , s , h ; s = n ( 71 ) , i = n ( 87 ) , a = n ( 88 ) , h = n ( 44 ) , o = function ( ) { function t ( t , r , o , h ) { if ( this . document = t , this . id = h , "string" == typeof r ) { if ( r in n ) return this . isAFM = ! 0 , this . font = new i ( n [ r ] ( ) ) , void this . registerAFM ( r ) ; if ( /\.(ttf|ttc)$/i . test ( r ) ) this . font = s . open ( r , o ) ; else { if ( ! /\.dfont$/i . test ( r ) ) throw new Error ( "Not a supported font format or standard PDF font." ) ; this . font = s . fromDFont ( r , o ) } } else if ( e . isBuffer ( r ) ) this . font = s . fromBuffer ( r , o ) ; else if ( r instanceof Uint8Array ) this . font = s . fromBuffer ( new e ( r ) , o ) ; else { if ( ! ( r instanceof ArrayBuffer ) ) throw new Error ( "Not a supported font format or standard PDF font." ) ; this . font = s . fromBuffer ( new e ( new Uint8Array ( r ) ) , o ) } this . subset = new a ( this . font ) , this . registerTTF ( ) } var n , o ; return n = { Courier : function ( ) { return h . readFileSync ( r + "/font/data/Courier.afm" , "utf8" ) } , "Courier-Bold" : function ( ) { return h . readFileSync ( r + "/font/data/Courier-Bold.afm" , "utf8" ) } , "Courier-Oblique" : function ( ) { return h . readFileSync ( r + "/font/data/Courier-Oblique.afm" , "utf8" ) } , "Courier-BoldOblique" : function ( ) { return h . readFileSync ( r + "/font/data/Courier-BoldOblique.afm" , "utf8" ) } , Helvetica : function ( ) { return h . readFileSync ( r + "/font/data/Helvetica.afm" , "utf8" ) } , "Helvetica-Bold" : function ( ) { return h . readFileSync ( r + "/font/data/Helvetica-Bold.afm" , "utf8" ) } , "Helvetica-Oblique" : function ( ) { return h . readFileSync ( r + "/font/data/Helvetica-Oblique.afm" , "utf8" ) } , "Helvetica-BoldOblique" : function ( ) { return h . readFileSync ( r + "/font/data/Helvetica-BoldOblique.afm" , "utf8" ) } , "Times-Roman" : function ( ) { return h . readFileSync ( r + "/font/data/Times-Roman.afm" , "utf8" ) } , "Times-Bold" : function ( ) { return h . readFileSync ( r + "/font/data/Times-Bold.afm" , "utf8" ) } , "Times-Italic" : function ( ) { return h . readFil
PostTable } ( r ) , t . exports = PostTable } ) . call ( this ) } , function ( t , e , n ) { ( function ( ) { var OS2Table , e , r = { } . hasOwnProperty , i = function ( t , e ) { function n ( ) { this . constructor = t } for ( var i in e ) r . call ( e , i ) && ( t [ i ] = e [ i ] ) ; return n . prototype = e . prototype , t . prototype = new n , t . _ _super _ _ = e . prototype , t } ; e = n ( 76 ) , OS2Table = function ( t ) { function OS2Table ( ) { return OS2Table . _ _super _ _ . constructor . apply ( this , arguments ) } return i ( OS2Table , t ) , OS2Table . prototype . tag = "OS/2" , OS2Table . prototype . parse = function ( t ) { var e ; return t . pos = this . offset , this . version = t . readUInt16 ( ) , this . averageCharWidth = t . readShort ( ) , this . weightClass = t . readUInt16 ( ) , this . widthClass = t . readUInt16 ( ) , this . type = t . readShort ( ) , this . ySubscriptXSize = t . readShort ( ) , this . ySubscriptYSize = t . readShort ( ) , this . ySubscriptXOffset = t . readShort ( ) , this . ySubscriptYOffset = t . readShort ( ) , this . ySuperscriptXSize = t . readShort ( ) , this . ySuperscriptYSize = t . readShort ( ) , this . ySuperscriptXOffset = t . readShort ( ) , this . ySuperscriptYOffset = t . readShort ( ) , this . yStrikeoutSize = t . readShort ( ) , this . yStrikeoutPosition = t . readShort ( ) , this . familyClass = t . readShort ( ) , this . panose = function ( ) { var n , r ; for ( r = [ ] , e = n = 0 ; 10 > n ; e = ++ n ) r . push ( t . readByte ( ) ) ; return r } ( ) , this . charRange = function ( ) { var n , r ; for ( r = [ ] , e = n = 0 ; 4 > n ; e = ++ n ) r . push ( t . readInt ( ) ) ; return r } ( ) , this . vendorID = t . readString ( 4 ) , this . selection = t . readShort ( ) , this . firstCharIndex = t . readShort ( ) , this . lastCharIndex = t . readShort ( ) , this . version > 0 && ( this . ascent = t . readShort ( ) , this . descent = t . readShort ( ) , this . lineGap = t . readShort ( ) , this . winAscent = t . readShort ( ) , this . winDescent = t . readShort ( ) , this . codePageRange = function ( ) { var n , r ; for ( r = [ ] , e = n = 0 ; 2 > n ; e = ++ n ) r . push ( t . readInt ( ) ) ; return r } ( ) , this . version > 1 ) ? ( this . xHeight = t . readShort ( ) , this . capHeight = t . readShort ( ) , this . defaultChar = t . readShort ( ) , this . breakChar = t . readShort ( ) , this . maxContext = t . readShort ( ) ) : void 0 } , OS2Table . prototype . encode = function ( ) { return this . raw ( ) } , OS2Table } ( e ) , t . exports = OS2Table } ) . call ( this ) } , function ( t , e , n ) { ( function ( ) { var e , LocaTable , r , i = { } . hasOwnProperty , o = function ( t , e ) { function n ( ) { this . constructor = t } for ( var r in e ) i . call ( e , r ) && ( t [ r ] = e [ r ] ) ; return n . prototype = e . prototype , t . prototype = new n , t . _ _super _ _ = e . prototype , t } ; r = n ( 76 ) , e = n ( 72 ) , LocaTable = function ( t ) { function LocaTable ( ) { return LocaTable . _ _super _ _ . constructor . apply ( this , arguments ) } return o ( LocaTable , t ) , LocaTable . prototype . tag = "loca" , LocaTable . prototype . parse = function ( t ) { var e , n ; return t . pos = this . offset , e = this . file . head . indexToLocFormat , 0 === e ? this . offsets = function ( ) { var e , r , i ; for ( i = [ ] , n = e = 0 , r = this . length ; r > e ; n = e += 2 ) i . push ( 2 * t . readUInt16 ( ) ) ; return i } . call ( this ) : this . offsets = function ( ) { var e , r , i ; for ( i = [ ] , n = e = 0 , r = this . length ; r > e ; n = e += 4 ) i . push ( t . readUInt32 ( ) ) ; return i } . call ( this ) } , LocaTable . prototype . indexOf = function ( t ) { return this . offsets [ t ] } , LocaTable . prototype . lengthOf = function ( t ) { return this . offsets [ t + 1 ] - this . offsets [ t ] } , LocaTable . prototype . encode = function ( t ) { var n , r , i , o , a , s , h , u , c , l , f ; for ( o = new e , a = 0 , u = t . length ; u > a ; a ++ ) if ( r = t [ a ] , r > 65535 ) { for ( f = this . offsets , s = 0 , c = f . length ; c > s ; s ++ ) n = f [ s ] , o . writeUInt32 ( n ) ; return i = { format : 1 , table : o . data } } for ( h = 0 , l = t . length ; l > h ; h ++ ) n = t [ h ] , o . writeUInt16 ( n / 2 ) ; return i = { format : 0 , table : o . data } } , LocaTable } ( r ) , t . exports = LocaTable } ) . call ( this ) } , function ( t , e , n ) { ( function ( ) { var e , r , GlyfTable , i , o , a = { } . hasOwnProperty , s = function ( t , e ) { function n ( ) { this . constructor = t } for ( var r in e ) a . call ( e , r ) && ( t [ r ] = e [ r ] ) ; return n . prototype = e . prototype , t . prototype = new n , t . _ _super _ _ = e . prototype , t } , h = [ ] . slice ; o = n ( 76 ) , r = n ( 72 ) , GlyfTable = function ( t ) { function GlyfTable ( ) { return GlyfTable . _ _super _ _ . constructor . apply ( this , arguments ) } return s ( GlyfTable , t ) , GlyfTable . prototype . tag = "glyf" , GlyfTable . prototype . parse = function ( t ) { return this . cache = { } } , GlyfTable . prototype . glyphFor = function ( t ) { var n , o , a , s , h , u , c , l , f , d ; return t in this . cache ? this . cache [ t ] : ( s = this . file . loca , n = this . file . contents , o = s . indexOf ( t ) , a = s . lengthOf ( t ) , 0 === a ? this . cache [ t ] = null : ( n . pos = this . offset + o , u = new r ( n . read ( a ) ) , h = u . readShort ( ) , l = u . readShort ( ) , d = u . readShort ( ) , c = u . readShort ( ) , f = u . readShort ( ) , - 1 === h ? this . cache [ t ] = new e ( u , l , d , c , f ) : this . cache [ t ] = new i ( u , h , l , d , c , f ) , this . cache [ t ] ) ) } , GlyfTable . prototype . encode = function ( t , e , n ) { var r , i , o , a , s , h ; for ( a = [ ] , o = [ ] , s
highStart : 919552 , errorValue : 0 } } , function ( t , e ) { ( function ( ) { var t , n , r , i , o , a , s , h , u , c , l , f , d , p , g , v , m , y , _ , w , b , x , S , k , E , C , I , A , L , R , T , B , O , M , D , U , P , z , F , W ; e . OP = L = 0 , e . CL = u = 1 , e . CP = l = 2 , e . QU = B = 3 , e . GL = p = 4 , e . NS = I = 5 , e . EX = d = 6 , e . SY = P = 7 , e . IS = b = 8 , e . PR = T = 9 , e . PO = R = 10 , e . NU = A = 11 , e . AL = n = 12 , e . HL = m = 13 , e . ID = _ = 14 , e . IN = w = 15 , e . HY = y = 16 , e . BA = i = 17 , e . BB = o = 18 , e . B2 = r = 19 , e . ZW = W = 20 , e . CM = c = 21 , e . WJ = z = 22 , e . H2 = g = 23 , e . H3 = v = 24 , e . JL = x = 25 , e . JV = k = 26 , e . JT = S = 27 , e . RI = O = 28 , e . AI = t = 29 , e . BK = a = 30 , e . CB = s = 31 , e . CJ = h = 32 , e . CR = f = 33 , e . LF = E = 34 , e . NL = C = 35 , e . SA = M = 36 , e . SG = D = 37 , e . SP = U = 38 , e . XX = F = 39 } ) . call ( this ) } , function ( t , e ) { ( function ( ) { var t , n , r , i , o ; e . DI _BRK = r = 0 , e . IN _BRK = i = 1 , e . CI _BRK = t = 2 , e . CP _BRK = n = 3 , e . PR _BRK = o = 4 , e . pairTable = [ [ o , o , o , o , o , o , o , o , o , o , o , o , o , o , o , o , o , o , o , o , o , n , o , o , o , o , o , o , o ] , [ r , o , o , i , i , o , o , o , o , i , i , r , r , r , r , r , i , i , r , r , o , t , o , r , r , r , r , r , r ] , [ r , o , o , i , i , o , o , o , o , i , i , i , i , i , r , r , i , i , r , r , o , t , o , r , r , r , r , r , r ] , [ o , o , o , i , i , i , o , o , o , i , i , i , i , i , i , i , i , i , i , i , o , t , o , i , i , i , i , i , i ] , [ i , o , o , i , i , i , o , o , o , i , i , i , i , i , i , i , i , i , i , i , o , t , o , i , i , i , i , i , i ] , [ r , o , o , i , i , i , o , o , o , r , r , r , r , r , r , r , i , i , r , r , o , t , o , r , r , r , r , r , r ] , [ r , o , o , i , i , i , o , o , o , r , r , r , r , r , r , r , i , i , r , r , o , t , o , r , r , r , r , r , r ] , [ r , o , o , i , i , i , o , o , o , r , r , i , r , r , r , r , i , i , r , r , o , t , o , r , r , r , r , r , r ] , [ r , o , o , i , i , i , o , o , o , r , r , i , i , i , r , r , i , i , r , r , o , t , o , r , r , r , r , r , r ] , [ i , o , o , i , i , i , o , o , o , r , r , i , i , i , i , r , i , i , r , r , o , t , o , i , i , i , i , i , r ] , [ i , o , o , i , i , i , o , o , o , r , r , i , i , i , r , r , i , i , r , r , o , t , o , r , r , r , r , r , r ] , [ i , o , o , i , i , i , o , o , o , i , i , i , i , i , r , i , i , i , r , r , o , t , o , r , r , r , r , r , r ] , [ i , o , o , i , i , i , o , o , o , r , r , i , i , i , r , i , i , i , r , r , o , t , o , r , r , r , r , r , r ] , [ i , o , o , i , i , i , o , o , o , r , r , i , i , i , r , i , i , i , r , r , o , t , o , r , r , r , r , r , r ] , [ r , o , o , i , i , i , o , o , o , r , i , r , r , r , r , i , i , i , r , r , o , t , o , r , r , r , r , r , r ] , [ r , o , o , i , i , i , o , o , o , r , r , r , r , r , r , i , i , i , r , r , o , t , o , r , r , r , r , r , r ] , [ r , o , o , i , r , i , o , o , o , r , r , i , r , r , r , r , i , i , r , r , o , t , o , r , r , r , r , r , r ] , [ r , o , o , i , r , i , o , o , o , r , r , r , r , r , r , r , i , i , r , r , o , t , o , r , r , r , r , r , r ] , [ i , o , o , i , i , i , o , o , o , i , i , i , i , i , i , i , i , i , i , i , o , t , o , i , i , i , i , i , i ] , [ r , o , o , i , i , i , o , o , o , r , r , r , r , r , r , r , i , i , r , o , o , t , o , r , r , r , r , r , r ] , [ r , r , r , r , r , r , r , r , r , r , r , r , r , r , r , r , r , r , r , r , o , r , r , r , r , r , r , r , r ] , [ i , o , o , i , i , i , o , o , o , r , r , i , i , i , r , i , i , i , r , r , o , t , o , r , r , r , r , r , r ] , [ i , o , o , i , i , i , o , o , o , i , i , i , i , i , i , i , i , i , i , i , o , t , o , i , i , i , i , i , i ] , [ r , o , o , i , i , i , o , o , o , r , i , r , r , r , r , i , i , i , r , r , o , t , o , r , r , r , i , i , r ] , [ r , o , o , i , i , i , o , o , o , r , i , r , r , r , r , i , i , i , r , r , o , t , o , r , r , r , r , i , r ] , [ r , o , o , i , i , i , o , o , o , r , i , r , r , r , r , i , i , i , r , r , o , t , o , i , i , i , i , r , r ] , [ r , o , o , i , i , i , o , o , o , r , i , r , r , r , r , i , i , i , r , r , o , t , o , r , r , r , i , i , r ] , [ r , o , o , i , i , i , o , o , o , r , i , r , r , r , r , i , i , i , r , r , o , t , o , r , r , r , r , i , r ] , [ r , o , o , i , i , i , o , o , o , r , r , r , r , r , r , r , i , i , r , r , o , t , o , r , r , r , r , r , i ] ] } ) . call ( this ) } , function ( t , e , n ) { ( function ( e ) { ( function ( ) { var r ; r = n ( 97 ) , t . exports = { initImages : function ( ) { return this . _imageRegistry = { } , this . _imageCount = 0 } , image : function ( t , n , i , o ) { var a , s , h , u , c , l , f , d , p , g , v , m , y , _ ; return null == o && ( o = { } ) , "object" == typeof n && ( o = n , n = null ) , n = null != ( m = null != n ? n : o . x ) ? m : this . x , i = null != ( y = null != i ? i : o . y ) ? y : this . y , e . isBuffer ( t ) || ( l = this . _imageRegistry [ t ] ) , l || ( l = r . open ( t , "I" + ++ this . _imageCount ) , l . embed ( this ) , e . isBuffer ( t ) || ( this . _imageRegistry [ t ] = l ) ) , null == ( g = this . page . xobjects ) [ v = l . label ] && ( g [ v ] = l . obj ) , d = o . width || l . width , u = o . height || l . height , o . width && ! o . height ? ( p = d / l . width , d = l . width * p , u = l . height * p ) : o . height && ! o . width ? ( c = u / l . height , d = l . width * c , u = l . height * c ) : o . scale ? ( d = l . width * o . scale , u = l . height * o . scale ) : o . fit && ( _ = o . fit , h = _ [ 0 ] , a = _ [ 1 ] , s = h / a , f = l . width / l . height , f > s ? ( d = h , u = h / f ) : ( u = a , d = a * f ) , "center" === o . align ? n = n + h / 2 - d / 2 : "right" === o . align && ( n = n + h - d ) , "center" === o . valign ? i = i + a / 2 - u / 2 : "bottom" === o . valign && ( i = i + a - u ) ) , this . y === i && ( this . y += u ) , this . save ( ) , this . transform ( d , 0 , 0 , - u , n , i + u ) , this . addContent ( "/" + l . label + " Do" ) , this . restore ( ) , this } } } ) . call ( this ) } ) . call ( e , n ( 2 ) . Buffer ) } , function ( t , e , n ) { ( function ( e ) { ( function ( ) { var r , i , o , a , s ; s = n ( 44 ) , r = n ( 72 ) , i = n ( 98 ) , a = n ( 99 ) , o = function ( ) { function t ( ) { } return t . open = function ( t , n ) { var r , o ; if ( e . isBuffer ( t ) ) r = t ; else if ( o = /^data:.+;base64,(.*)$/ . exec ( t ) ) r = new e ( o [ 1 ] , "base64" ) ; else if ( r = s . readFileSync ( t ) , ! r ) return ; if ( 255 === r [ 0 ] && 216 === r [ 1 ] ) return new i ( r , n ) ; if ( 137 === r [ 0 ] && "PNG" === r . toString ( "ascii" , 1 , 4 ) ) return new a ( r , n ) ; throw new Error ( "Unknown image format." ) } , t } ( ) , t . exports = o } ) . call ( this ) } ) . call ( e , n ( 2 ) . Buffer ) } , function ( t , e , n ) { ( function ( ) { var e , r , i = [ ] . indexOf || function ( t ) { for ( var e = 0 , n = this . length ; n > e ; e ++ ) if ( e in this && this
2015-10-18 09:30:28 +02:00
//# sourceMappingURL=js/pdfmake.min.js.map
2015-11-04 08:48:47 +01:00
2016-01-07 08:08:30 +01:00
window . pdfMake = window . pdfMake || { } ; window . pdfMake . vfs = { } ;
if ( window . ninjaFontVfs ) ninjaLoadFontVfs ( ) ;
function ninjaLoadFontVfs ( ) {
jQuery . each ( window . ninjaFontVfs , function ( font , files ) {
jQuery . each ( files , function ( filename , file ) {
2016-03-23 23:40:42 +01:00
window . pdfMake . vfs [ 'fonts/' + font + '/' + filename ] = file ;
2016-01-07 08:08:30 +01:00
} ) ;
} )
2016-03-23 23:40:42 +01:00
}
function ninjaAddVFSDoc ( name , content ) {
window . pdfMake . vfs [ 'docs/' + name ] = content ;
if ( window . refreshPDF ) refreshPDF ( true ) ;
jQuery ( document ) . trigger ( 'ninjaVFSDocAdded' ) ;
2016-01-07 08:08:30 +01:00
}