unipdf/ps/ps.go

208 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-02-22 02:29:48 +00:00
package ps ;import (_f "bufio";_a "bytes";_b "errors";_ef "fmt";_gg "github.com/unidoc/unipdf/v3/common";_ec "github.com/unidoc/unipdf/v3/core";_e "io";_bf "math";);
2020-08-27 21:45:09 +00:00
2021-02-22 02:29:48 +00:00
// Append appends an object to the PSProgram.
func (_gcd *PSProgram )Append (obj PSObject ){*_gcd =append (*_gcd ,obj )};
2020-12-06 13:03:03 +00:00
2021-02-22 02:29:48 +00:00
// PSObject represents a postscript object.
type PSObject interface{
2021-01-07 14:20:10 +00:00
2021-02-22 02:29:48 +00:00
// Duplicate makes a fresh copy of the PSObject.
Duplicate ()PSObject ;
2020-08-27 21:45:09 +00:00
2021-02-22 02:29:48 +00:00
// DebugString returns a descriptive representation of the PSObject with more information than String()
// for debugging purposes.
DebugString ()string ;
2020-09-07 00:23:12 +00:00
2021-02-22 02:29:48 +00:00
// String returns a string representation of the PSObject.
String ()string ;};func (_ebgf *PSOperand )idiv (_agc *PSStack )error {_aga ,_afd :=_agc .Pop ();if _afd !=nil {return _afd ;};_cad ,_afd :=_agc .Pop ();if _afd !=nil {return _afd ;};_dag ,_abc :=_aga .(*PSInteger );if !_abc {return ErrTypeCheck ;};if _dag .Val ==0{return ErrUndefinedResult ;
};_geg ,_abc :=_cad .(*PSInteger );if !_abc {return ErrTypeCheck ;};_edbd :=_geg .Val /_dag .Val ;_afd =_agc .Push (MakeInteger (_edbd ));return _afd ;};func (_aede *PSOperand )pop (_gdfc *PSStack )error {_ ,_ecgc :=_gdfc .Pop ();if _ecgc !=nil {return _ecgc ;
};return nil ;};func (_cf *PSInteger )DebugString ()string {return _ef .Sprintf ("\u0069\u006e\u0074\u003a\u0025\u0064",_cf .Val );};func (_eced *PSOperand )le (_dfdb *PSStack )error {_dfcc ,_afca :=_dfdb .PopNumberAsFloat64 ();if _afca !=nil {return _afca ;
};_agd ,_afca :=_dfdb .PopNumberAsFloat64 ();if _afca !=nil {return _afca ;};if _bf .Abs (_agd -_dfcc )< _d {_eee :=_dfdb .Push (MakeBool (true ));return _eee ;}else if _agd < _dfcc {_ddf :=_dfdb .Push (MakeBool (true ));return _ddf ;}else {_gefa :=_dfdb .Push (MakeBool (false ));
return _gefa ;};};
2020-08-27 21:45:09 +00:00
2021-02-22 02:29:48 +00:00
// String returns a string representation of the stack.
func (_dbf *PSStack )String ()string {_ada :="\u005b\u0020";for _ ,_cde :=range *_dbf {_ada +=_cde .String ();_ada +="\u0020";};_ada +="\u005d";return _ada ;};func (_fde *PSOperand )div (_cacf *PSStack )error {_gee ,_bdd :=_cacf .Pop ();if _bdd !=nil {return _bdd ;
};_aab ,_bdd :=_cacf .Pop ();if _bdd !=nil {return _bdd ;};_dgd ,_ccga :=_gee .(*PSReal );_gbbg ,_cgf :=_gee .(*PSInteger );if !_ccga &&!_cgf {return ErrTypeCheck ;};if _ccga &&_dgd .Val ==0{return ErrUndefinedResult ;};if _cgf &&_gbbg .Val ==0{return ErrUndefinedResult ;
};_cee ,_fffb :=_aab .(*PSReal );_fcd ,_bbdc :=_aab .(*PSInteger );if !_fffb &&!_bbdc {return ErrTypeCheck ;};var _bca float64 ;if _fffb {_bca =_cee .Val ;}else {_bca =float64 (_fcd .Val );};if _ccga {_bca /=_dgd .Val ;}else {_bca /=float64 (_gbbg .Val );
};_bdd =_cacf .Push (MakeReal (_bca ));return _bdd ;};func (_ffe *PSOperand )String ()string {return string (*_ffe )};func (_gaa *PSBoolean )String ()string {return _ef .Sprintf ("\u0025\u0076",_gaa .Val )};
2020-08-27 21:45:09 +00:00
2021-02-22 02:29:48 +00:00
// Exec executes the operand `op` in the state specified by `stack`.
func (_ag *PSOperand )Exec (stack *PSStack )error {_ebf :=ErrUnsupportedOperand ;switch *_ag {case "\u0061\u0062\u0073":_ebf =_ag .abs (stack );case "\u0061\u0064\u0064":_ebf =_ag .add (stack );case "\u0061\u006e\u0064":_ebf =_ag .and (stack );case "\u0061\u0074\u0061\u006e":_ebf =_ag .atan (stack );
case "\u0062\u0069\u0074\u0073\u0068\u0069\u0066\u0074":_ebf =_ag .bitshift (stack );case "\u0063e\u0069\u006c\u0069\u006e\u0067":_ebf =_ag .ceiling (stack );case "\u0063\u006f\u0070\u0079":_ebf =_ag .copy (stack );case "\u0063\u006f\u0073":_ebf =_ag .cos (stack );
case "\u0063\u0076\u0069":_ebf =_ag .cvi (stack );case "\u0063\u0076\u0072":_ebf =_ag .cvr (stack );case "\u0064\u0069\u0076":_ebf =_ag .div (stack );case "\u0064\u0075\u0070":_ebf =_ag .dup (stack );case "\u0065\u0071":_ebf =_ag .eq (stack );case "\u0065\u0078\u0063\u0068":_ebf =_ag .exch (stack );
case "\u0065\u0078\u0070":_ebf =_ag .exp (stack );case "\u0066\u006c\u006fo\u0072":_ebf =_ag .floor (stack );case "\u0067\u0065":_ebf =_ag .ge (stack );case "\u0067\u0074":_ebf =_ag .gt (stack );case "\u0069\u0064\u0069\u0076":_ebf =_ag .idiv (stack );
case "\u0069\u0066":_ebf =_ag .ifCondition (stack );case "\u0069\u0066\u0065\u006c\u0073\u0065":_ebf =_ag .ifelse (stack );case "\u0069\u006e\u0064e\u0078":_ebf =_ag .index (stack );case "\u006c\u0065":_ebf =_ag .le (stack );case "\u006c\u006f\u0067":_ebf =_ag .log (stack );
case "\u006c\u006e":_ebf =_ag .ln (stack );case "\u006c\u0074":_ebf =_ag .lt (stack );case "\u006d\u006f\u0064":_ebf =_ag .mod (stack );case "\u006d\u0075\u006c":_ebf =_ag .mul (stack );case "\u006e\u0065":_ebf =_ag .ne (stack );case "\u006e\u0065\u0067":_ebf =_ag .neg (stack );
case "\u006e\u006f\u0074":_ebf =_ag .not (stack );case "\u006f\u0072":_ebf =_ag .or (stack );case "\u0070\u006f\u0070":_ebf =_ag .pop (stack );case "\u0072\u006f\u0075n\u0064":_ebf =_ag .round (stack );case "\u0072\u006f\u006c\u006c":_ebf =_ag .roll (stack );
case "\u0073\u0069\u006e":_ebf =_ag .sin (stack );case "\u0073\u0071\u0072\u0074":_ebf =_ag .sqrt (stack );case "\u0073\u0075\u0062":_ebf =_ag .sub (stack );case "\u0074\u0072\u0075\u006e\u0063\u0061\u0074\u0065":_ebf =_ag .truncate (stack );case "\u0078\u006f\u0072":_ebf =_ag .xor (stack );
};return _ebf ;};
2020-10-19 10:58:10 +00:00
2021-02-22 02:29:48 +00:00
// PSExecutor has its own execution stack and is used to executre a PS routine (program).
type PSExecutor struct{Stack *PSStack ;_ga *PSProgram ;};func (_gce *PSOperand )ne (_gfec *PSStack )error {_badf :=_gce .eq (_gfec );if _badf !=nil {return _badf ;};_badf =_gce .not (_gfec );return _badf ;};
2021-01-26 01:31:56 +00:00
2021-02-22 02:29:48 +00:00
// PopInteger specificially pops an integer from the top of the stack, returning the value as an int.
func (_gfeb *PSStack )PopInteger ()(int ,error ){_cegc ,_dabf :=_gfeb .Pop ();if _dabf !=nil {return 0,_dabf ;};if _dfbe ,_dce :=_cegc .(*PSInteger );_dce {return _dfbe .Val ,nil ;};return 0,ErrTypeCheck ;};func (_dfe *PSOperand )cos (_dgc *PSStack )error {_dc ,_cac :=_dgc .PopNumberAsFloat64 ();
if _cac !=nil {return _cac ;};_baf :=_bf .Cos (_dc *_bf .Pi /180.0);_cac =_dgc .Push (MakeReal (_baf ));return _cac ;};func (_dfa *PSOperand )atan (_bdc *PSStack )error {_cg ,_eag :=_bdc .PopNumberAsFloat64 ();if _eag !=nil {return _eag ;};_dfd ,_eag :=_bdc .PopNumberAsFloat64 ();
if _eag !=nil {return _eag ;};if _cg ==0{var _cge error ;if _dfd < 0{_cge =_bdc .Push (MakeReal (270));}else {_cge =_bdc .Push (MakeReal (90));};return _cge ;};_fg :=_dfd /_cg ;_cega :=_bf .Atan (_fg )*180/_bf .Pi ;_eag =_bdc .Push (MakeReal (_cega ));
return _eag ;};
2020-11-23 22:15:56 +00:00
2021-02-22 02:29:48 +00:00
// PSObjectArrayToFloat64Array converts []PSObject into a []float64 array. Each PSObject must represent a number,
// otherwise a ErrTypeCheck error occurs.
func PSObjectArrayToFloat64Array (objects []PSObject )([]float64 ,error ){var _ea []float64 ;for _ ,_de :=range objects {if _eb ,_dg :=_de .(*PSInteger );_dg {_ea =append (_ea ,float64 (_eb .Val ));}else if _ee ,_ff :=_de .(*PSReal );_ff {_ea =append (_ea ,_ee .Val );
}else {return nil ,ErrTypeCheck ;};};return _ea ,nil ;};func (_bcg *PSOperand )ifelse (_gca *PSStack )error {_dccf ,_eec :=_gca .Pop ();if _eec !=nil {return _eec ;};_bdf ,_eec :=_gca .Pop ();if _eec !=nil {return _eec ;};_ebba ,_eec :=_gca .Pop ();if _eec !=nil {return _eec ;
};_bfcg ,_db :=_dccf .(*PSProgram );if !_db {return ErrTypeCheck ;};_cgcd ,_db :=_bdf .(*PSProgram );if !_db {return ErrTypeCheck ;};_edf ,_db :=_ebba .(*PSBoolean );if !_db {return ErrTypeCheck ;};if _edf .Val {_dab :=_cgcd .Exec (_gca );return _dab ;
};_eec =_bfcg .Exec (_gca );return _eec ;};func (_cedb *PSOperand )ln (_ccac *PSStack )error {_aadb ,_bea :=_ccac .PopNumberAsFloat64 ();if _bea !=nil {return _bea ;};_gcb :=_bf .Log (_aadb );_bea =_ccac .Push (MakeReal (_gcb ));return _bea ;};var ErrStackOverflow =_b .New ("\u0073\u0074\u0061\u0063\u006b\u0020\u006f\u0076\u0065r\u0066\u006c\u006f\u0077");
func (_eab *PSOperand )bitshift (_fcb *PSStack )error {_cga ,_cff :=_fcb .PopInteger ();if _cff !=nil {return _cff ;};_bga ,_cff :=_fcb .PopInteger ();if _cff !=nil {return _cff ;};var _acg int ;if _cga >=0{_acg =_bga <<uint (_cga );}else {_acg =_bga >>uint (-_cga );
};_cff =_fcb .Push (MakeInteger (_acg ));return _cff ;};func (_cbd *PSParser )skipSpaces ()(int ,error ){_acec :=0;for {_aeaf ,_bcff :=_cbd ._bbag .Peek (1);if _bcff !=nil {return 0,_bcff ;};if _ec .IsWhiteSpace (_aeaf [0]){_cbd ._bbag .ReadByte ();_acec ++;
}else {break ;};};return _acec ,nil ;};func (_cae *PSOperand )floor (_edg *PSStack )error {_dea ,_dca :=_edg .Pop ();if _dca !=nil {return _dca ;};if _bfc ,_gbbgb :=_dea .(*PSReal );_gbbgb {_dca =_edg .Push (MakeReal (_bf .Floor (_bfc .Val )));}else if _gfc ,_gdf :=_dea .(*PSInteger );
_gdf {_dca =_edg .Push (MakeInteger (_gfc .Val ));}else {return ErrTypeCheck ;};return _dca ;};func (_baa *PSOperand )Duplicate ()PSObject {_fd :=*_baa ;return &_fd };
2020-11-23 22:15:56 +00:00
2021-02-22 02:29:48 +00:00
// Exec executes the program, typically leaving output values on the stack.
func (_fff *PSProgram )Exec (stack *PSStack )error {for _ ,_bc :=range *_fff {var _fc error ;switch _bg :=_bc .(type ){case *PSInteger :_aed :=_bg ;_fc =stack .Push (_aed );case *PSReal :_ffb :=_bg ;_fc =stack .Push (_ffb );case *PSBoolean :_eeg :=_bg ;
_fc =stack .Push (_eeg );case *PSProgram :_gea :=_bg ;_fc =stack .Push (_gea );case *PSOperand :_ab :=_bg ;_fc =_ab .Exec (stack );default:return ErrTypeCheck ;};if _fc !=nil {return _fc ;};};return nil ;};
// PSOperand represents a Postscript operand (text string).
type PSOperand string ;func (_ba *PSProgram )DebugString ()string {_gga :="\u007b\u0020";for _ ,_ae :=range *_ba {_gga +=_ae .DebugString ();_gga +="\u0020";};_gga +="\u007d";return _gga ;};func (_ebg *PSOperand )exch (_fcf *PSStack )error {_gdae ,_cgc :=_fcf .Pop ();
if _cgc !=nil {return _cgc ;};_bcf ,_cgc :=_fcf .Pop ();if _cgc !=nil {return _cgc ;};_cgc =_fcf .Push (_gdae );if _cgc !=nil {return _cgc ;};_cgc =_fcf .Push (_bcf );return _cgc ;};func (_degb *PSOperand )add (_egf *PSStack )error {_cfd ,_gef :=_egf .Pop ();
if _gef !=nil {return _gef ;};_bed ,_gef :=_egf .Pop ();if _gef !=nil {return _gef ;};_aaeg ,_eed :=_cfd .(*PSReal );_df ,_gab :=_cfd .(*PSInteger );if !_eed &&!_gab {return ErrTypeCheck ;};_dd ,_fed :=_bed .(*PSReal );_edc ,_afc :=_bed .(*PSInteger );
if !_fed &&!_afc {return ErrTypeCheck ;};if _gab &&_afc {_ddc :=_df .Val +_edc .Val ;_bcb :=_egf .Push (MakeInteger (_ddc ));return _bcb ;};var _gag float64 ;if _eed {_gag =_aaeg .Val ;}else {_gag =float64 (_df .Val );};if _fed {_gag +=_dd .Val ;}else {_gag +=float64 (_edc .Val );
};_gef =_egf .Push (MakeReal (_gag ));return _gef ;};func (_dee *PSInteger )String ()string {return _ef .Sprintf ("\u0025\u0064",_dee .Val )};
2020-08-27 21:45:09 +00:00
2021-02-11 10:35:13 +00:00
// Empty empties the stack.
2021-02-22 02:29:48 +00:00
func (_aef *PSStack )Empty (){*_aef =[]PSObject {}};func (_aee *PSParser )parseBool ()(*PSBoolean ,error ){_geb ,_ggc :=_aee ._bbag .Peek (4);if _ggc !=nil {return MakeBool (false ),_ggc ;};if (len (_geb )>=4)&&(string (_geb [:4])=="\u0074\u0072\u0075\u0065"){_aee ._bbag .Discard (4);
return MakeBool (true ),nil ;};_geb ,_ggc =_aee ._bbag .Peek (5);if _ggc !=nil {return MakeBool (false ),_ggc ;};if (len (_geb )>=5)&&(string (_geb [:5])=="\u0066\u0061\u006cs\u0065"){_aee ._bbag .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");
};
2020-08-27 21:45:09 +00:00
2021-02-22 02:29:48 +00:00
// PSProgram defines a Postscript program which is a series of PS objects (arguments, commands, programs etc).
type PSProgram []PSObject ;
2020-08-27 21:45:09 +00:00
2021-02-22 02:29:48 +00:00
// NewPSProgram returns an empty, initialized PSProgram.
func NewPSProgram ()*PSProgram {return &PSProgram {}};
2020-11-11 18:48:37 +00:00
2021-02-11 10:35:13 +00:00
// MakeReal returns a new PSReal object initialized with `val`.
2021-02-22 02:29:48 +00:00
func MakeReal (val float64 )*PSReal {_deff :=PSReal {};_deff .Val =val ;return &_deff };
2020-10-12 14:17:59 +00:00
2021-02-22 02:29:48 +00:00
// PSInteger represents an integer.
type PSInteger struct{Val int ;};var ErrUnsupportedOperand =_b .New ("\u0075\u006e\u0073\u0075pp\u006f\u0072\u0074\u0065\u0064\u0020\u006f\u0070\u0065\u0072\u0061\u006e\u0064");
2020-10-12 14:17:59 +00:00
2021-02-22 02:29:48 +00:00
// PSStack defines a stack of PSObjects. PSObjects can be pushed on or pull from the stack.
type PSStack []PSObject ;func (_fgc *PSOperand )gt (_gac *PSStack )error {_cccb ,_bag :=_gac .PopNumberAsFloat64 ();if _bag !=nil {return _bag ;};_gaf ,_bag :=_gac .PopNumberAsFloat64 ();if _bag !=nil {return _bag ;};if _bf .Abs (_gaf -_cccb )< _d {_cgfe :=_gac .Push (MakeBool (false ));
return _cgfe ;}else if _gaf > _cccb {_fcfa :=_gac .Push (MakeBool (true ));return _fcfa ;}else {_dga :=_gac .Push (MakeBool (false ));return _dga ;};};
2020-10-12 14:17:59 +00:00
2021-02-22 02:29:48 +00:00
// NewPSExecutor returns an initialized PSExecutor for an input `program`.
func NewPSExecutor (program *PSProgram )*PSExecutor {_c :=&PSExecutor {};_c .Stack =NewPSStack ();_c ._ga =program ;return _c ;};var ErrTypeCheck =_b .New ("\u0074\u0079p\u0065\u0020\u0063h\u0065\u0063\u006b\u0020\u0065\u0072\u0072\u006f\u0072");
2020-09-28 23:18:17 +00:00
2021-02-22 02:29:48 +00:00
// MakeBool returns a new PSBoolean object initialized with `val`.
func MakeBool (val bool )*PSBoolean {_cbfg :=PSBoolean {};_cbfg .Val =val ;return &_cbfg };func (_bde *PSBoolean )Duplicate ()PSObject {_ed :=PSBoolean {};_ed .Val =_bde .Val ;return &_ed };
2021-02-11 10:35:13 +00:00
2021-02-22 02:29:48 +00:00
// MakeOperand returns a new PSOperand object based on string `val`.
func MakeOperand (val string )*PSOperand {_gdcc :=PSOperand (val );return &_gdcc };func (_aa *PSReal )DebugString ()string {return _ef .Sprintf ("\u0072e\u0061\u006c\u003a\u0025\u002e\u0035f",_aa .Val );};
2021-02-11 10:35:13 +00:00
2021-02-22 02:29:48 +00:00
// Pop pops an object from the top of the stack.
func (_abbe *PSStack )Pop ()(PSObject ,error ){if len (*_abbe )< 1{return nil ,ErrStackUnderflow ;};_gbf :=(*_abbe )[len (*_abbe )-1];*_abbe =(*_abbe )[0:len (*_abbe )-1];return _gbf ,nil ;};
2020-08-27 21:45:09 +00:00
2021-02-22 02:29:48 +00:00
// PSReal represents a real number.
type PSReal struct{Val float64 ;};func (_dfde *PSParser )parseOperand ()(*PSOperand ,error ){var _bdad []byte ;for {_acee ,_bef :=_dfde ._bbag .Peek (1);if _bef !=nil {if _bef ==_e .EOF {break ;};return nil ,_bef ;};if _ec .IsDelimiter (_acee [0]){break ;
};if _ec .IsWhiteSpace (_acee [0]){break ;};_affc ,_ :=_dfde ._bbag .ReadByte ();_bdad =append (_bdad ,_affc );};if len (_bdad )==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 (_bdad )),nil ;};func (_ddcb *PSOperand )dup (_fbff *PSStack )error {_efg ,_ddb :=_fbff .Pop ();if _ddb !=nil {return _ddb ;};_ddb =_fbff .Push (_efg );if _ddb !=nil {return _ddb ;};_ddb =_fbff .Push (_efg .Duplicate ());return _ddb ;
};func (_bb *PSOperand )DebugString ()string {return _ef .Sprintf ("\u006fp\u003a\u0027\u0025\u0073\u0027",*_bb );};func (_caca *PSOperand )or (_fcg *PSStack )error {_bbab ,_gff :=_fcg .Pop ();if _gff !=nil {return _gff ;};_bagc ,_gff :=_fcg .Pop ();if _gff !=nil {return _gff ;
};if _bff ,_cdd :=_bbab .(*PSBoolean );_cdd {_adcc ,_bbgb :=_bagc .(*PSBoolean );if !_bbgb {return ErrTypeCheck ;};_gff =_fcg .Push (MakeBool (_bff .Val ||_adcc .Val ));return _gff ;};if _gdbb ,_dcbc :=_bbab .(*PSInteger );_dcbc {_ebaf ,_aaff :=_bagc .(*PSInteger );
if !_aaff {return ErrTypeCheck ;};_gff =_fcg .Push (MakeInteger (_gdbb .Val |_ebaf .Val ));return _gff ;};return ErrTypeCheck ;};func (_geag *PSOperand )and (_gbb *PSStack )error {_fdb ,_feg :=_gbb .Pop ();if _feg !=nil {return _feg ;};_ad ,_feg :=_gbb .Pop ();
if _feg !=nil {return _feg ;};if _edcb ,_bedc :=_fdb .(*PSBoolean );_bedc {_aaa ,_bbd :=_ad .(*PSBoolean );if !_bbd {return ErrTypeCheck ;};_feg =_gbb .Push (MakeBool (_edcb .Val &&_aaa .Val ));return _feg ;};if _edb ,_agg :=_fdb .(*PSInteger );_agg {_age ,_fa :=_ad .(*PSInteger );
if !_fa {return ErrTypeCheck ;};_feg =_gbb .Push (MakeInteger (_edb .Val &_age .Val ));return _feg ;};return ErrTypeCheck ;};
2020-10-19 10:58:10 +00:00
2021-02-11 10:35:13 +00:00
// NewPSParser returns a new instance of the PDF Postscript parser from input data.
2021-02-22 02:29:48 +00:00
func NewPSParser (content []byte )*PSParser {_cgd :=PSParser {};_fcgg :=_a .NewBuffer (content );_cgd ._bbag =_f .NewReader (_fcgg );return &_cgd ;};func (_gfdd *PSOperand )eq (_add *PSStack )error {_eegc ,_faa :=_add .Pop ();if _faa !=nil {return _faa ;
};_beg ,_faa :=_add .Pop ();if _faa !=nil {return _faa ;};_gad ,_agf :=_eegc .(*PSBoolean );_bba ,_aea :=_beg .(*PSBoolean );if _agf ||_aea {var _cace error ;if _agf &&_aea {_cace =_add .Push (MakeBool (_gad .Val ==_bba .Val ));}else {_cace =_add .Push (MakeBool (false ));
};return _cace ;};var _fbfe float64 ;var _dac float64 ;if _egc ,_aaebe :=_eegc .(*PSInteger );_aaebe {_fbfe =float64 (_egc .Val );}else if _bbg ,_dgf :=_eegc .(*PSReal );_dgf {_fbfe =_bbg .Val ;}else {return ErrTypeCheck ;};if _ebb ,_fcde :=_beg .(*PSInteger );
_fcde {_dac =float64 (_ebb .Val );}else if _bbe ,_ddd :=_beg .(*PSReal );_ddd {_dac =_bbe .Val ;}else {return ErrTypeCheck ;};if _bf .Abs (_dac -_fbfe )< _d {_faa =_add .Push (MakeBool (true ));}else {_faa =_add .Push (MakeBool (false ));};return _faa ;
};func (_afa *PSProgram )Duplicate ()PSObject {_ge :=&PSProgram {};for _ ,_aca :=range *_afa {_ge .Append (_aca .Duplicate ());};return _ge ;};func (_bbea *PSOperand )log (_eabf *PSStack )error {_aaf ,_bfa :=_eabf .PopNumberAsFloat64 ();if _bfa !=nil {return _bfa ;
};_bbf :=_bf .Log10 (_aaf );_bfa =_eabf .Push (MakeReal (_bbf ));return _bfa ;};func (_aaef *PSOperand )mul (_dfg *PSStack )error {_bcgd ,_ffbb :=_dfg .Pop ();if _ffbb !=nil {return _ffbb ;};_faff ,_ffbb :=_dfg .Pop ();if _ffbb !=nil {return _ffbb ;};_bgbb ,_adc :=_bcgd .(*PSReal );
_cfda ,_ecg :=_bcgd .(*PSInteger );if !_adc &&!_ecg {return ErrTypeCheck ;};_fdc ,_cfc :=_faff .(*PSReal );_gba ,_fcfc :=_faff .(*PSInteger );if !_cfc &&!_fcfc {return ErrTypeCheck ;};if _ecg &&_fcfc {_fge :=_cfda .Val *_gba .Val ;_egb :=_dfg .Push (MakeInteger (_fge ));
return _egb ;};var _eba float64 ;if _adc {_eba =_bgbb .Val ;}else {_eba =float64 (_cfda .Val );};if _cfc {_eba *=_fdc .Val ;}else {_eba *=float64 (_gba .Val );};_ffbb =_dfg .Push (MakeReal (_eba ));return _ffbb ;};func (_baab *PSOperand )neg (_bcab *PSStack )error {_bab ,_fgb :=_bcab .Pop ();
if _fgb !=nil {return _fgb ;};if _bedf ,_fab :=_bab .(*PSReal );_fab {_fgb =_bcab .Push (MakeReal (-_bedf .Val ));return _fgb ;}else if _dfed ,_gdfb :=_bab .(*PSInteger );_gdfb {_fgb =_bcab .Push (MakeInteger (-_dfed .Val ));return _fgb ;}else {return ErrTypeCheck ;
};};func (_bbgf *PSOperand )index (_bge *PSStack )error {_gdaf ,_edd :=_bge .Pop ();if _edd !=nil {return _edd ;};_dcd ,_ega :=_gdaf .(*PSInteger );if !_ega {return ErrTypeCheck ;};if _dcd .Val < 0{return ErrRangeCheck ;};if _dcd .Val > len (*_bge )-1{return ErrStackUnderflow ;
};_efge :=(*_bge )[len (*_bge )-1-_dcd .Val ];_edd =_bge .Push (_efge .Duplicate ());return _edd ;};
2020-10-19 10:58:10 +00:00
2021-02-22 02:29:48 +00:00
// NewPSStack returns an initialized PSStack.
func NewPSStack ()*PSStack {return &PSStack {}};func (_gfe *PSOperand )ifCondition (_ggg *PSStack )error {_fga ,_fced :=_ggg .Pop ();if _fced !=nil {return _fced ;};_fcdf ,_fced :=_ggg .Pop ();if _fced !=nil {return _fced ;};_cfe ,_caa :=_fga .(*PSProgram );
if !_caa {return ErrTypeCheck ;};_geeg ,_caa :=_fcdf .(*PSBoolean );if !_caa {return ErrTypeCheck ;};if _geeg .Val {_dfea :=_cfe .Exec (_ggg );return _dfea ;};return nil ;};
2020-10-19 10:58:10 +00:00
2021-02-22 02:29:48 +00:00
// Parse parses the postscript and store as a program that can be executed.
func (_gfef *PSParser )Parse ()(*PSProgram ,error ){_gfef .skipSpaces ();_dage ,_edgd :=_gfef ._bbag .Peek (2);if _edgd !=nil {return nil ,_edgd ;};if _dage [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");
};_degc ,_edgd :=_gfef .parseFunction ();if _edgd !=nil &&_edgd !=_e .EOF {return nil ,_edgd ;};return _degc ,_edgd ;};
2020-08-27 21:45:09 +00:00
2021-02-22 02:29:48 +00:00
// MakeInteger returns a new PSInteger object initialized with `val`.
func MakeInteger (val int )*PSInteger {_egce :=PSInteger {};_egce .Val =val ;return &_egce };var ErrRangeCheck =_b .New ("\u0072\u0061\u006e\u0067\u0065\u0020\u0063\u0068\u0065\u0063\u006b\u0020e\u0072\u0072\u006f\u0072");func (_dfb *PSOperand )xor (_dbc *PSStack )error {_egdg ,_gaff :=_dbc .Pop ();
if _gaff !=nil {return _gaff ;};_egg ,_gaff :=_dbc .Pop ();if _gaff !=nil {return _gaff ;};if _gcdc ,_cdb :=_egdg .(*PSBoolean );_cdb {_gdg ,_dbe :=_egg .(*PSBoolean );if !_dbe {return ErrTypeCheck ;};_gaff =_dbc .Push (MakeBool (_gcdc .Val !=_gdg .Val ));
return _gaff ;};if _debg ,_egbc :=_egdg .(*PSInteger );_egbc {_bgfd ,_ffc :=_egg .(*PSInteger );if !_ffc {return ErrTypeCheck ;};_gaff =_dbc .Push (MakeInteger (_debg .Val ^_bgfd .Val ));return _gaff ;};return ErrTypeCheck ;};func (_dfc *PSOperand )cvr (_bgae *PSStack )error {_fdbf ,_bda :=_bgae .Pop ();
if _bda !=nil {return _bda ;};if _gge ,_acd :=_fdbf .(*PSReal );_acd {_bda =_bgae .Push (MakeReal (_gge .Val ));}else if _bdcb ,_da :=_fdbf .(*PSInteger );_da {_bda =_bgae .Push (MakeReal (float64 (_bdcb .Val )));}else {return ErrTypeCheck ;};return _bda ;
};func (_ccg *PSOperand )cvi (_abd *PSStack )error {_fffg ,_gfd :=_abd .Pop ();if _gfd !=nil {return _gfd ;};if _eda ,_gda :=_fffg .(*PSReal );_gda {_fbb :=int (_eda .Val );_gfd =_abd .Push (MakeInteger (_fbb ));}else if _ade ,_bedd :=_fffg .(*PSInteger );
_bedd {_ced :=_ade .Val ;_gfd =_abd .Push (MakeInteger (_ced ));}else {return ErrTypeCheck ;};return _gfd ;};func (_dgba *PSOperand )copy (_cd *PSStack )error {_dec ,_bgb :=_cd .PopInteger ();if _bgb !=nil {return _bgb ;};if _dec < 0{return ErrRangeCheck ;
};if _dec > len (*_cd ){return ErrRangeCheck ;};*_cd =append (*_cd ,(*_cd )[len (*_cd )-_dec :]...);return nil ;};
2020-10-19 10:58:10 +00:00
2021-02-22 02:29:48 +00:00
// DebugString returns a descriptive string representation of the stack - intended for debugging.
func (_dfbf *PSStack )DebugString ()string {_afcad :="\u005b\u0020";for _ ,_gabb :=range *_dfbf {_afcad +=_gabb .DebugString ();_afcad +="\u0020";};_afcad +="\u005d";return _afcad ;};func (_ebe *PSOperand )sin (_fcbe *PSStack )error {_ebfa ,_fba :=_fcbe .PopNumberAsFloat64 ();
if _fba !=nil {return _fba ;};_aac :=_bf .Sin (_ebfa *_bf .Pi /180.0);_fba =_fcbe .Push (MakeReal (_aac ));return _fba ;};func (_cc *PSReal )Duplicate ()PSObject {_cca :=PSReal {};_cca .Val =_cc .Val ;return &_cca };func (_caf *PSOperand )sub (_efc *PSStack )error {_fabf ,_aecc :=_efc .Pop ();
if _aecc !=nil {return _aecc ;};_ded ,_aecc :=_efc .Pop ();if _aecc !=nil {return _aecc ;};_gdd ,_ccgf :=_fabf .(*PSReal );_bae ,_fdg :=_fabf .(*PSInteger );if !_ccgf &&!_fdg {return ErrTypeCheck ;};_cbc ,_ffbg :=_ded .(*PSReal );_gcf ,_agbb :=_ded .(*PSInteger );
if !_ffbg &&!_agbb {return ErrTypeCheck ;};if _fdg &&_agbb {_deb :=_gcf .Val -_bae .Val ;_daf :=_efc .Push (MakeInteger (_deb ));return _daf ;};var _fefc float64 =0;if _ffbg {_fefc =_cbc .Val ;}else {_fefc =float64 (_gcf .Val );};if _ccgf {_fefc -=_gdd .Val ;
}else {_fefc -=float64 (_bae .Val );};_aecc =_efc .Push (MakeReal (_fefc ));return _aecc ;};func _gbg (_efdf int )int {if _efdf < 0{return -_efdf ;};return _efdf ;};func (_fe *PSInteger )Duplicate ()PSObject {_be :=PSInteger {};_be .Val =_fe .Val ;return &_be };
func (_geaa *PSParser )parseNumber ()(PSObject ,error ){_gcfd ,_cef :=_ec .ParseNumber (_geaa ._bbag );if _cef !=nil {return nil ,_cef ;};switch _ddgc :=_gcfd .(type ){case *_ec .PdfObjectFloat :return MakeReal (float64 (*_ddgc )),nil ;case *_ec .PdfObjectInteger :return MakeInteger (int (*_ddgc )),nil ;
};return nil ,_ef .Errorf ("\u0075n\u0068\u0061\u006e\u0064\u006c\u0065\u0064\u0020\u006e\u0075\u006db\u0065\u0072\u0020\u0074\u0079\u0070\u0065\u0020\u0025\u0054",_gcfd );};func (_fcdea *PSOperand )exp (_ece *PSStack )error {_bfb ,_aff :=_ece .PopNumberAsFloat64 ();
if _aff !=nil {return _aff ;};_dcb ,_aff :=_ece .PopNumberAsFloat64 ();if _aff !=nil {return _aff ;};if _bf .Abs (_bfb )< 1&&_dcb < 0{return ErrUndefinedResult ;};_cdf :=_bf .Pow (_dcb ,_bfb );_aff =_ece .Push (MakeReal (_cdf ));return _aff ;};func (_gcc *PSOperand )abs (_efb *PSStack )error {_gcg ,_deg :=_efb .Pop ();
if _deg !=nil {return _deg ;};if _eg ,_dgb :=_gcg .(*PSReal );_dgb {_aae :=_eg .Val ;if _aae < 0{_deg =_efb .Push (MakeReal (-_aae ));}else {_deg =_efb .Push (MakeReal (_aae ));};}else if _fdf ,_cbb :=_gcg .(*PSInteger );_cbb {_gf :=_fdf .Val ;if _gf < 0{_deg =_efb .Push (MakeInteger (-_gf ));
}else {_deg =_efb .Push (MakeInteger (_gf ));};}else {return ErrTypeCheck ;};return _deg ;};const _d =0.000001;func (_aeda *PSParser )parseFunction ()(*PSProgram ,error ){_cdba ,_ :=_aeda ._bbag .ReadByte ();if _cdba !='{'{return nil ,_b .New ("\u0069\u006ev\u0061\u006c\u0069d\u0020\u0066\u0075\u006e\u0063\u0074\u0069\u006f\u006e");
};_ffd :=NewPSProgram ();for {_aeda .skipSpaces ();_cbge ,_badd :=_aeda ._bbag .Peek (2);if _badd !=nil {if _badd ==_e .EOF {break ;};return nil ,_badd ;};_gg .Log .Trace ("\u0050e\u0065k\u0020\u0073\u0074\u0072\u0069\u006e\u0067\u003a\u0020\u0025\u0073",string (_cbge ));
if _cbge [0]=='}'{_gg .Log .Trace ("\u0045\u004f\u0046 \u0066\u0075\u006e\u0063\u0074\u0069\u006f\u006e");_aeda ._bbag .ReadByte ();break ;}else if _cbge [0]=='{'{_gg .Log .Trace ("\u0046u\u006e\u0063\u0074\u0069\u006f\u006e!");_fadd ,_bgc :=_aeda .parseFunction ();
if _bgc !=nil {return nil ,_bgc ;};_ffd .Append (_fadd );}else if _ec .IsDecimalDigit (_cbge [0])||(_cbge [0]=='-'&&_ec .IsDecimalDigit (_cbge [1])){_gg .Log .Trace ("\u002d>\u004e\u0075\u006d\u0062\u0065\u0072!");_gdc ,_ddg :=_aeda .parseNumber ();if _ddg !=nil {return nil ,_ddg ;
};_ffd .Append (_gdc );}else {_gg .Log .Trace ("\u002d>\u004fp\u0065\u0072\u0061\u006e\u0064 \u006f\u0072 \u0062\u006f\u006f\u006c\u003f");_cbge ,_ =_aeda ._bbag .Peek (5);_acf :=string (_cbge );_gg .Log .Trace ("\u0050\u0065\u0065k\u0020\u0073\u0074\u0072\u003a\u0020\u0025\u0073",_acf );
if (len (_acf )> 4)&&(_acf [:5]=="\u0066\u0061\u006cs\u0065"){_ffeb ,_dfcd :=_aeda .parseBool ();if _dfcd !=nil {return nil ,_dfcd ;};_ffd .Append (_ffeb );}else if (len (_acf )> 3)&&(_acf [:4]=="\u0074\u0072\u0075\u0065"){_def ,_bdab :=_aeda .parseBool ();
if _bdab !=nil {return nil ,_bdab ;};_ffd .Append (_def );}else {_ffa ,_aedb :=_aeda .parseOperand ();if _aedb !=nil {return nil ,_aedb ;};_ffd .Append (_ffa );};};};return _ffd ,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 (_ac *PSProgram )String ()string {_bec :="\u007b\u0020";for _ ,_ceg :=range *_ac {_bec +=_ceg .String ();_bec +="\u0020";};_bec +="\u007d";return _bec ;};func (_fce *PSOperand )ge (_bdae *PSStack )error {_aad ,_dcc :=_bdae .PopNumberAsFloat64 ();if _dcc !=nil {return _dcc ;
};_bbaf ,_dcc :=_bdae .PopNumberAsFloat64 ();if _dcc !=nil {return _dcc ;};if _bf .Abs (_bbaf -_aad )< _d {_ccc :=_bdae .Push (MakeBool (true ));return _ccc ;}else if _bbaf > _aad {_fca :=_bdae .Push (MakeBool (true ));return _fca ;}else {_cbg :=_bdae .Push (MakeBool (false ));
return _cbg ;};};func (_bgf *PSOperand )ceiling (_cbbb *PSStack )error {_acc ,_aec :=_cbbb .Pop ();if _aec !=nil {return _aec ;};if _aaeb ,_ged :=_acc .(*PSReal );_ged {_aec =_cbbb .Push (MakeReal (_bf .Ceil (_aaeb .Val )));}else if _fda ,_gdb :=_acc .(*PSInteger );
_gdb {_aec =_cbbb .Push (MakeInteger (_fda .Val ));}else {_aec =ErrTypeCheck ;};return _aec ;};func (_abb *PSOperand )truncate (_cadg *PSStack )error {_acdaf ,_cda :=_cadg .Pop ();if _cda !=nil {return _cda ;};if _cfa ,_eebe :=_acdaf .(*PSReal );_eebe {_bfca :=int (_cfa .Val );
_cda =_cadg .Push (MakeReal (float64 (_bfca )));}else if _gafg ,_cdg :=_acdaf .(*PSInteger );_cdg {_cda =_cadg .Push (MakeInteger (_gafg .Val ));}else {return ErrTypeCheck ;};return _cda ;};
2020-10-19 10:58:10 +00:00
2021-02-22 02:29:48 +00:00
// Push pushes an object on top of the stack.
func (_cbaf *PSStack )Push (obj PSObject )error {if len (*_cbaf )> 100{return ErrStackOverflow ;};*_cbaf =append (*_cbaf ,obj );return nil ;};
2020-09-21 01:20:10 +00:00
2021-02-22 02:29:48 +00:00
// PopNumberAsFloat64 pops and return the numeric value of the top of the stack as a float64.
// Real or integer only.
func (_dge *PSStack )PopNumberAsFloat64 ()(float64 ,error ){_gaae ,_ebgg :=_dge .Pop ();if _ebgg !=nil {return 0,_ebgg ;};if _bbcb ,_agdb :=_gaae .(*PSReal );_agdb {return _bbcb .Val ,nil ;}else if _afdd ,_agdg :=_gaae .(*PSInteger );_agdg {return float64 (_afdd .Val ),nil ;
}else {return 0,ErrTypeCheck ;};};func (_eceg *PSOperand )mod (_ddfa *PSStack )error {_fef ,_bgd :=_ddfa .Pop ();if _bgd !=nil {return _bgd ;};_fdfb ,_bgd :=_ddfa .Pop ();if _bgd !=nil {return _bgd ;};_cgfg ,_gaba :=_fef .(*PSInteger );if !_gaba {return ErrTypeCheck ;
};if _cgfg .Val ==0{return ErrUndefinedResult ;};_cbf ,_gaba :=_fdfb .(*PSInteger );if !_gaba {return ErrTypeCheck ;};_cab :=_cbf .Val %_cgfg .Val ;_bgd =_ddfa .Push (MakeInteger (_cab ));return _bgd ;};
2020-10-05 19:28:24 +00:00
2021-02-22 02:29:48 +00:00
// PSParser is a basic Postscript parser.
type PSParser struct{_bbag *_f .Reader };func (_eca *PSOperand )sqrt (_afg *PSStack )error {_ggeb ,_bbabb :=_afg .PopNumberAsFloat64 ();if _bbabb !=nil {return _bbabb ;};if _ggeb < 0{return ErrRangeCheck ;};_bac :=_bf .Sqrt (_ggeb );_bbabb =_afg .Push (MakeReal (_bac ));
return _bbabb ;};var ErrStackUnderflow =_b .New ("\u0073t\u0061c\u006b\u0020\u0075\u006e\u0064\u0065\u0072\u0066\u006c\u006f\u0077");func (_bd *PSBoolean )DebugString ()string {return _ef .Sprintf ("\u0062o\u006f\u006c\u003a\u0025\u0076",_bd .Val );};func (_cfcf *PSOperand )not (_dcf *PSStack )error {_efe ,_gfg :=_dcf .Pop ();
if _gfg !=nil {return _gfg ;};if _aadbc ,_fbe :=_efe .(*PSBoolean );_fbe {_gfg =_dcf .Push (MakeBool (!_aadbc .Val ));return _gfg ;}else if _gcaf ,_cba :=_efe .(*PSInteger );_cba {_gfg =_dcf .Push (MakeInteger (^_gcaf .Val ));return _gfg ;}else {return ErrTypeCheck ;
};};func (_gb *PSReal )String ()string {return _ef .Sprintf ("\u0025\u002e\u0035\u0066",_gb .Val )};func (_ace *PSOperand )roll (_gfb *PSStack )error {_gfa ,_acda :=_gfb .Pop ();if _acda !=nil {return _acda ;};_bbc ,_acda :=_gfb .Pop ();if _acda !=nil {return _acda ;
};_aedd ,_egba :=_gfa .(*PSInteger );if !_egba {return ErrTypeCheck ;};_eebf ,_egba :=_bbc .(*PSInteger );if !_egba {return ErrTypeCheck ;};if _eebf .Val < 0{return ErrRangeCheck ;};if _eebf .Val ==0||_eebf .Val ==1{return nil ;};if _eebf .Val > len (*_gfb ){return ErrStackUnderflow ;
};for _eac :=0;_eac < _gbg (_aedd .Val );_eac ++{var _edbc []PSObject ;_edbc =(*_gfb )[len (*_gfb )-(_eebf .Val ):len (*_gfb )];if _aedd .Val > 0{_fdcb :=_edbc [len (_edbc )-1];_edbc =append ([]PSObject {_fdcb },_edbc [0:len (_edbc )-1]...);}else {_cbbc :=_edbc [len (_edbc )-_eebf .Val ];
_edbc =append (_edbc [1:],_cbbc );};_fad :=append ((*_gfb )[0:len (*_gfb )-_eebf .Val ],_edbc ...);_gfb =&_fad ;};return nil ;};
2021-02-11 10:35:13 +00:00
2021-02-22 02:29:48 +00:00
// Execute executes the program for an input parameters `objects` and returns a slice of output objects.
func (_ebc *PSExecutor )Execute (objects []PSObject )([]PSObject ,error ){for _ ,_ca :=range objects {_fbf :=_ebc .Stack .Push (_ca );if _fbf !=nil {return nil ,_fbf ;};};_af :=_ebc ._ga .Exec (_ebc .Stack );if _af !=nil {_gg .Log .Debug ("\u0045x\u0065c\u0020\u0066\u0061\u0069\u006c\u0065\u0064\u003a\u0020\u0025\u0076",_af );
return nil ,_af ;};_eeb :=[]PSObject (*_ebc .Stack );_ebc .Stack .Empty ();return _eeb ,nil ;};
2021-02-11 10:35:13 +00:00
2021-02-22 02:29:48 +00:00
// PSBoolean represents a boolean value.
type PSBoolean struct{Val bool ;};func (_eaf *PSOperand )lt (_cgeb *PSStack )error {_bdb ,_faf :=_cgeb .PopNumberAsFloat64 ();if _faf !=nil {return _faf ;};_fbfea ,_faf :=_cgeb .PopNumberAsFloat64 ();if _faf !=nil {return _faf ;};if _bf .Abs (_fbfea -_bdb )< _d {_egd :=_cgeb .Push (MakeBool (false ));
return _egd ;}else if _fbfea < _bdb {_bad :=_cgeb .Push (MakeBool (true ));return _bad ;}else {_dfeg :=_cgeb .Push (MakeBool (false ));return _dfeg ;};};func (_caec *PSOperand )round (_bfgf *PSStack )error {_ccd ,_gae :=_bfgf .Pop ();if _gae !=nil {return _gae ;
};if _gcea ,_cacag :=_ccd .(*PSReal );_cacag {_gae =_bfgf .Push (MakeReal (_bf .Floor (_gcea .Val +0.5)));}else if _bbeaf ,_agb :=_ccd .(*PSInteger );_agb {_gae =_bfgf .Push (MakeInteger (_bbeaf .Val ));}else {return ErrTypeCheck ;};return _gae ;};