unipdf/ps/ps.go

212 lines
32 KiB
Go
Raw Normal View History

2020-08-27 21:45:09 +00:00
//
// Copyright 2020 FoxyUtils ehf. All rights reserved.
//
// This is a commercial product and requires a license to operate.
// A trial license can be obtained at https://unidoc.io
//
// DO NOT EDIT: generated by unitwist Go source code obfuscator.
//
// Use of this source code is governed by the UniDoc End User License Agreement
// terms that can be accessed at https://unidoc.io/eula/
// Package ps implements various functionalities needed for handling Postscript for PDF uses, in particular
// for PDF function type 4.
//
// Package ps implements various functionalities needed for handling Postscript for PDF uses, in particular
// for PDF function type 4.
2021-04-23 20:28:14 +00:00
package ps ;import (_d "bufio";_e "bytes";_b "errors";_eg "fmt";_ea "github.com/unidoc/unipdf/v3/common";_ae "github.com/unidoc/unipdf/v3/core";_a "io";_c "math";);func (_geaf *PSOperand )or (_dge *PSStack )error {_gba ,_geg :=_dge .Pop ();if _geg !=nil {return _geg ;
};_cgda ,_geg :=_dge .Pop ();if _geg !=nil {return _geg ;};if _ddac ,_fgdf :=_gba .(*PSBoolean );_fgdf {_egda ,_bgec :=_cgda .(*PSBoolean );if !_bgec {return ErrTypeCheck ;};_geg =_dge .Push (MakeBool (_ddac .Val ||_egda .Val ));return _geg ;};if _fbbe ,_agde :=_gba .(*PSInteger );
_agde {_bggd ,_fdde :=_cgda .(*PSInteger );if !_fdde {return ErrTypeCheck ;};_geg =_dge .Push (MakeInteger (_fbbe .Val |_bggd .Val ));return _geg ;};return ErrTypeCheck ;};func (_cggd *PSOperand )exp (_ebcec *PSStack )error {_feae ,_eac :=_ebcec .PopNumberAsFloat64 ();
if _eac !=nil {return _eac ;};_egad ,_eac :=_ebcec .PopNumberAsFloat64 ();if _eac !=nil {return _eac ;};if _c .Abs (_feae )< 1&&_egad < 0{return ErrUndefinedResult ;};_dba :=_c .Pow (_egad ,_feae );_eac =_ebcec .Push (MakeReal (_dba ));return _eac ;};func (_ad *PSReal )Duplicate ()PSObject {_de :=PSReal {};
_de .Val =_ad .Val ;return &_de };func (_eag *PSOperand )and (_ead *PSStack )error {_fed ,_deg :=_ead .Pop ();if _deg !=nil {return _deg ;};_adb ,_deg :=_ead .Pop ();if _deg !=nil {return _deg ;};if _dbe ,_efa :=_fed .(*PSBoolean );_efa {_egd ,_ebcg :=_adb .(*PSBoolean );
if !_ebcg {return ErrTypeCheck ;};_deg =_ead .Push (MakeBool (_dbe .Val &&_egd .Val ));return _deg ;};if _baf ,_cca :=_fed .(*PSInteger );_cca {_ace ,_ade :=_adb .(*PSInteger );if !_ade {return ErrTypeCheck ;};_deg =_ead .Push (MakeInteger (_baf .Val &_ace .Val ));
return _deg ;};return ErrTypeCheck ;};
2021-04-17 13:46:54 +00:00
// PSObjectArrayToFloat64Array converts []PSObject into a []float64 array. Each PSObject must represent a number,
// otherwise a ErrTypeCheck error occurs.
2021-04-23 20:28:14 +00:00
func PSObjectArrayToFloat64Array (objects []PSObject )([]float64 ,error ){var _eb []float64 ;for _ ,_dc :=range objects {if _da ,_fbd :=_dc .(*PSInteger );_fbd {_eb =append (_eb ,float64 (_da .Val ));}else if _aa ,_fa :=_dc .(*PSReal );_fa {_eb =append (_eb ,_aa .Val );
}else {return nil ,ErrTypeCheck ;};};return _eb ,nil ;};func (_egc *PSOperand )ln (_ccd *PSStack )error {_dcge ,_adgf :=_ccd .PopNumberAsFloat64 ();if _adgf !=nil {return _adgf ;};_eade :=_c .Log (_dcge );_adgf =_ccd .Push (MakeReal (_eade ));return _adgf ;
};
2021-04-17 13:46:54 +00:00
2021-04-23 20:28:14 +00:00
// PSOperand represents a Postscript operand (text string).
type PSOperand string ;func (_cf *PSBoolean )Duplicate ()PSObject {_cdb :=PSBoolean {};_cdb .Val =_cf .Val ;return &_cdb };
2021-04-17 13:46:54 +00:00
2021-04-23 20:28:14 +00:00
// NewPSExecutor returns an initialized PSExecutor for an input `program`.
func NewPSExecutor (program *PSProgram )*PSExecutor {_ee :=&PSExecutor {};_ee .Stack =NewPSStack ();_ee ._fb =program ;return _ee ;};func (_gdf *PSParser )parseNumber ()(PSObject ,error ){_bcb ,_gad :=_ae .ParseNumber (_gdf ._ecgc );if _gad !=nil {return nil ,_gad ;
};switch _gbda :=_bcb .(type ){case *_ae .PdfObjectFloat :return MakeReal (float64 (*_gbda )),nil ;case *_ae .PdfObjectInteger :return MakeInteger (int (*_gbda )),nil ;};return nil ,_eg .Errorf ("\u0075n\u0068\u0061\u006e\u0064\u006c\u0065\u0064\u0020\u006e\u0075\u006db\u0065\u0072\u0020\u0074\u0079\u0070\u0065\u0020\u0025\u0054",_bcb );
};func (_edae *PSOperand )log (_fec *PSStack )error {_ada ,_adgd :=_fec .PopNumberAsFloat64 ();if _adgd !=nil {return _adgd ;};_gcb :=_c .Log10 (_ada );_adgd =_fec .Push (MakeReal (_gcb ));return _adgd ;};
2021-04-17 13:46:54 +00:00
2021-04-23 20:28:14 +00:00
// String returns a string representation of the stack.
func (_baeg *PSStack )String ()string {_ecdd :="\u005b\u0020";for _ ,_cfd :=range *_baeg {_ecdd +=_cfd .String ();_ecdd +="\u0020";};_ecdd +="\u005d";return _ecdd ;};
2020-09-07 00:23:12 +00:00
2021-04-23 20:28:14 +00:00
// PSProgram defines a Postscript program which is a series of PS objects (arguments, commands, programs etc).
type PSProgram []PSObject ;var ErrStackOverflow =_b .New ("\u0073\u0074\u0061\u0063\u006b\u0020\u006f\u0076\u0065r\u0066\u006c\u006f\u0077");func (_fgd *PSOperand )String ()string {return string (*_fgd )};func (_bbca *PSOperand )le (_cab *PSStack )error {_daa ,_edb :=_cab .PopNumberAsFloat64 ();
if _edb !=nil {return _edb ;};_gbfd ,_edb :=_cab .PopNumberAsFloat64 ();if _edb !=nil {return _edb ;};if _c .Abs (_gbfd -_daa )< _dd {_fegg :=_cab .Push (MakeBool (true ));return _fegg ;}else if _gbfd < _daa {_abg :=_cab .Push (MakeBool (true ));return _abg ;
}else {_gfa :=_cab .Push (MakeBool (false ));return _gfa ;};};func (_ece *PSOperand )copy (_ed *PSStack )error {_ffg ,_gffa :=_ed .PopInteger ();if _gffa !=nil {return _gffa ;};if _ffg < 0{return ErrRangeCheck ;};if _ffg > len (*_ed ){return ErrRangeCheck ;
};*_ed =append (*_ed ,(*_ed )[len (*_ed )-_ffg :]...);return nil ;};
2021-04-17 13:46:54 +00:00
2021-04-23 20:28:14 +00:00
// Parse parses the postscript and store as a program that can be executed.
func (_ebcf *PSParser )Parse ()(*PSProgram ,error ){_ebcf .skipSpaces ();_aeef ,_begd :=_ebcf ._ecgc .Peek (2);if _begd !=nil {return nil ,_begd ;};if _aeef [0]!='{'{return nil ,_b .New ("\u0069\u006e\u0076\u0061\u006c\u0069\u0064\u0020\u0050\u0053\u0020\u0050\u0072\u006f\u0067\u0072\u0061\u006d\u0020\u006e\u006f\u0074\u0020\u0073t\u0061\u0072\u0074\u0069\u006eg\u0020\u0077i\u0074\u0068\u0020\u007b");
};_dbf ,_begd :=_ebcf .parseFunction ();if _begd !=nil &&_begd !=_a .EOF {return nil ,_begd ;};return _dbf ,_begd ;};
2021-04-17 13:46:54 +00:00
2021-04-23 20:28:14 +00:00
// Pop pops an object from the top of the stack.
func (_ege *PSStack )Pop ()(PSObject ,error ){if len (*_ege )< 1{return nil ,ErrStackUnderflow ;};_edc :=(*_ege )[len (*_ege )-1];*_ege =(*_ege )[0:len (*_ege )-1];return _edc ,nil ;};func (_fad *PSOperand )exch (_aca *PSStack )error {_gebfd ,_agd :=_aca .Pop ();
if _agd !=nil {return _agd ;};_adec ,_agd :=_aca .Pop ();if _agd !=nil {return _agd ;};_agd =_aca .Push (_gebfd );if _agd !=nil {return _agd ;};_agd =_aca .Push (_adec );return _agd ;};func (_db *PSInteger )DebugString ()string {return _eg .Sprintf ("\u0069\u006e\u0074\u003a\u0025\u0064",_db .Val );
};
2021-04-17 13:46:54 +00:00
2021-04-23 20:28:14 +00:00
// NewPSProgram returns an empty, initialized PSProgram.
func NewPSProgram ()*PSProgram {return &PSProgram {}};func (_bcfa *PSOperand )roll (_fbgf *PSStack )error {_bgcg ,_gac :=_fbgf .Pop ();if _gac !=nil {return _gac ;};_dfdf ,_gac :=_fbgf .Pop ();if _gac !=nil {return _gac ;};_bdb ,_gbae :=_bgcg .(*PSInteger );
if !_gbae {return ErrTypeCheck ;};_add ,_gbae :=_dfdf .(*PSInteger );if !_gbae {return ErrTypeCheck ;};if _add .Val < 0{return ErrRangeCheck ;};if _add .Val ==0||_add .Val ==1{return nil ;};if _add .Val > len (*_fbgf ){return ErrStackUnderflow ;};for _ebbe :=0;
_ebbe < _bfbdf (_bdb .Val );_ebbe ++{var _aee []PSObject ;_aee =(*_fbgf )[len (*_fbgf )-(_add .Val ):len (*_fbgf )];if _bdb .Val > 0{_ggg :=_aee [len (_aee )-1];_aee =append ([]PSObject {_ggg },_aee [0:len (_aee )-1]...);}else {_fge :=_aee [len (_aee )-_add .Val ];
_aee =append (_aee [1:],_fge );};_acae :=append ((*_fbgf )[0:len (*_fbgf )-_add .Val ],_aee ...);_fbgf =&_acae ;};return nil ;};func (_fdd *PSOperand )idiv (_dcb *PSStack )error {_gebb ,_cebb :=_dcb .Pop ();if _cebb !=nil {return _cebb ;};_bade ,_cebb :=_dcb .Pop ();
if _cebb !=nil {return _cebb ;};_cee ,_ggf :=_gebb .(*PSInteger );if !_ggf {return ErrTypeCheck ;};if _cee .Val ==0{return ErrUndefinedResult ;};_bdaeg ,_ggf :=_bade .(*PSInteger );if !_ggf {return ErrTypeCheck ;};_bff :=_bdaeg .Val /_cee .Val ;_cebb =_dcb .Push (MakeInteger (_bff ));
return _cebb ;};
2021-04-17 13:46:54 +00:00
2021-04-23 20:28:14 +00:00
// Execute executes the program for an input parameters `objects` and returns a slice of output objects.
func (_dcf *PSExecutor )Execute (objects []PSObject )([]PSObject ,error ){for _ ,_fg :=range objects {_ge :=_dcf .Stack .Push (_fg );if _ge !=nil {return nil ,_ge ;};};_cc :=_dcf ._fb .Exec (_dcf .Stack );if _cc !=nil {_ea .Log .Debug ("\u0045x\u0065c\u0020\u0066\u0061\u0069\u006c\u0065\u0064\u003a\u0020\u0025\u0076",_cc );
return nil ,_cc ;};_ba :=[]PSObject (*_dcf .Stack );_dcf .Stack .Empty ();return _ba ,nil ;};func (_fc *PSProgram )String ()string {_gb :="\u007b\u0020";for _ ,_cg :=range *_fc {_gb +=_cg .String ();_gb +="\u0020";};_gb +="\u007d";return _gb ;};func (_dbdc *PSOperand )pop (_aded *PSStack )error {_ ,_fef :=_aded .Pop ();
if _fef !=nil {return _fef ;};return nil ;};var ErrStackUnderflow =_b .New ("\u0073t\u0061c\u006b\u0020\u0075\u006e\u0064\u0065\u0072\u0066\u006c\u006f\u0077");func (_cd *PSBoolean )String ()string {return _eg .Sprintf ("\u0025\u0076",_cd .Val )};func (_ecgb *PSOperand )lt (_cgb *PSStack )error {_cgef ,_dggc :=_cgb .PopNumberAsFloat64 ();
if _dggc !=nil {return _dggc ;};_ccfe ,_dggc :=_cgb .PopNumberAsFloat64 ();if _dggc !=nil {return _dggc ;};if _c .Abs (_ccfe -_cgef )< _dd {_efc :=_cgb .Push (MakeBool (false ));return _efc ;}else if _ccfe < _cgef {_dbdg :=_cgb .Push (MakeBool (true ));
return _dbdg ;}else {_dccd :=_cgb .Push (MakeBool (false ));return _dccd ;};};
2020-08-27 21:45:09 +00:00
2021-04-17 13:46:54 +00:00
// Append appends an object to the PSProgram.
2021-04-23 20:28:14 +00:00
func (_dde *PSProgram )Append (obj PSObject ){*_dde =append (*_dde ,obj )};func (_aad *PSOperand )Duplicate ()PSObject {_dca :=*_aad ;return &_dca };func (_gga *PSOperand )neg (_fbb *PSStack )error {_geda ,_fgb :=_fbb .Pop ();if _fgb !=nil {return _fgb ;
};if _bbb ,_egg :=_geda .(*PSReal );_egg {_fgb =_fbb .Push (MakeReal (-_bbb .Val ));return _fgb ;}else if _cedf ,_aagc :=_geda .(*PSInteger );_aagc {_fgb =_fbb .Push (MakeInteger (-_cedf .Val ));return _fgb ;}else {return ErrTypeCheck ;};};func (_ded *PSProgram )Duplicate ()PSObject {_gc :=&PSProgram {};
for _ ,_df :=range *_ded {_gc .Append (_df .Duplicate ());};return _gc ;};
2021-04-17 13:46:54 +00:00
2021-04-23 20:28:14 +00:00
// PSParser is a basic Postscript parser.
type PSParser struct{_ecgc *_d .Reader };
2021-04-17 13:46:54 +00:00
2021-04-23 20:28:14 +00:00
// Empty empties the stack.
func (_dee *PSStack )Empty (){*_dee =[]PSObject {}};
2021-04-17 13:46:54 +00:00
// DebugString returns a descriptive string representation of the stack - intended for debugging.
2021-04-23 20:28:14 +00:00
func (_cffg *PSStack )DebugString ()string {_dgd :="\u005b\u0020";for _ ,_bgfe :=range *_cffg {_dgd +=_bgfe .DebugString ();_dgd +="\u0020";};_dgd +="\u005d";return _dgd ;};
// MakeReal returns a new PSReal object initialized with `val`.
func MakeReal (val float64 )*PSReal {_ecc :=PSReal {};_ecc .Val =val ;return &_ecc };func (_ebe *PSOperand )DebugString ()string {return _eg .Sprintf ("\u006fp\u003a\u0027\u0025\u0073\u0027",*_ebe );};
// MakeOperand returns a new PSOperand object based on string `val`.
func MakeOperand (val string )*PSOperand {_gfad :=PSOperand (val );return &_gfad };func (_aae *PSInteger )String ()string {return _eg .Sprintf ("\u0025\u0064",_aae .Val )};func (_adda *PSOperand )sub (_ebf *PSStack )error {_aedc ,_bgcb :=_ebf .Pop ();if _bgcb !=nil {return _bgcb ;
};_badde ,_bgcb :=_ebf .Pop ();if _bgcb !=nil {return _bgcb ;};_cfcc ,_bfd :=_aedc .(*PSReal );_efb ,_efag :=_aedc .(*PSInteger );if !_bfd &&!_efag {return ErrTypeCheck ;};_gecdf ,_bfb :=_badde .(*PSReal );_aggb ,_bfbd :=_badde .(*PSInteger );if !_bfb &&!_bfbd {return ErrTypeCheck ;
};if _efag &&_bfbd {_gge :=_aggb .Val -_efb .Val ;_fba :=_ebf .Push (MakeInteger (_gge ));return _fba ;};var _fbed float64 =0;if _bfb {_fbed =_gecdf .Val ;}else {_fbed =float64 (_aggb .Val );};if _bfd {_fbed -=_cfcc .Val ;}else {_fbed -=float64 (_efb .Val );
};_bgcb =_ebf .Push (MakeReal (_fbed ));return _bgcb ;};func (_fege *PSOperand )sin (_bdad *PSStack )error {_caf ,_fega :=_bdad .PopNumberAsFloat64 ();if _fega !=nil {return _fega ;};_adef :=_c .Sin (_caf *_c .Pi /180.0);_fega =_bdad .Push (MakeReal (_adef ));
return _fega ;};
// PSStack defines a stack of PSObjects. PSObjects can be pushed on or pull from the stack.
type PSStack []PSObject ;func (_feb *PSOperand )dup (_gbbc *PSStack )error {_bag ,_acea :=_gbbc .Pop ();if _acea !=nil {return _acea ;};_acea =_gbbc .Push (_bag );if _acea !=nil {return _acea ;};_acea =_gbbc .Push (_bag .Duplicate ());return _acea ;};
// Exec executes the operand `op` in the state specified by `stack`.
func (_gfc *PSOperand )Exec (stack *PSStack )error {_faf :=ErrUnsupportedOperand ;switch *_gfc {case "\u0061\u0062\u0073":_faf =_gfc .abs (stack );case "\u0061\u0064\u0064":_faf =_gfc .add (stack );case "\u0061\u006e\u0064":_faf =_gfc .and (stack );case "\u0061\u0074\u0061\u006e":_faf =_gfc .atan (stack );
case "\u0062\u0069\u0074\u0073\u0068\u0069\u0066\u0074":_faf =_gfc .bitshift (stack );case "\u0063e\u0069\u006c\u0069\u006e\u0067":_faf =_gfc .ceiling (stack );case "\u0063\u006f\u0070\u0079":_faf =_gfc .copy (stack );case "\u0063\u006f\u0073":_faf =_gfc .cos (stack );
case "\u0063\u0076\u0069":_faf =_gfc .cvi (stack );case "\u0063\u0076\u0072":_faf =_gfc .cvr (stack );case "\u0064\u0069\u0076":_faf =_gfc .div (stack );case "\u0064\u0075\u0070":_faf =_gfc .dup (stack );case "\u0065\u0071":_faf =_gfc .eq (stack );case "\u0065\u0078\u0063\u0068":_faf =_gfc .exch (stack );
case "\u0065\u0078\u0070":_faf =_gfc .exp (stack );case "\u0066\u006c\u006fo\u0072":_faf =_gfc .floor (stack );case "\u0067\u0065":_faf =_gfc .ge (stack );case "\u0067\u0074":_faf =_gfc .gt (stack );case "\u0069\u0064\u0069\u0076":_faf =_gfc .idiv (stack );
case "\u0069\u0066":_faf =_gfc .ifCondition (stack );case "\u0069\u0066\u0065\u006c\u0073\u0065":_faf =_gfc .ifelse (stack );case "\u0069\u006e\u0064e\u0078":_faf =_gfc .index (stack );case "\u006c\u0065":_faf =_gfc .le (stack );case "\u006c\u006f\u0067":_faf =_gfc .log (stack );
case "\u006c\u006e":_faf =_gfc .ln (stack );case "\u006c\u0074":_faf =_gfc .lt (stack );case "\u006d\u006f\u0064":_faf =_gfc .mod (stack );case "\u006d\u0075\u006c":_faf =_gfc .mul (stack );case "\u006e\u0065":_faf =_gfc .ne (stack );case "\u006e\u0065\u0067":_faf =_gfc .neg (stack );
case "\u006e\u006f\u0074":_faf =_gfc .not (stack );case "\u006f\u0072":_faf =_gfc .or (stack );case "\u0070\u006f\u0070":_faf =_gfc .pop (stack );case "\u0072\u006f\u0075n\u0064":_faf =_gfc .round (stack );case "\u0072\u006f\u006c\u006c":_faf =_gfc .roll (stack );
case "\u0073\u0069\u006e":_faf =_gfc .sin (stack );case "\u0073\u0071\u0072\u0074":_faf =_gfc .sqrt (stack );case "\u0073\u0075\u0062":_faf =_gfc .sub (stack );case "\u0074\u0072\u0075\u006e\u0063\u0061\u0074\u0065":_faf =_gfc .truncate (stack );case "\u0078\u006f\u0072":_faf =_gfc .xor (stack );
};return _faf ;};func (_acf *PSOperand )gt (_cdbb *PSStack )error {_cbe ,_cac :=_cdbb .PopNumberAsFloat64 ();if _cac !=nil {return _cac ;};_ffcg ,_cac :=_cdbb .PopNumberAsFloat64 ();if _cac !=nil {return _cac ;};if _c .Abs (_ffcg -_cbe )< _dd {_eff :=_cdbb .Push (MakeBool (false ));
return _eff ;}else if _ffcg > _cbe {_dege :=_cdbb .Push (MakeBool (true ));return _dege ;}else {_gdbb :=_cdbb .Push (MakeBool (false ));return _gdbb ;};};func (_becc *PSOperand )xor (_ffgc *PSStack )error {_gfgeg ,_agfg :=_ffgc .Pop ();if _agfg !=nil {return _agfg ;
};_gdg ,_agfg :=_ffgc .Pop ();if _agfg !=nil {return _agfg ;};if _fce ,_ggfc :=_gfgeg .(*PSBoolean );_ggfc {_cggf ,_aedd :=_gdg .(*PSBoolean );if !_aedd {return ErrTypeCheck ;};_agfg =_ffgc .Push (MakeBool (_fce .Val !=_cggf .Val ));return _agfg ;};if _bacb ,_acd :=_gfgeg .(*PSInteger );
_acd {_dacf ,_dfaf :=_gdg .(*PSInteger );if !_dfaf {return ErrTypeCheck ;};_agfg =_ffgc .Push (MakeInteger (_bacb .Val ^_dacf .Val ));return _agfg ;};return ErrTypeCheck ;};func (_cgf *PSOperand )mul (_faea *PSStack )error {_cffb ,_gaa :=_faea .Pop ();
if _gaa !=nil {return _gaa ;};_gffb ,_gaa :=_faea .Pop ();if _gaa !=nil {return _gaa ;};_bge ,_ceeg :=_cffb .(*PSReal );_acfg ,_bcf :=_cffb .(*PSInteger );if !_ceeg &&!_bcf {return ErrTypeCheck ;};_bga ,_efge :=_gffb .(*PSReal );_cdg ,_ddd :=_gffb .(*PSInteger );
if !_efge &&!_ddd {return ErrTypeCheck ;};if _bcf &&_ddd {_cda :=_acfg .Val *_cdg .Val ;_eea :=_faea .Push (MakeInteger (_cda ));return _eea ;};var _cgee float64 ;if _ceeg {_cgee =_bge .Val ;}else {_cgee =float64 (_acfg .Val );};if _efge {_cgee *=_bga .Val ;
}else {_cgee *=float64 (_cdg .Val );};_gaa =_faea .Push (MakeReal (_cgee ));return _gaa ;};func _bfbdf (_fbf int )int {if _fbf < 0{return -_fbf ;};return _fbf ;};func (_dbd *PSOperand )add (_fbg *PSStack )error {_dbb ,_gfg :=_fbg .Pop ();if _gfg !=nil {return _gfg ;
};_aec ,_gfg :=_fbg .Pop ();if _gfg !=nil {return _gfg ;};_ega ,_bce :=_dbb .(*PSReal );_gbf ,_cff :=_dbb .(*PSInteger );if !_bce &&!_cff {return ErrTypeCheck ;};_ceb ,_bdae :=_aec .(*PSReal );_eba ,_fcf :=_aec .(*PSInteger );if !_bdae &&!_fcf {return ErrTypeCheck ;
};if _cff &&_fcf {_ecdg :=_gbf .Val +_eba .Val ;_fbc :=_fbg .Push (MakeInteger (_ecdg ));return _fbc ;};var _dae float64 ;if _bce {_dae =_ega .Val ;}else {_dae =float64 (_gbf .Val );};if _bdae {_dae +=_ceb .Val ;}else {_dae +=float64 (_eba .Val );};_gfg =_fbg .Push (MakeReal (_dae ));
return _gfg ;};var ErrRangeCheck =_b .New ("\u0072\u0061\u006e\u0067\u0065\u0020\u0063\u0068\u0065\u0063\u006b\u0020e\u0072\u0072\u006f\u0072");
// NewPSStack returns an initialized PSStack.
func NewPSStack ()*PSStack {return &PSStack {}};func (_bddf *PSOperand )ne (_dccf *PSStack )error {_ffb :=_bddf .eq (_dccf );if _ffb !=nil {return _ffb ;};_ffb =_bddf .not (_dccf );return _ffb ;};
// PopNumberAsFloat64 pops and return the numeric value of the top of the stack as a float64.
// Real or integer only.
func (_bgfg *PSStack )PopNumberAsFloat64 ()(float64 ,error ){_abf ,_fda :=_bgfg .Pop ();if _fda !=nil {return 0,_fda ;};if _ebed ,_agec :=_abf .(*PSReal );_agec {return _ebed .Val ,nil ;}else if _bgga ,_bgfd :=_abf .(*PSInteger );_bgfd {return float64 (_bgga .Val ),nil ;
}else {return 0,ErrTypeCheck ;};};func (_dab *PSInteger )Duplicate ()PSObject {_gf :=PSInteger {};_gf .Val =_dab .Val ;return &_gf };
2021-02-22 02:29:48 +00:00
2021-03-23 23:12:52 +00:00
// PSObject represents a postscript object.
type PSObject interface{
2020-08-27 21:45:09 +00:00
2021-03-23 23:12:52 +00:00
// Duplicate makes a fresh copy of the PSObject.
Duplicate ()PSObject ;
2020-08-27 21:45:09 +00:00
2021-03-23 23:12:52 +00:00
// DebugString returns a descriptive representation of the PSObject with more information than String()
// for debugging purposes.
DebugString ()string ;
2020-08-27 21:45:09 +00:00
2021-03-23 23:12:52 +00:00
// String returns a string representation of the PSObject.
2021-04-23 20:28:14 +00:00
String ()string ;};func (_fbgb *PSOperand )sqrt (_bdadf *PSStack )error {_bab ,_dbee :=_bdadf .PopNumberAsFloat64 ();if _dbee !=nil {return _dbee ;};if _bab < 0{return ErrRangeCheck ;};_cae :=_c .Sqrt (_bab );_dbee =_bdadf .Push (MakeReal (_cae ));return _dbee ;
};func (_dfd *PSOperand )div (_bgff *PSStack )error {_bb ,_ddfe :=_bgff .Pop ();if _ddfe !=nil {return _ddfe ;};_geb ,_ddfe :=_bgff .Pop ();if _ddfe !=nil {return _ddfe ;};_bfe ,_aba :=_bb .(*PSReal );_efaf ,_cb :=_bb .(*PSInteger );if !_aba &&!_cb {return ErrTypeCheck ;
};if _aba &&_bfe .Val ==0{return ErrUndefinedResult ;};if _cb &&_efaf .Val ==0{return ErrUndefinedResult ;};_gcf ,_bgc :=_geb .(*PSReal );_dbc ,_gbg :=_geb .(*PSInteger );if !_bgc &&!_gbg {return ErrTypeCheck ;};var _bbf float64 ;if _bgc {_bbf =_gcf .Val ;
}else {_bbf =float64 (_dbc .Val );};if _aba {_bbf /=_bfe .Val ;}else {_bbf /=float64 (_efaf .Val );};_ddfe =_bgff .Push (MakeReal (_bbf ));return _ddfe ;};func (_ddf *PSProgram )DebugString ()string {_fe :="\u007b\u0020";for _ ,_badg :=range *_ddf {_fe +=_badg .DebugString ();
_fe +="\u0020";};_fe +="\u007d";return _fe ;};func (_aed *PSReal )DebugString ()string {return _eg .Sprintf ("\u0072e\u0061\u006c\u003a\u0025\u002e\u0035f",_aed .Val );};
2020-10-12 14:17:59 +00:00
2021-04-23 20:28:14 +00:00
// PSInteger represents an integer.
type PSInteger struct{Val int ;};func (_fafa *PSOperand )cvr (_af *PSStack )error {_aff ,_ab :=_af .Pop ();if _ab !=nil {return _ab ;};if _adg ,_bec :=_aff .(*PSReal );_bec {_ab =_af .Push (MakeReal (_adg .Val ));}else if _ecgg ,_fbde :=_aff .(*PSInteger );
_fbde {_ab =_af .Push (MakeReal (float64 (_ecgg .Val )));}else {return ErrTypeCheck ;};return _ab ;};var ErrTypeCheck =_b .New ("\u0074\u0079p\u0065\u0020\u0063h\u0065\u0063\u006b\u0020\u0065\u0072\u0072\u006f\u0072");func (_ccdc *PSOperand )round (_dgfe *PSStack )error {_faeg ,_agdf :=_dgfe .Pop ();
if _agdf !=nil {return _agdf ;};if _ffda ,_aeca :=_faeg .(*PSReal );_aeca {_agdf =_dgfe .Push (MakeReal (_c .Floor (_ffda .Val +0.5)));}else if _agdeg ,_fdg :=_faeg .(*PSInteger );_fdg {_agdf =_dgfe .Push (MakeInteger (_agdeg .Val ));}else {return ErrTypeCheck ;
};return _agdf ;};func (_ffd *PSOperand )not (_gcdf *PSStack )error {_geaa ,_fbbg :=_gcdf .Pop ();if _fbbg !=nil {return _fbbg ;};if _gbgd ,_feggf :=_geaa .(*PSBoolean );_feggf {_fbbg =_gcdf .Push (MakeBool (!_gbgd .Val ));return _fbbg ;}else if _dddd ,_bgcc :=_geaa .(*PSInteger );
_bgcc {_fbbg =_gcdf .Push (MakeInteger (^_dddd .Val ));return _fbbg ;}else {return ErrTypeCheck ;};};func (_fgf *PSOperand )cos (_gbb *PSStack )error {_ffcf ,_fgg :=_gbb .PopNumberAsFloat64 ();if _fgg !=nil {return _fgg ;};_bgf :=_c .Cos (_ffcf *_c .Pi /180.0);
_fgg =_gbb .Push (MakeReal (_bgf ));return _fgg ;};func (_dcg *PSBoolean )DebugString ()string {return _eg .Sprintf ("\u0062o\u006f\u006c\u003a\u0025\u0076",_dcg .Val );};func (_cde *PSOperand )eq (_gec *PSStack )error {_eec ,_bed :=_gec .Pop ();if _bed !=nil {return _bed ;
};_ddc ,_bed :=_gec .Pop ();if _bed !=nil {return _bed ;};_fd ,_ccbec :=_eec .(*PSBoolean );_def ,_eeg :=_ddc .(*PSBoolean );if _ccbec ||_eeg {var _beeg error ;if _ccbec &&_eeg {_beeg =_gec .Push (MakeBool (_fd .Val ==_def .Val ));}else {_beeg =_gec .Push (MakeBool (false ));
};return _beeg ;};var _gebf float64 ;var _gdb float64 ;if _agf ,_ebce :=_eec .(*PSInteger );_ebce {_gebf =float64 (_agf .Val );}else if _bdac ,_ged :=_eec .(*PSReal );_ged {_gebf =_bdac .Val ;}else {return ErrTypeCheck ;};if _dfb ,_dfde :=_ddc .(*PSInteger );
_dfde {_gdb =float64 (_dfb .Val );}else if _abd ,_fdc :=_ddc .(*PSReal );_fdc {_gdb =_abd .Val ;}else {return ErrTypeCheck ;};if _c .Abs (_gdb -_gebf )< _dd {_bed =_gec .Push (MakeBool (true ));}else {_bed =_gec .Push (MakeBool (false ));};return _bed ;
};func (_beb *PSParser )parseOperand ()(*PSOperand ,error ){var _cdd []byte ;for {_ede ,_ccdf :=_beb ._ecgc .Peek (1);if _ccdf !=nil {if _ccdf ==_a .EOF {break ;};return nil ,_ccdf ;};if _ae .IsDelimiter (_ede [0]){break ;};if _ae .IsWhiteSpace (_ede [0]){break ;
};_acef ,_ :=_beb ._ecgc .ReadByte ();_cdd =append (_cdd ,_acef );};if len (_cdd )==0{return nil ,_b .New ("\u0069\u006e\u0076al\u0069\u0064\u0020\u006f\u0070\u0065\u0072\u0061\u006e\u0064\u0020\u0028\u0065\u006d\u0070\u0074\u0079\u0029");};return MakeOperand (string (_cdd )),nil ;
};var ErrUndefinedResult =_b .New ("\u0075\u006e\u0064\u0065fi\u006e\u0065\u0064\u0020\u0072\u0065\u0073\u0075\u006c\u0074\u0020\u0065\u0072\u0072o\u0072");func (_fcg *PSParser )skipSpaces ()(int ,error ){_cba :=0;for {_dgc ,_fcc :=_fcg ._ecgc .Peek (1);
if _fcc !=nil {return 0,_fcc ;};if _ae .IsWhiteSpace (_dgc [0]){_fcg ._ecgc .ReadByte ();_cba ++;}else {break ;};};return _cba ,nil ;};func (_efg *PSOperand )ge (_fdf *PSStack )error {_gbd ,_fbe :=_fdf .PopNumberAsFloat64 ();if _fbe !=nil {return _fbe ;
};_fac ,_fbe :=_fdf .PopNumberAsFloat64 ();if _fbe !=nil {return _fbe ;};if _c .Abs (_fac -_gbd )< _dd {_bfc :=_fdf .Push (MakeBool (true ));return _bfc ;}else if _fac > _gbd {_fbcc :=_fdf .Push (MakeBool (true ));return _fbcc ;}else {_ecgd :=_fdf .Push (MakeBool (false ));
return _ecgd ;};};
2020-09-28 23:18:17 +00:00
2021-04-17 13:46:54 +00:00
// NewPSParser returns a new instance of the PDF Postscript parser from input data.
2021-04-23 20:28:14 +00:00
func NewPSParser (content []byte )*PSParser {_bggb :=PSParser {};_daeed :=_e .NewBuffer (content );_bggb ._ecgc =_d .NewReader (_daeed );return &_bggb ;};func (_abe *PSOperand )ifelse (_gde *PSStack )error {_acc ,_ceed :=_gde .Pop ();if _ceed !=nil {return _ceed ;
};_gcab ,_ceed :=_gde .Pop ();if _ceed !=nil {return _ceed ;};_dff ,_ceed :=_gde .Pop ();if _ceed !=nil {return _ceed ;};_fbeb ,_ebb :=_acc .(*PSProgram );if !_ebb {return ErrTypeCheck ;};_fddd ,_ebb :=_gcab .(*PSProgram );if !_ebb {return ErrTypeCheck ;
};_daf ,_ebb :=_dff .(*PSBoolean );if !_ebb {return ErrTypeCheck ;};if _daf .Val {_affb :=_fddd .Exec (_gde );return _affb ;};_ceed =_fbeb .Exec (_gde );return _ceed ;};
2021-04-06 22:35:37 +00:00
2021-04-23 20:28:14 +00:00
// Exec executes the program, typically leaving output values on the stack.
func (_dda *PSProgram )Exec (stack *PSStack )error {for _ ,_bc :=range *_dda {var _ce error ;switch _gbc :=_bc .(type ){case *PSInteger :_cgg :=_gbc ;_ce =stack .Push (_cgg );case *PSReal :_bgg :=_gbc ;_ce =stack .Push (_bgg );case *PSBoolean :_gcg :=_gbc ;
_ce =stack .Push (_gcg );case *PSProgram :_ec :=_gbc ;_ce =stack .Push (_ec );case *PSOperand :_ga :=_gbc ;_ce =_ga .Exec (stack );default:return ErrTypeCheck ;};if _ce !=nil {return _ce ;};};return nil ;};func (_bcg *PSOperand )bitshift (_aef *PSStack )error {_dac ,_aaf :=_aef .PopInteger ();
if _aaf !=nil {return _aaf ;};_dce ,_aaf :=_aef .PopInteger ();if _aaf !=nil {return _aaf ;};var _aag int ;if _dac >=0{_aag =_dce <<uint (_dac );}else {_aag =_dce >>uint (-_dac );};_aaf =_aef .Push (MakeInteger (_aag ));return _aaf ;};func (_dcac *PSOperand )index (_bgge *PSStack )error {_daba ,_bbc :=_bgge .Pop ();
if _bbc !=nil {return _bbc ;};_dgg ,_cea :=_daba .(*PSInteger );if !_cea {return ErrTypeCheck ;};if _dgg .Val < 0{return ErrRangeCheck ;};if _dgg .Val > len (*_bgge )-1{return ErrStackUnderflow ;};_gecd :=(*_bgge )[len (*_bgge )-1-_dgg .Val ];_bbc =_bgge .Push (_gecd .Duplicate ());
return _bbc ;};func (_gg *PSOperand )ceiling (_bf *PSStack )error {_baeb ,_be :=_bf .Pop ();if _be !=nil {return _be ;};if _gcaf ,_ff :=_baeb .(*PSReal );_ff {_be =_bf .Push (MakeReal (_c .Ceil (_gcaf .Val )));}else if _ffc ,_fea :=_baeb .(*PSInteger );
_fea {_be =_bf .Push (MakeInteger (_ffc .Val ));}else {_be =ErrTypeCheck ;};return _be ;};func (_agcf *PSParser )parseFunction ()(*PSProgram ,error ){_afd ,_ :=_agcf ._ecgc .ReadByte ();if _afd !='{'{return nil ,_b .New ("\u0069\u006ev\u0061\u006c\u0069d\u0020\u0066\u0075\u006e\u0063\u0074\u0069\u006f\u006e");
};_fab :=NewPSProgram ();for {_agcf .skipSpaces ();_fddg ,_eaf :=_agcf ._ecgc .Peek (2);if _eaf !=nil {if _eaf ==_a .EOF {break ;};return nil ,_eaf ;};_ea .Log .Trace ("\u0050e\u0065k\u0020\u0073\u0074\u0072\u0069\u006e\u0067\u003a\u0020\u0025\u0073",string (_fddg ));
if _fddg [0]=='}'{_ea .Log .Trace ("\u0045\u004f\u0046 \u0066\u0075\u006e\u0063\u0074\u0069\u006f\u006e");_agcf ._ecgc .ReadByte ();break ;}else if _fddg [0]=='{'{_ea .Log .Trace ("\u0046u\u006e\u0063\u0074\u0069\u006f\u006e!");_bcff ,_afg :=_agcf .parseFunction ();
if _afg !=nil {return nil ,_afg ;};_fab .Append (_bcff );}else if _ae .IsDecimalDigit (_fddg [0])||(_fddg [0]=='-'&&_ae .IsDecimalDigit (_fddg [1])){_ea .Log .Trace ("\u002d>\u004e\u0075\u006d\u0062\u0065\u0072!");_gbaeb ,_bbga :=_agcf .parseNumber ();
if _bbga !=nil {return nil ,_bbga ;};_fab .Append (_gbaeb );}else {_ea .Log .Trace ("\u002d>\u004fp\u0065\u0072\u0061\u006e\u0064 \u006f\u0072 \u0062\u006f\u006f\u006c\u003f");_fddg ,_ =_agcf ._ecgc .Peek (5);_aeedd :=string (_fddg );_ea .Log .Trace ("\u0050\u0065\u0065k\u0020\u0073\u0074\u0072\u003a\u0020\u0025\u0073",_aeedd );
if (len (_aeedd )> 4)&&(_aeedd [:5]=="\u0066\u0061\u006cs\u0065"){_geag ,_ccg :=_agcf .parseBool ();if _ccg !=nil {return nil ,_ccg ;};_fab .Append (_geag );}else if (len (_aeedd )> 3)&&(_aeedd [:4]=="\u0074\u0072\u0075\u0065"){_cacg ,_aeg :=_agcf .parseBool ();
if _aeg !=nil {return nil ,_aeg ;};_fab .Append (_cacg );}else {_fdb ,_dcd :=_agcf .parseOperand ();if _dcd !=nil {return nil ,_dcd ;};_fab .Append (_fdb );};};};return _fab ,nil ;};func (_bad *PSReal )String ()string {return _eg .Sprintf ("\u0025\u002e\u0035\u0066",_bad .Val )};
2020-10-19 10:58:10 +00:00
2021-03-13 21:28:23 +00:00
2021-04-23 20:28:14 +00:00
// PSReal represents a real number.
type PSReal struct{Val float64 ;};
2021-03-23 23:12:52 +00:00
2021-04-23 20:28:14 +00:00
// PopInteger specificially pops an integer from the top of the stack, returning the value as an int.
func (_gbcf *PSStack )PopInteger ()(int ,error ){_cad ,_dfae :=_gbcf .Pop ();if _dfae !=nil {return 0,_dfae ;};if _fbge ,_gcga :=_cad .(*PSInteger );_gcga {return _fbge .Val ,nil ;};return 0,ErrTypeCheck ;};func (_cec *PSOperand )atan (_fae *PSStack )error {_cfc ,_gd :=_fae .PopNumberAsFloat64 ();
if _gd !=nil {return _gd ;};_gfge ,_gd :=_fae .PopNumberAsFloat64 ();if _gd !=nil {return _gd ;};if _cfc ==0{var _adea error ;if _gfge < 0{_adea =_fae .Push (MakeReal (270));}else {_adea =_fae .Push (MakeReal (90));};return _adea ;};_gca :=_gfge /_cfc ;
_gff :=_c .Atan (_gca )*180/_c .Pi ;_gd =_fae .Push (MakeReal (_gff ));return _gd ;};const _dd =0.000001;func (_bbg *PSOperand )ifCondition (_beg *PSStack )error {_dcc ,_cdca :=_beg .Pop ();if _cdca !=nil {return _cdca ;};_bdc ,_cdca :=_beg .Pop ();if _cdca !=nil {return _cdca ;
};_aecb ,_dceg :=_dcc .(*PSProgram );if !_dceg {return ErrTypeCheck ;};_dbbf ,_dceg :=_bdc .(*PSBoolean );if !_dceg {return ErrTypeCheck ;};if _dbbf .Val {_gbbf :=_aecb .Exec (_beg );return _gbbf ;};return nil ;};
2021-04-06 22:35:37 +00:00
2021-04-17 13:46:54 +00:00
// PSExecutor has its own execution stack and is used to executre a PS routine (program).
2021-04-23 20:28:14 +00:00
type PSExecutor struct{Stack *PSStack ;_fb *PSProgram ;};var ErrUnsupportedOperand =_b .New ("\u0075\u006e\u0073\u0075pp\u006f\u0072\u0074\u0065\u0064\u0020\u006f\u0070\u0065\u0072\u0061\u006e\u0064");
2021-04-06 22:35:37 +00:00
2021-04-23 20:28:14 +00:00
// MakeInteger returns a new PSInteger object initialized with `val`.
func MakeInteger (val int )*PSInteger {_cgba :=PSInteger {};_cgba .Val =val ;return &_cgba };func (_cgd *PSOperand )mod (_gbff *PSStack )error {_fcd ,_age :=_gbff .Pop ();if _age !=nil {return _age ;};_degc ,_age :=_gbff .Pop ();if _age !=nil {return _age ;
};_dgf ,_badd :=_fcd .(*PSInteger );if !_badd {return ErrTypeCheck ;};if _dgf .Val ==0{return ErrUndefinedResult ;};_ebca ,_badd :=_degc .(*PSInteger );if !_badd {return ErrTypeCheck ;};_bdd :=_ebca .Val %_dgf .Val ;_age =_gbff .Push (MakeInteger (_bdd ));
return _age ;};func (_dabf *PSOperand )truncate (_aeed *PSStack )error {_ccdd ,_dfa :=_aeed .Pop ();if _dfa !=nil {return _dfa ;};if _daee ,_ffgf :=_ccdd .(*PSReal );_ffgf {_ffe :=int (_daee .Val );_dfa =_aeed .Push (MakeReal (float64 (_ffe )));}else if _cdbbb ,_dcgb :=_ccdd .(*PSInteger );
_dcgb {_dfa =_aeed .Push (MakeInteger (_cdbbb .Val ));}else {return ErrTypeCheck ;};return _dfa ;};
2021-04-06 22:35:37 +00:00
2021-04-23 20:28:14 +00:00
// Push pushes an object on top of the stack.
func (_gcbe *PSStack )Push (obj PSObject )error {if len (*_gcbe )> 100{return ErrStackOverflow ;};*_gcbe =append (*_gcbe ,obj );return nil ;};
2021-04-06 22:35:37 +00:00
2021-04-17 13:46:54 +00:00
// MakeBool returns a new PSBoolean object initialized with `val`.
2021-04-23 20:28:14 +00:00
func MakeBool (val bool )*PSBoolean {_eee :=PSBoolean {};_eee .Val =val ;return &_eee };
2021-04-06 22:35:37 +00:00
2021-04-23 20:28:14 +00:00
// PSBoolean represents a boolean value.
type PSBoolean struct{Val bool ;};func (_ebea *PSParser )parseBool ()(*PSBoolean ,error ){_agdb ,_ccdg :=_ebea ._ecgc .Peek (4);if _ccdg !=nil {return MakeBool (false ),_ccdg ;};if (len (_agdb )>=4)&&(string (_agdb [:4])=="\u0074\u0072\u0075\u0065"){_ebea ._ecgc .Discard (4);
return MakeBool (true ),nil ;};_agdb ,_ccdg =_ebea ._ecgc .Peek (5);if _ccdg !=nil {return MakeBool (false ),_ccdg ;};if (len (_agdb )>=5)&&(string (_agdb [:5])=="\u0066\u0061\u006cs\u0065"){_ebea ._ecgc .Discard (5);return MakeBool (false ),nil ;};return MakeBool (false ),_b .New ("\u0075n\u0065\u0078\u0070\u0065c\u0074\u0065\u0064\u0020\u0062o\u006fl\u0065a\u006e\u0020\u0073\u0074\u0072\u0069\u006eg");
};func (_gea *PSOperand )cvi (_cce *PSStack )error {_eda ,_bca :=_cce .Pop ();if _bca !=nil {return _bca ;};if _ccb ,_dg :=_eda .(*PSReal );_dg {_ccbe :=int (_ccb .Val );_bca =_cce .Push (MakeInteger (_ccbe ));}else if _caa ,_agc :=_eda .(*PSInteger );
_agc {_bee :=_caa .Val ;_bca =_cce .Push (MakeInteger (_bee ));}else {return ErrTypeCheck ;};return _bca ;};func (_cfe *PSOperand )floor (_ced *PSStack )error {_feg ,_cdc :=_ced .Pop ();if _cdc !=nil {return _cdc ;};if _aeb ,_gcd :=_feg .(*PSReal );_gcd {_cdc =_ced .Push (MakeReal (_c .Floor (_aeb .Val )));
}else if _deda ,_bac :=_feg .(*PSInteger );_bac {_cdc =_ced .Push (MakeInteger (_deda .Val ));}else {return ErrTypeCheck ;};return _cdc ;};func (_ecg *PSOperand )abs (_ef *PSStack )error {_ac ,_ccf :=_ef .Pop ();if _ccf !=nil {return _ccf ;};if _ag ,_cge :=_ac .(*PSReal );
_cge {_bae :=_ag .Val ;if _bae < 0{_ccf =_ef .Push (MakeReal (-_bae ));}else {_ccf =_ef .Push (MakeReal (_bae ));};}else if _agg ,_ecd :=_ac .(*PSInteger );_ecd {_bda :=_agg .Val ;if _bda < 0{_ccf =_ef .Push (MakeInteger (-_bda ));}else {_ccf =_ef .Push (MakeInteger (_bda ));
};}else {return ErrTypeCheck ;};return _ccf ;};