github.com/unidoc/unidoc@v2.2.0+incompatible/pdf/ps/exec.go (about)

     1  /*
     2   * This file is subject to the terms and conditions defined in
     3   * file 'LICENSE.md', which is part of this source code package.
     4   */
     5  
     6  package ps
     7  
     8  // A limited postscript parser for PDF function type 4.
     9  
    10  import (
    11  	"fmt"
    12  
    13  	"github.com/unidoc/unidoc/common"
    14  )
    15  
    16  // A PSExecutor has its own execution stack and is used to executre a PS routine (program).
    17  type PSExecutor struct {
    18  	Stack   *PSStack
    19  	program *PSProgram
    20  }
    21  
    22  func NewPSExecutor(program *PSProgram) *PSExecutor {
    23  	executor := &PSExecutor{}
    24  	executor.Stack = NewPSStack()
    25  	executor.program = program
    26  	return executor
    27  }
    28  
    29  func PSObjectArrayToFloat64Array(objects []PSObject) ([]float64, error) {
    30  	vals := []float64{}
    31  
    32  	for _, obj := range objects {
    33  		if number, is := obj.(*PSInteger); is {
    34  			vals = append(vals, float64(number.Val))
    35  		} else if number, is := obj.(*PSReal); is {
    36  			vals = append(vals, number.Val)
    37  		} else {
    38  			return nil, fmt.Errorf("Type error")
    39  		}
    40  	}
    41  
    42  	return vals, nil
    43  }
    44  
    45  func (this *PSExecutor) Execute(objects []PSObject) ([]PSObject, error) {
    46  	// Add the arguments on stack
    47  	// [obj1 obj2 ...]
    48  	for _, obj := range objects {
    49  		err := this.Stack.Push(obj)
    50  		if err != nil {
    51  			return nil, err
    52  		}
    53  	}
    54  
    55  	err := this.program.Exec(this.Stack)
    56  	if err != nil {
    57  		common.Log.Debug("Exec failed: %v", err)
    58  		return nil, err
    59  	}
    60  
    61  	result := []PSObject(*this.Stack)
    62  	this.Stack.Empty()
    63  
    64  	return result, nil
    65  }