mirror of
https://github.com/unidoc/unipdf.git
synced 2025-04-27 13:48:51 +08:00
119 lines
32 KiB
Go
119 lines
32 KiB
Go
//
|
|
// 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.
|
|
package ps ;import (_df "bufio";_c "bytes";_d "errors";_e "fmt";_dfe "github.com/unidoc/unipdf/v3/common";_cd "github.com/unidoc/unipdf/v3/core";_b "io";_bb "math";);
|
|
|
|
// NewPSParser returns a new instance of the PDF Postscript parser from input data.
|
|
func NewPSParser (content []byte )*PSParser {_facc :=PSParser {};_acc :=_c .NewBuffer (content );_facc ._acfg =_df .NewReader (_acc );return &_facc ;};var ErrTypeCheck =_d .New ("\u0074\u0079p\u0065\u0020\u0063h\u0065\u0063\u006b\u0020\u0065\u0072\u0072\u006f\u0072");
|
|
|
|
// Pop pops an object from the top of the stack.
|
|
func (_bcg *PSStack )Pop ()(PSObject ,error ){if len (*_bcg )< 1{return nil ,ErrStackUnderflow ;};_bdc :=(*_bcg )[len (*_bcg )-1];*_bcg =(*_bcg )[0:len (*_bcg )-1];return _bdc ,nil ;};func (_dba *PSProgram )String ()string {_ec :="\u007b\u0020";for _ ,_ag :=range *_dba {_ec +=_ag .String ();_ec +="\u0020";};_ec +="\u007d";return _ec ;};var ErrStackUnderflow =_d .New ("\u0073t\u0061c\u006b\u0020\u0075\u006e\u0064\u0065\u0072\u0066\u006c\u006f\u0077");
|
|
|
|
// PopNumberAsFloat64 pops and return the numeric value of the top of the stack as a float64.
|
|
// Real or integer only.
|
|
func (_cecd *PSStack )PopNumberAsFloat64 ()(float64 ,error ){_acgg ,_eeec :=_cecd .Pop ();if _eeec !=nil {return 0,_eeec ;};if _aggd ,_ddbe :=_acgg .(*PSReal );_ddbe {return _aggd .Val ,nil ;}else if _acec ,_bfeg :=_acgg .(*PSInteger );_bfeg {return float64 (_acec .Val ),nil ;}else {return 0,ErrTypeCheck ;};};func (_bf *PSReal )Duplicate ()PSObject {_g :=PSReal {};_g .Val =_bf .Val ;return &_g };func (_beeg *PSOperand )roll (_gde *PSStack )error {_ged ,_abg :=_gde .Pop ();if _abg !=nil {return _abg ;};_ecd ,_abg :=_gde .Pop ();if _abg !=nil {return _abg ;};_caec ,_fdcf :=_ged .(*PSInteger );if !_fdcf {return ErrTypeCheck ;};_ecggb ,_fdcf :=_ecd .(*PSInteger );if !_fdcf {return ErrTypeCheck ;};if _ecggb .Val < 0{return ErrRangeCheck ;};if _ecggb .Val ==0||_ecggb .Val ==1{return nil ;};if _ecggb .Val > len (*_gde ){return ErrStackUnderflow ;};for _dbgf :=0;_dbgf < _dfg (_caec .Val );_dbgf ++{var _edd []PSObject ;_edd =(*_gde )[len (*_gde )-(_ecggb .Val ):len (*_gde )];if _caec .Val > 0{_gaed :=_edd [len (_edd )-1];_edd =append ([]PSObject {_gaed },_edd [0:len (_edd )-1]...);}else {_gfd :=_edd [len (_edd )-_ecggb .Val ];_edd =append (_edd [1:],_gfd );};_fcf :=append ((*_gde )[0:len (*_gde )-_ecggb .Val ],_edd ...);_gde =&_fcf ;};return nil ;};
|
|
|
|
// Exec executes the operand `op` in the state specified by `stack`.
|
|
func (_cc *PSOperand )Exec (stack *PSStack )error {_bbc :=ErrUnsupportedOperand ;switch *_cc {case "\u0061\u0062\u0073":_bbc =_cc .abs (stack );case "\u0061\u0064\u0064":_bbc =_cc .add (stack );case "\u0061\u006e\u0064":_bbc =_cc .and (stack );case "\u0061\u0074\u0061\u006e":_bbc =_cc .atan (stack );case "\u0062\u0069\u0074\u0073\u0068\u0069\u0066\u0074":_bbc =_cc .bitshift (stack );case "\u0063e\u0069\u006c\u0069\u006e\u0067":_bbc =_cc .ceiling (stack );case "\u0063\u006f\u0070\u0079":_bbc =_cc .copy (stack );case "\u0063\u006f\u0073":_bbc =_cc .cos (stack );case "\u0063\u0076\u0069":_bbc =_cc .cvi (stack );case "\u0063\u0076\u0072":_bbc =_cc .cvr (stack );case "\u0064\u0069\u0076":_bbc =_cc .div (stack );case "\u0064\u0075\u0070":_bbc =_cc .dup (stack );case "\u0065\u0071":_bbc =_cc .eq (stack );case "\u0065\u0078\u0063\u0068":_bbc =_cc .exch (stack );case "\u0065\u0078\u0070":_bbc =_cc .exp (stack );case "\u0066\u006c\u006fo\u0072":_bbc =_cc .floor (stack );case "\u0067\u0065":_bbc =_cc .ge (stack );case "\u0067\u0074":_bbc =_cc .gt (stack );case "\u0069\u0064\u0069\u0076":_bbc =_cc .idiv (stack );case "\u0069\u0066":_bbc =_cc .ifCondition (stack );case "\u0069\u0066\u0065\u006c\u0073\u0065":_bbc =_cc .ifelse (stack );case "\u0069\u006e\u0064e\u0078":_bbc =_cc .index (stack );case "\u006c\u0065":_bbc =_cc .le (stack );case "\u006c\u006f\u0067":_bbc =_cc .log (stack );case "\u006c\u006e":_bbc =_cc .ln (stack );case "\u006c\u0074":_bbc =_cc .lt (stack );case "\u006d\u006f\u0064":_bbc =_cc .mod (stack );case "\u006d\u0075\u006c":_bbc =_cc .mul (stack );case "\u006e\u0065":_bbc =_cc .ne (stack );case "\u006e\u0065\u0067":_bbc =_cc .neg (stack );case "\u006e\u006f\u0074":_bbc =_cc .not (stack );case "\u006f\u0072":_bbc =_cc .or (stack );case "\u0070\u006f\u0070":_bbc =_cc .pop (stack );case "\u0072\u006f\u0075n\u0064":_bbc =_cc .round (stack );case "\u0072\u006f\u006c\u006c":_bbc =_cc .roll (stack );case "\u0073\u0069\u006e":_bbc =_cc .sin (stack );case "\u0073\u0071\u0072\u0074":_bbc =_cc .sqrt (stack );case "\u0073\u0075\u0062":_bbc =_cc .sub (stack );case "\u0074\u0072\u0075\u006e\u0063\u0061\u0074\u0065":_bbc =_cc .truncate (stack );case "\u0078\u006f\u0072":_bbc =_cc .xor (stack );};return _bbc ;};
|
|
|
|
// MakeInteger returns a new PSInteger object initialized with `val`.
|
|
func MakeInteger (val int )*PSInteger {_ccdg :=PSInteger {};_ccdg .Val =val ;return &_ccdg };func (_gfca *PSOperand )exp (_gee *PSStack )error {_afc ,_fba :=_gee .PopNumberAsFloat64 ();if _fba !=nil {return _fba ;};_fabf ,_fba :=_gee .PopNumberAsFloat64 ();if _fba !=nil {return _fba ;};if _bb .Abs (_afc )< 1&&_fabf < 0{return ErrUndefinedResult ;};_egbf :=_bb .Pow (_fabf ,_afc );_fba =_gee .Push (MakeReal (_egbf ));return _fba ;};func (_eecb *PSOperand )ln (_ebbe *PSStack )error {_dag ,_adce :=_ebbe .PopNumberAsFloat64 ();if _adce !=nil {return _adce ;};_ccga :=_bb .Log (_dag );_adce =_ebbe .Push (MakeReal (_ccga ));return _adce ;};func (_abga *PSParser )parseNumber ()(PSObject ,error ){_bege ,_bfge :=_cd .ParseNumber (_abga ._acfg );if _bfge !=nil {return nil ,_bfge ;};switch _ddaf :=_bege .(type ){case *_cd .PdfObjectFloat :return MakeReal (float64 (*_ddaf )),nil ;case *_cd .PdfObjectInteger :return MakeInteger (int (*_ddaf )),nil ;};return nil ,_e .Errorf ("\u0075n\u0068\u0061\u006e\u0064\u006c\u0065\u0064\u0020\u006e\u0075\u006db\u0065\u0072\u0020\u0074\u0079\u0070\u0065\u0020\u0025\u0054",_bege );};
|
|
|
|
// PSReal represents a real number.
|
|
type PSReal struct{Val float64 ;};
|
|
|
|
// PSProgram defines a Postscript program which is a series of PS objects (arguments, commands, programs etc).
|
|
type PSProgram []PSObject ;
|
|
|
|
// PSBoolean represents a boolean value.
|
|
type PSBoolean struct{Val bool ;};func (_eac *PSOperand )copy (_aed *PSStack )error {_eaa ,_cgf :=_aed .PopInteger ();if _cgf !=nil {return _cgf ;};if _eaa < 0{return ErrRangeCheck ;};if _eaa > len (*_aed ){return ErrRangeCheck ;};*_aed =append (*_aed ,(*_aed )[len (*_aed )-_eaa :]...);return nil ;};func _dfg (_ggb int )int {if _ggb < 0{return -_ggb ;};return _ggb ;};func (_bfce *PSOperand )mul (_gaf *PSStack )error {_bfbb ,_cdgf :=_gaf .Pop ();if _cdgf !=nil {return _cdgf ;};_cda ,_cdgf :=_gaf .Pop ();if _cdgf !=nil {return _cdgf ;};_ccc ,_afe :=_bfbb .(*PSReal );_gbd ,_bfcc :=_bfbb .(*PSInteger );if !_afe &&!_bfcc {return ErrTypeCheck ;};_ccd ,_bbbc :=_cda .(*PSReal );_ddd ,_gfg :=_cda .(*PSInteger );if !_bbbc &&!_gfg {return ErrTypeCheck ;};if _bfcc &&_gfg {_cge :=_gbd .Val *_ddd .Val ;_cce :=_gaf .Push (MakeInteger (_cge ));return _cce ;};var _dgd float64 =0;if _afe {_dgd =_ccc .Val ;}else {_dgd =float64 (_gbd .Val );};if _bbbc {_dgd *=_ccd .Val ;}else {_dgd *=float64 (_ddd .Val );};_cdgf =_gaf .Push (MakeReal (_dgd ));return _cdgf ;};
|
|
|
|
// NewPSStack returns an initialized PSStack.
|
|
func NewPSStack ()*PSStack {return &PSStack {}};
|
|
|
|
// PSObject represents a postscript object.
|
|
type PSObject interface{
|
|
|
|
// Duplicate makes a fresh copy of the PSObject.
|
|
Duplicate ()PSObject ;
|
|
|
|
// DebugString returns a descriptive representation of the PSObject with more information than String()
|
|
// for debugging purposes.
|
|
DebugString ()string ;
|
|
|
|
// String returns a string representation of the PSObject.
|
|
String ()string ;};func (_bfdb *PSOperand )ne (_daba *PSStack )error {_gcdf :=_bfdb .eq (_daba );if _gcdf !=nil {return _gcdf ;};_gcdf =_bfdb .not (_daba );return _gcdf ;};func (_aa *PSBoolean )Duplicate ()PSObject {_af :=PSBoolean {};_af .Val =_aa .Val ;return &_af };
|
|
|
|
// PopInteger specificially pops an integer from the top of the stack, returning the value as an int.
|
|
func (_dcgb *PSStack )PopInteger ()(int ,error ){_ddff ,_gea :=_dcgb .Pop ();if _gea !=nil {return 0,_gea ;};if _ede ,_addb :=_ddff .(*PSInteger );_addb {return _ede .Val ,nil ;};return 0,ErrTypeCheck ;};
|
|
|
|
// PSStack defines a stack of PSObjects. PSObjects can be pushed on or pull from the stack.
|
|
type PSStack []PSObject ;func (_ceca *PSOperand )exch (_cdbb *PSStack )error {_fabg ,_befc :=_cdbb .Pop ();if _befc !=nil {return _befc ;};_fdc ,_befc :=_cdbb .Pop ();if _befc !=nil {return _befc ;};_befc =_cdbb .Push (_fabg );if _befc !=nil {return _befc ;};_befc =_cdbb .Push (_fdc );return _befc ;};func (_cefg *PSOperand )round (_dbabg *PSStack )error {_gegg ,_gcaa :=_dbabg .Pop ();if _gcaa !=nil {return _gcaa ;};if _gaa ,_bbe :=_gegg .(*PSReal );_bbe {_gcaa =_dbabg .Push (MakeReal (_bb .Floor (_gaa .Val +0.5)));}else if _bdec ,_dfcd :=_gegg .(*PSInteger );_dfcd {_gcaa =_dbabg .Push (MakeInteger (_bdec .Val ));}else {return ErrTypeCheck ;};return _gcaa ;};func (_dgc *PSProgram )DebugString ()string {_bef :="\u007b\u0020";for _ ,_dge :=range *_dgc {_bef +=_dge .DebugString ();_bef +="\u0020";};_bef +="\u007d";return _bef ;};const _dg =0.000001;func (_gcg *PSOperand )dup (_eefa *PSStack )error {_acd ,_bfef :=_eefa .Pop ();if _bfef !=nil {return _bfef ;};_bfef =_eefa .Push (_acd );if _bfef !=nil {return _bfef ;};_bfef =_eefa .Push (_acd .Duplicate ());return _bfef ;};func (_bed *PSOperand )log (_dbec *PSStack )error {_eege ,_acef :=_dbec .PopNumberAsFloat64 ();if _acef !=nil {return _acef ;};_ebf :=_bb .Log10 (_eege );_acef =_dbec .Push (MakeReal (_ebf ));return _acef ;};func (_cef *PSOperand )eq (_cdb *PSStack )error {_efa ,_ecea :=_cdb .Pop ();if _ecea !=nil {return _ecea ;};_ebd ,_ecea :=_cdb .Pop ();if _ecea !=nil {return _ecea ;};_gfc ,_bdf :=_efa .(*PSBoolean );_gfcf ,_bfa :=_ebd .(*PSBoolean );if _bdf ||_bfa {var _cgfc error ;if _bdf &&_bfa {_cgfc =_cdb .Push (MakeBool (_gfc .Val ==_gfcf .Val ));}else {_cgfc =_cdb .Push (MakeBool (false ));};return _cgfc ;};var _ebbf float64 ;var _gdb float64 ;if _gddd ,_cded :=_efa .(*PSInteger );_cded {_ebbf =float64 (_gddd .Val );}else if _fab ,_fbc :=_efa .(*PSReal );_fbc {_ebbf =_fab .Val ;}else {return ErrTypeCheck ;};if _ffa ,_dea :=_ebd .(*PSInteger );_dea {_gdb =float64 (_ffa .Val );}else if _dbab ,_gegd :=_ebd .(*PSReal );_gegd {_gdb =_dbab .Val ;}else {return ErrTypeCheck ;};if _bb .Abs (_gdb -_ebbf )< _dg {_ecea =_cdb .Push (MakeBool (true ));}else {_ecea =_cdb .Push (MakeBool (false ));};return _ecea ;};
|
|
|
|
// PSInteger represents an integer.
|
|
type PSInteger struct{Val int ;};func (_ff *PSOperand )Duplicate ()PSObject {_gd :=*_ff ;return &_gd };func (_bde *PSOperand )floor (_dbac *PSStack )error {_decf ,_ccf :=_dbac .Pop ();if _ccf !=nil {return _ccf ;};if _fdb ,_cae :=_decf .(*PSReal );_cae {_ccf =_dbac .Push (MakeReal (_bb .Floor (_fdb .Val )));}else if _daeb ,_fgf :=_decf .(*PSInteger );_fgf {_ccf =_dbac .Push (MakeInteger (_daeb .Val ));}else {return ErrTypeCheck ;};return _ccf ;};func (_dgb *PSOperand )bitshift (_dee *PSStack )error {_bfc ,_dcd :=_dee .PopInteger ();if _dcd !=nil {return _dcd ;};_ae ,_dcd :=_dee .PopInteger ();if _dcd !=nil {return _dcd ;};var _gc int ;if _bfc >=0{_gc =_ae <<uint (_bfc );}else {_gc =_ae >>uint (-_bfc );};_dcd =_dee .Push (MakeInteger (_gc ));return _dcd ;};func (_fd *PSInteger )String ()string {return _e .Sprintf ("\u0025\u0064",_fd .Val )};func (_becb *PSOperand )gt (_ddg *PSStack )error {_egbb ,_ceg :=_ddg .PopNumberAsFloat64 ();if _ceg !=nil {return _ceg ;};_dfcc ,_ceg :=_ddg .PopNumberAsFloat64 ();if _ceg !=nil {return _ceg ;};if _bb .Abs (_dfcc -_egbb )< _dg {_dgg :=_ddg .Push (MakeBool (false ));return _dgg ;}else if _dfcc > _egbb {_faaf :=_ddg .Push (MakeBool (true ));return _faaf ;}else {_bade :=_ddg .Push (MakeBool (false ));return _bade ;};};
|
|
|
|
// NewPSProgram returns an empty, initialized PSProgram.
|
|
func NewPSProgram ()*PSProgram {return &PSProgram {}};func (_cf *PSInteger )Duplicate ()PSObject {_fbe :=PSInteger {};_fbe .Val =_cf .Val ;return &_fbe };func (_dbg *PSOperand )atan (_bad *PSStack )error {_dcf ,_ca :=_bad .PopNumberAsFloat64 ();if _ca !=nil {return _ca ;};_beb ,_ca :=_bad .PopNumberAsFloat64 ();if _ca !=nil {return _ca ;};if _dcf ==0{var _ed error ;if _beb < 0{_ed =_bad .Push (MakeReal (270));}else {_ed =_bad .Push (MakeReal (90));};return _ed ;};_aaa :=_beb /_dcf ;_fdg :=_bb .Atan (_aaa )*180/_bb .Pi ;_ca =_bad .Push (MakeReal (_fdg ));return _ca ;};func (_eee *PSOperand )String ()string {return _e .Sprintf ("\u0025\u0073",*_eee )};func (_dfd *PSOperand )sqrt (_cccf *PSStack )error {_gbgc ,_adfg :=_cccf .PopNumberAsFloat64 ();if _adfg !=nil {return _adfg ;};if _gbgc < 0{return ErrRangeCheck ;};_cccd :=_bb .Sqrt (_gbgc );_adfg =_cccf .Push (MakeReal (_cccd ));return _adfg ;};
|
|
|
|
// PSExecutor has its own execution stack and is used to executre a PS routine (program).
|
|
type PSExecutor struct{Stack *PSStack ;_de *PSProgram ;};var ErrRangeCheck =_d .New ("\u0072\u0061\u006e\u0067\u0065\u0020\u0063\u0068\u0065\u0063\u006b\u0020e\u0072\u0072\u006f\u0072");func (_aae *PSParser )parseBool ()(*PSBoolean ,error ){_cdae ,_bafe :=_aae ._acfg .Peek (4);if _bafe !=nil {return MakeBool (false ),_bafe ;};if (len (_cdae )>=4)&&(string (_cdae [:4])=="\u0074\u0072\u0075\u0065"){_aae ._acfg .Discard (4);return MakeBool (true ),nil ;};_cdae ,_bafe =_aae ._acfg .Peek (5);if _bafe !=nil {return MakeBool (false ),_bafe ;};if (len (_cdae )>=5)&&(string (_cdae [:5])=="\u0066\u0061\u006cs\u0065"){_aae ._acfg .Discard (5);return MakeBool (false ),nil ;};return MakeBool (false ),_d .New ("\u0075n\u0065\u0078\u0070\u0065c\u0074\u0065\u0064\u0020\u0062o\u006fl\u0065a\u006e\u0020\u0073\u0074\u0072\u0069\u006eg");};var ErrStackOverflow =_d .New ("\u0073\u0074\u0061\u0063\u006b\u0020\u006f\u0076\u0065r\u0066\u006c\u006f\u0077");func (_bdbe *PSOperand )or (_gge *PSStack )error {_cadg ,_bga :=_gge .Pop ();if _bga !=nil {return _bga ;};_cgef ,_bga :=_gge .Pop ();if _bga !=nil {return _bga ;};if _bggb ,_agc :=_cadg .(*PSBoolean );_agc {_caed ,_ecc :=_cgef .(*PSBoolean );if !_ecc {return ErrTypeCheck ;};_bga =_gge .Push (MakeBool (_bggb .Val ||_caed .Val ));return _bga ;};if _cedg ,_ab :=_cadg .(*PSInteger );_ab {_eeea ,_gdac :=_cgef .(*PSInteger );if !_gdac {return ErrTypeCheck ;};_bga =_gge .Push (MakeInteger (_cedg .Val |_eeea .Val ));return _bga ;};return ErrTypeCheck ;};func (_gcd *PSOperand )idiv (_cdgg *PSStack )error {_fed ,_gcdg :=_cdgg .Pop ();if _gcdg !=nil {return _gcdg ;};_cgff ,_gcdg :=_cdgg .Pop ();if _gcdg !=nil {return _gcdg ;};_add ,_fbg :=_fed .(*PSInteger );if !_fbg {return ErrTypeCheck ;};if _add .Val ==0{return ErrUndefinedResult ;};_bab ,_fbg :=_cgff .(*PSInteger );if !_fbg {return ErrTypeCheck ;};_ccbfb :=_bab .Val /_add .Val ;_gcdg =_cdgg .Push (MakeInteger (_ccbfb ));return _gcdg ;};
|
|
|
|
// Parse parses the postscript and store as a program that can be executed.
|
|
func (_dda *PSParser )Parse ()(*PSProgram ,error ){_dda .skipSpaces ();_daea ,_gbb :=_dda ._acfg .Peek (2);if _gbb !=nil {return nil ,_gbb ;};if _daea [0]!='{'{return nil ,_d .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");};_beeb ,_gbb :=_dda .parseFunction ();if _gbb !=nil &&_gbb !=_b .EOF {return nil ,_gbb ;};return _beeb ,_gbb ;};func (_dga *PSOperand )not (_gbde *PSStack )error {_aegb ,_gce :=_gbde .Pop ();if _gce !=nil {return _gce ;};if _bge ,_fgda :=_aegb .(*PSBoolean );_fgda {_gce =_gbde .Push (MakeBool (!_bge .Val ));return _gce ;}else if _gcf ,_cac :=_aegb .(*PSInteger );_cac {_gce =_gbde .Push (MakeInteger (^_gcf .Val ));return _gce ;}else {return ErrTypeCheck ;};};
|
|
|
|
// DebugString returns a descriptive string representation of the stack - intended for debugging.
|
|
func (_babd *PSStack )DebugString ()string {_efg :="\u005b\u0020";for _ ,_bfdd :=range *_babd {_efg +=_bfdd .DebugString ();_efg +="\u0020";};_efg +="\u005d";return _efg ;};func (_fga *PSOperand )DebugString ()string {return _e .Sprintf ("\u006fp\u003a\u0027\u0025\u0073\u0027",*_fga );};func (_bbb *PSBoolean )DebugString ()string {return _e .Sprintf ("\u0062o\u006f\u006c\u003a\u0025\u0076",_bbb .Val );};var ErrUndefinedResult =_d .New ("\u0075\u006e\u0064\u0065fi\u006e\u0065\u0064\u0020\u0072\u0065\u0073\u0075\u006c\u0074\u0020\u0065\u0072\u0072o\u0072");func (_gg *PSOperand )cvr (_eb *PSStack )error {_dfaf ,_dfc :=_eb .Pop ();if _dfc !=nil {return _dfc ;};if _aef ,_cfg :=_dfaf .(*PSReal );_cfg {_dfc =_eb .Push (MakeReal (_aef .Val ));}else if _ace ,_cdg :=_dfaf .(*PSInteger );_cdg {_dfc =_eb .Push (MakeReal (float64 (_ace .Val )));}else {return ErrTypeCheck ;};return _dfc ;};func (_gfe *PSOperand )mod (_ebe *PSStack )error {_eegc ,_bdb :=_ebe .Pop ();if _bdb !=nil {return _bdb ;};_gcag ,_bdb :=_ebe .Pop ();if _bdb !=nil {return _bdb ;};_bgf ,_dde :=_eegc .(*PSInteger );if !_dde {return ErrTypeCheck ;};if _bgf .Val ==0{return ErrUndefinedResult ;};_ecb ,_dde :=_gcag .(*PSInteger );if !_dde {return ErrTypeCheck ;};_deac :=_ecb .Val %_bgf .Val ;_bdb =_ebe .Push (MakeInteger (_deac ));return _bdb ;};func (_dbde *PSOperand )sin (_febg *PSStack )error {_egcf ,_fcbc :=_febg .PopNumberAsFloat64 ();if _fcbc !=nil {return _fcbc ;};_cdf :=_bb .Sin (_egcf *_bb .Pi /180.0);_fcbc =_febg .Push (MakeReal (_cdf ));return _fcbc ;};
|
|
|
|
// PSOperand represents a Postscript operand (text string).
|
|
type PSOperand string ;func (_febc *PSOperand )lt (_dcg *PSStack )error {_acb ,_fafe :=_dcg .PopNumberAsFloat64 ();if _fafe !=nil {return _fafe ;};_bcef ,_fafe :=_dcg .PopNumberAsFloat64 ();if _fafe !=nil {return _fafe ;};if _bb .Abs (_bcef -_acb )< _dg {_cba :=_dcg .Push (MakeBool (false ));return _cba ;}else if _bcef < _acb {_ced :=_dcg .Push (MakeBool (true ));return _ced ;}else {_cgd :=_dcg .Push (MakeBool (false ));return _cgd ;};};func (_dbfa *PSOperand )le (_eec *PSStack )error {_gef ,_ggff :=_eec .PopNumberAsFloat64 ();if _ggff !=nil {return _ggff ;};_effc ,_ggff :=_eec .PopNumberAsFloat64 ();if _ggff !=nil {return _ggff ;};if _bb .Abs (_effc -_gef )< _dg {_gdfd :=_eec .Push (MakeBool (true ));return _gdfd ;}else if _effc < _gef {_ddb :=_eec .Push (MakeBool (true ));return _ddb ;}else {_gdc :=_eec .Push (MakeBool (false ));return _gdc ;};};func (_bgcc *PSParser )parseFunction ()(*PSProgram ,error ){_bdeg ,_ :=_bgcc ._acfg .ReadByte ();if _bdeg !='{'{return nil ,_d .New ("\u0069\u006ev\u0061\u006c\u0069d\u0020\u0066\u0075\u006e\u0063\u0074\u0069\u006f\u006e");};_eaf :=NewPSProgram ();for {_bgcc .skipSpaces ();_bcb ,_bfde :=_bgcc ._acfg .Peek (2);if _bfde !=nil {if _bfde ==_b .EOF {break ;};return nil ,_bfde ;};_dfe .Log .Trace ("\u0050e\u0065k\u0020\u0073\u0074\u0072\u0069\u006e\u0067\u003a\u0020\u0025\u0073",string (_bcb ));if _bcb [0]=='}'{_dfe .Log .Trace ("\u0045\u004f\u0046 \u0066\u0075\u006e\u0063\u0074\u0069\u006f\u006e");_bgcc ._acfg .ReadByte ();break ;}else if _bcb [0]=='{'{_dfe .Log .Trace ("\u0046u\u006e\u0063\u0074\u0069\u006f\u006e!");_ffg ,_ddf :=_bgcc .parseFunction ();if _ddf !=nil {return nil ,_ddf ;};_eaf .Append (_ffg );}else if _cd .IsDecimalDigit (_bcb [0])||(_bcb [0]=='-'&&_cd .IsDecimalDigit (_bcb [1])){_dfe .Log .Trace ("\u002d>\u004e\u0075\u006d\u0062\u0065\u0072!");_eeed ,_cadgg :=_bgcc .parseNumber ();if _cadgg !=nil {return nil ,_cadgg ;};_eaf .Append (_eeed );}else {_dfe .Log .Trace ("\u002d>\u004fp\u0065\u0072\u0061\u006e\u0064 \u006f\u0072 \u0062\u006f\u006f\u006c\u003f");_bcb ,_ =_bgcc ._acfg .Peek (5);_dgaa :=string (_bcb );_dfe .Log .Trace ("\u0050\u0065\u0065k\u0020\u0073\u0074\u0072\u003a\u0020\u0025\u0073",_dgaa );if (len (_dgaa )> 4)&&(_dgaa [:5]=="\u0066\u0061\u006cs\u0065"){_aaf ,_fdgb :=_bgcc .parseBool ();if _fdgb !=nil {return nil ,_fdgb ;};_eaf .Append (_aaf );}else if (len (_dgaa )> 3)&&(_dgaa [:4]=="\u0074\u0072\u0075\u0065"){_ffgd ,_fda :=_bgcc .parseBool ();if _fda !=nil {return nil ,_fda ;};_eaf .Append (_ffgd );}else {_gaef ,_fedb :=_bgcc .parseOperand ();if _fedb !=nil {return nil ,_fedb ;};_eaf .Append (_gaef );};};};return _eaf ,nil ;};func (_fgdd *PSOperand )ceiling (_bee *PSStack )error {_dec ,_eg :=_bee .Pop ();if _eg !=nil {return _eg ;};if _bfd ,_bfb :=_dec .(*PSReal );_bfb {_eg =_bee .Push (MakeReal (_bb .Ceil (_bfd .Val )));}else if _cfc ,_fag :=_dec .(*PSInteger );_fag {_eg =_bee .Push (MakeInteger (_cfc .Val ));}else {_eg =ErrTypeCheck ;};return _eg ;};func (_ccge *PSOperand )cos (_eff *PSStack )error {_cca ,_gae :=_eff .PopNumberAsFloat64 ();if _gae !=nil {return _gae ;};_aeg :=_bb .Cos (_cca *_bb .Pi /180.0);_gae =_eff .Push (MakeReal (_aeg ));return _gae ;};
|
|
|
|
// Exec executes the program, typically leaving output values on the stack.
|
|
func (_cg *PSProgram )Exec (stack *PSStack )error {for _ ,_baa :=range *_cg {var _bac error ;switch _ge :=_baa .(type ){case *PSInteger :_ee :=_ge ;_bac =stack .Push (_ee );case *PSReal :_fgd :=_ge ;_bac =stack .Push (_fgd );case *PSBoolean :_cbg :=_ge ;_bac =stack .Push (_cbg );case *PSProgram :_geg :=_ge ;_bac =stack .Push (_geg );case *PSOperand :_ce :=_ge ;_bac =_ce .Exec (stack );default:return ErrTypeCheck ;};if _bac !=nil {return _bac ;};};return nil ;};func (_aebg *PSOperand )xor (_ddeg *PSStack )error {_dcb ,_afec :=_ddeg .Pop ();if _afec !=nil {return _afec ;};_fcbf ,_afec :=_ddeg .Pop ();if _afec !=nil {return _afec ;};if _effb ,_efd :=_dcb .(*PSBoolean );_efd {_ebfd ,_acf :=_fcbf .(*PSBoolean );if !_acf {return ErrTypeCheck ;};_afec =_ddeg .Push (MakeBool (_effb .Val !=_ebfd .Val ));return _afec ;};if _ddcb ,_cga :=_dcb .(*PSInteger );_cga {_bgfa ,_bbef :=_fcbf .(*PSInteger );if !_bbef {return ErrTypeCheck ;};_afec =_ddeg .Push (MakeInteger (_ddcb .Val ^_bgfa .Val ));return _afec ;};return ErrTypeCheck ;};func (_adbd *PSOperand )ge (_eab *PSStack )error {_bea ,_bgc :=_eab .PopNumberAsFloat64 ();if _bgc !=nil {return _bgc ;};_acgb ,_bgc :=_eab .PopNumberAsFloat64 ();if _bgc !=nil {return _bgc ;};if _bb .Abs (_acgb -_bea )< _dg {_gca :=_eab .Push (MakeBool (true ));return _gca ;}else if _acgb > _bea {_dbf :=_eab .Push (MakeBool (true ));return _dbf ;}else {_cbgf :=_eab .Push (MakeBool (false ));return _cbgf ;};};func (_dbe *PSOperand )ifCondition (_ceb *PSStack )error {_adde ,_dab :=_ceb .Pop ();if _dab !=nil {return _dab ;};_cfa ,_dab :=_ceb .Pop ();if _dab !=nil {return _dab ;};_fca ,_gda :=_adde .(*PSProgram );if !_gda {return ErrTypeCheck ;};_bdg ,_gda :=_cfa .(*PSBoolean );if !_gda {return ErrTypeCheck ;};if _bdg .Val {_ggf :=_fca .Exec (_ceb );return _ggf ;};return nil ;};func (_ddec *PSOperand )pop (_cea *PSStack )error {_ ,_fagb :=_cea .Pop ();if _fagb !=nil {return _fagb ;};return nil ;};func (_agg *PSOperand )div (_deed *PSStack )error {_ebb ,_efb :=_deed .Pop ();if _efb !=nil {return _efb ;};_badd ,_efb :=_deed .Pop ();if _efb !=nil {return _efb ;};_caa ,_ege :=_ebb .(*PSReal );_ecg ,_ebba :=_ebb .(*PSInteger );if !_ege &&!_ebba {return ErrTypeCheck ;};if _ege &&_caa .Val ==0{return ErrUndefinedResult ;};if _ebba &&_ecg .Val ==0{return ErrUndefinedResult ;};_cad ,_egb :=_badd .(*PSReal );_faf ,_cec :=_badd .(*PSInteger );if !_egb &&!_cec {return ErrTypeCheck ;};var _aeb float64 =0;if _egb {_aeb =_cad .Val ;}else {_aeb =float64 (_faf .Val );};if _ege {_aeb /=_caa .Val ;}else {_aeb /=float64 (_ecg .Val );};_efb =_deed .Push (MakeReal (_aeb ));return _efb ;};func (_bg *PSReal )String ()string {return _e .Sprintf ("\u0025\u002e\u0035\u0066",_bg .Val )};func (_cb *PSReal )DebugString ()string {return _e .Sprintf ("\u0072e\u0061\u006c\u003a\u0025\u002e\u0035f",_cb .Val );};
|
|
|
|
// NewPSExecutor returns an initialized PSExecutor for an input `program`.
|
|
func NewPSExecutor (program *PSProgram )*PSExecutor {_dgf :=&PSExecutor {};_dgf .Stack =NewPSStack ();_dgf ._de =program ;return _dgf ;};func (_cefb *PSOperand )ifelse (_adcf *PSStack )error {_feb ,_gbee :=_adcf .Pop ();if _gbee !=nil {return _gbee ;};_ecgg ,_gbee :=_adcf .Pop ();if _gbee !=nil {return _gbee ;};_fea ,_gbee :=_adcf .Pop ();if _gbee !=nil {return _gbee ;};_gbc ,_gdf :=_feb .(*PSProgram );if !_gdf {return ErrTypeCheck ;};_afg ,_gdf :=_ecgg .(*PSProgram );if !_gdf {return ErrTypeCheck ;};_eeg ,_gdf :=_fea .(*PSBoolean );if !_gdf {return ErrTypeCheck ;};if _eeg .Val {_bba :=_afg .Exec (_adcf );return _bba ;};_gbee =_gbc .Exec (_adcf );return _gbee ;};func (_adf *PSOperand )index (_gfa *PSStack )error {_beab ,_egc :=_gfa .Pop ();if _egc !=nil {return _egc ;};_gga ,_bgcb :=_beab .(*PSInteger );if !_bgcb {return ErrTypeCheck ;};if _gga .Val < 0{return ErrRangeCheck ;};if _gga .Val > len (*_gfa )-1{return ErrStackUnderflow ;};_bgd :=(*_gfa )[len (*_gfa )-1-_gga .Val ];_egc =_gfa .Push (_bgd .Duplicate ());return _egc ;};func (_affa *PSParser )skipSpaces ()(int ,error ){_gec :=0;for {_gedg ,_bfg :=_affa ._acfg .Peek (1);if _bfg !=nil {return 0,_bfg ;};if _cd .IsWhiteSpace (_gedg [0]){_affa ._acfg .ReadByte ();_gec ++;}else {break ;};};return _gec ,nil ;};func (_aab *PSOperand )cvi (_dbd *PSStack )error {_acg ,_bfdf :=_dbd .Pop ();if _bfdf !=nil {return _bfdf ;};if _baae ,_adg :=_acg .(*PSReal );_adg {_gba :=int (_baae .Val );_bfdf =_dbd .Push (MakeInteger (_gba ));}else if _agb ,_afb :=_acg .(*PSInteger );_afb {_dbad :=_agb .Val ;_bfdf =_dbd .Push (MakeInteger (_dbad ));}else {return ErrTypeCheck ;};return _bfdf ;};
|
|
|
|
// 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 _db []float64 ;for _ ,_dbc :=range objects {if _da ,_dc :=_dbc .(*PSInteger );_dc {_db =append (_db ,float64 (_da .Val ));}else if _cdd ,_bc :=_dbc .(*PSReal );_bc {_db =append (_db ,_cdd .Val );}else {return nil ,ErrTypeCheck ;};};return _db ,nil ;};func (_bce *PSInteger )DebugString ()string {return _e .Sprintf ("\u0069\u006e\u0074\u003a\u0025\u0064",_bce .Val );};
|
|
|
|
// Empty empties the stack.
|
|
func (_eed *PSStack )Empty (){*_eed =[]PSObject {}};func (_ceda *PSOperand )neg (_egg *PSStack )error {_gbg ,_fdbf :=_egg .Pop ();if _fdbf !=nil {return _fdbf ;};if _fdgg ,_cbc :=_gbg .(*PSReal );_cbc {_fdbf =_egg .Push (MakeReal (-_fdgg .Val ));return _fdbf ;}else if _bgcf ,_edb :=_gbg .(*PSInteger );_edb {_fdbf =_egg .Push (MakeInteger (-_bgcf .Val ));return _fdbf ;}else {return ErrTypeCheck ;};};
|
|
|
|
// Execute executes the program for an input parameters `objects` and returns a slice of output objects.
|
|
func (_ea *PSExecutor )Execute (objects []PSObject )([]PSObject ,error ){for _ ,_ac :=range objects {_be :=_ea .Stack .Push (_ac );if _be !=nil {return nil ,_be ;};};_fa :=_ea ._de .Exec (_ea .Stack );if _fa !=nil {_dfe .Log .Debug ("\u0045x\u0065c\u0020\u0066\u0061\u0069\u006c\u0065\u0064\u003a\u0020\u0025\u0076",_fa );return nil ,_fa ;};_fg :=[]PSObject (*_ea .Stack );_ea .Stack .Empty ();return _fg ,nil ;};func (_cddb *PSOperand )abs (_fgg *PSStack )error {_eef ,_fe :=_fgg .Pop ();if _fe !=nil {return _fe ;};if _baaf ,_ef :=_eef .(*PSReal );_ef {_fc :=_baaf .Val ;if _fc < 0{_fe =_fgg .Push (MakeReal (-_fc ));}else {_fe =_fgg .Push (MakeReal (_fc ));};}else if _dfeg ,_bd :=_eef .(*PSInteger );_bd {_dcc :=_dfeg .Val ;if _dcc < 0{_fe =_fgg .Push (MakeInteger (-_dcc ));}else {_fe =_fgg .Push (MakeInteger (_dcc ));};}else {return ErrTypeCheck ;};return _fe ;};func (_egd *PSParser )parseOperand ()(*PSOperand ,error ){var _cdc []byte ;for {_cee ,_afd :=_egd ._acfg .Peek (1);if _afd !=nil {if _afd ==_b .EOF {break ;};return nil ,_afd ;};if _cd .IsDelimiter (_cee [0]){break ;};if _cd .IsWhiteSpace (_cee [0]){break ;};_aec ,_ :=_egd ._acfg .ReadByte ();_cdc =append (_cdc ,_aec );};if len (_cdc )==0{return nil ,_d .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 (_cdc )),nil ;};func (_bcec *PSOperand )sub (_bfca *PSStack )error {_baf ,_fce :=_bfca .Pop ();if _fce !=nil {return _fce ;};_fafa ,_fce :=_bfca .Pop ();if _fce !=nil {return _fce ;};_afee ,_dce :=_baf .(*PSReal );_eddf ,_gab :=_baf .(*PSInteger );if !_dce &&!_gab {return ErrTypeCheck ;};_dcdd ,_cege :=_fafa .(*PSReal );_adge ,_edc :=_fafa .(*PSInteger );if !_cege &&!_edc {return ErrTypeCheck ;};if _gab &&_edc {_eabg :=_adge .Val -_eddf .Val ;_dbdc :=_bfca .Push (MakeInteger (_eabg ));return _dbdc ;};var _gedd float64 =0;if _cege {_gedd =_dcdd .Val ;}else {_gedd =float64 (_adge .Val );};if _dce {_gedd -=_afee .Val ;}else {_gedd -=float64 (_eddf .Val );};_fce =_bfca .Push (MakeReal (_gedd ));return _fce ;};
|
|
|
|
// String returns a string representation of the stack.
|
|
func (_cgaf *PSStack )String ()string {_beff :="\u005b\u0020";for _ ,_faag :=range *_cgaf {_beff +=_faag .String ();_beff +="\u0020";};_beff +="\u005d";return _beff ;};func (_cfe *PSProgram )Duplicate ()PSObject {_faa :=&PSProgram {};for _ ,_ga :=range *_cfe {_faa .Append (_ga .Duplicate ());};return _faa ;};
|
|
|
|
// PSParser is a basic Postscript parser.
|
|
type PSParser struct{_acfg *_df .Reader };func (_ad *PSBoolean )String ()string {return _e .Sprintf ("\u0025\u0076",_ad .Val )};
|
|
|
|
// MakeReal returns a new PSReal object initialized with `val`.
|
|
func MakeReal (val float64 )*PSReal {_gbdd :=PSReal {};_gbdd .Val =val ;return &_gbdd };func (_afa *PSOperand )truncate (_gebg *PSStack )error {_bgb ,_fac :=_gebg .Pop ();if _fac !=nil {return _fac ;};if _dgda ,_dbgb :=_bgb .(*PSReal );_dbgb {_bae :=int (_dgda .Val );_fac =_gebg .Push (MakeReal (float64 (_bae )));}else if _acde ,_bggg :=_bgb .(*PSInteger );_bggg {_fac =_gebg .Push (MakeInteger (_acde .Val ));}else {return ErrTypeCheck ;};return _fac ;};
|
|
|
|
// MakeBool returns a new PSBoolean object initialized with `val`.
|
|
func MakeBool (val bool )*PSBoolean {_ecbg :=PSBoolean {};_ecbg .Val =val ;return &_ecbg };
|
|
|
|
// Push pushes an object on top of the stack.
|
|
func (_aege *PSStack )Push (obj PSObject )error {if len (*_aege )> 100{return ErrStackOverflow ;};*_aege =append (*_aege ,obj );return nil ;};
|
|
|
|
// Append appends an object to the PSProgram.
|
|
func (_dd *PSProgram )Append (obj PSObject ){*_dd =append (*_dd ,obj )};func (_fcg *PSOperand )and (_aff *PSStack )error {_ece ,_cbfg :=_aff .Pop ();if _cbfg !=nil {return _cbfg ;};_bgg ,_cbfg :=_aff .Pop ();if _cbfg !=nil {return _cbfg ;};if _eae ,_bfe :=_ece .(*PSBoolean );_bfe {_gbe ,_adb :=_bgg .(*PSBoolean );if !_adb {return ErrTypeCheck ;};_cbfg =_aff .Push (MakeBool (_eae .Val &&_gbe .Val ));return _cbfg ;};if _gdd ,_ffe :=_ece .(*PSInteger );_ffe {_ddc ,_def :=_bgg .(*PSInteger );if !_def {return ErrTypeCheck ;};_cbfg =_aff .Push (MakeInteger (_gdd .Val &_ddc .Val ));return _cbfg ;};return ErrTypeCheck ;};
|
|
|
|
// MakeOperand returns a new PSOperand object based on string `val`.
|
|
func MakeOperand (val string )*PSOperand {_deacf :=PSOperand (val );return &_deacf };var ErrUnsupportedOperand =_d .New ("\u0075\u006e\u0073\u0075pp\u006f\u0072\u0074\u0065\u0064\u0020\u006f\u0070\u0065\u0072\u0061\u006e\u0064");func (_bec *PSOperand )add (_daf *PSStack )error {_adc ,_beg :=_daf .Pop ();if _beg !=nil {return _beg ;};_eca ,_beg :=_daf .Pop ();if _beg !=nil {return _beg ;};_gag ,_ccb :=_adc .(*PSReal );_ccg ,_geb :=_adc .(*PSInteger );if !_ccb &&!_geb {return ErrTypeCheck ;};_ccbf ,_fcb :=_eca .(*PSReal );_cgb ,_cde :=_eca .(*PSInteger );if !_fcb &&!_cde {return ErrTypeCheck ;};if _geb &&_cde {_fgc :=_ccg .Val +_cgb .Val ;_dfa :=_daf .Push (MakeInteger (_fgc ));return _dfa ;};var _cbf float64 =0;if _ccb {_cbf =_gag .Val ;}else {_cbf =float64 (_ccg .Val );};if _fcb {_cbf +=_ccbf .Val ;}else {_cbf +=float64 (_cgb .Val );};_beg =_daf .Push (MakeReal (_cbf ));return _beg ;}; |