• PostScript语言教程(七、条件语句)


    POSTSCRIPT语言中有许多操作符用于制定程序内流的控制。我们在前一章使用了一个repeat运算。所有的控制操作符都使用了之前简要提到的对象类型,即函数,用于我们调用。

    7.1、函数

    函数(既过程)是一个数组,其内容由解析器执行。

    当解析器在程序中遇到一系列对象(值和名称)时,它执行与这些指令相应的操作,将对象放在堆栈上,查找和执行操作符和过程。

    但是如果一系列对象用括号括起来,则不会立即执行,而是放在堆栈上。

    86 23 add
    

    该行使解析器将数字86和23相加

    {86 23 add}
    

    当执行置放时,操作符添加一个程序块,然后放在堆栈上,函数通常跟字面名称,后边跟def运算符,def运算符将其与当前所保存的名称相连(这就是函数的定义)。  

    7.2、条件语句

    7.2.1、比较

    POSTSCRIPT提供了一套比较完整额比较运算符,这些比较栈上的前两个项目,可以是任何类型,返回一个布尔类型的对象在堆栈上。他们的等效数学符号为:

    eq =;  ne ≠;  gt >;  lt <;  ge ≥; le≤;

    7.2.2、if

    例:检查是否到达当前行的末尾

    /chkforendofline
    {  currentpoint pop     %获取x的位置
        612 gt              %是否大于612
        {0 -12 translate 0 0 moveto} if
    }def
    

    执行取出当前的x,比较看是否大于612(即本行的末尾),如果大于,则将原点移动到下一行的开头,当前点移动到原点的位置。

    编写一个程序,对字符串进行简单的格式打印:检查该字符串的长度是否适合当前行,如果不适合,则移动到新的行,然后进行打印。

    在这里定义了三个变量:左边距,右边距,当前文本的垂直位置,以及单独文本的垂直距离。

    首先复制要打印的字符串,然后使用stringwith计算其长度,然后取出当前的x的位置,将两个值相加,看是否大于右边沿,如果大于,跳转到下一行进行打印。

    % -------------- Variables ---------------
    /LM 72 def              %定义左边沿
    /RM 216 def             %定义右边沿
    /ypos 720 def           %当前文本的垂直位置
    /lineheight 14 def      %一行字符的高度
                            % of text
        
    % ------------- Procedures ---------------
    /newline                %跳转倒下一行
    {   ypos lineheight sub     %720 - 14 即为下一行的垂直位置
        /ypos exch def          %将当前文本的垂直高度刷新为新的值
        LM ypos moveto } def    %将当前点移动到新的起始点
    
    /prtstr                 %打印字符串
    {   dup stringwidth pop     %取出打印的字符串的宽度
        currentpoint pop        %取出当前画笔x的位置
        add RM gt               %相加看是否大于右边距
        {newline} if            %条件符合,跳转到下一行
        show } def              %进行打印
    
    %------------- Main Program --------------
    /Times-Italic findfont 13 scalefont setfont
    
    LM ypos moveto
    (If ) prtstr (you ) prtstr (tell ) prtstr
    (the ) prtstr (truth, ) prtstr (you ) prtstr
    (don’t ))prtstr (have ) prtstr (to ) prtstr 
    (remember ) prtstr (anything. ) prtstr
    (- Mark ) prtstr (Twain ) prtstr
    showpage
    

    7.2.3、ifelse

    这个运算符需要堆栈上有三个对象:一个布尔值和两个执行语句。

    如果为真,则执行第一个,否则执行第二个。

    bool {op1} {op2} ifelse
    

    例:使用ifelse生成了一组灰度交替逐渐减少高度的重叠梯形。

    % ------- Variables & Procedures ---------
    /scalefactor 1 def
    
    /counter 0 def
    
    /DecreaseScale
    {   scalefactor .2 sub
        /scalefactor exch def } def
    
    /IncreaseCounter
    {   /counter counter 1 add def } def
    
    /trappath                   
    {   0 0 moveto 90 0 rlineto
        -20 45 rlineto -50 0 rlineto
        closepath } def
    
    /doATrap
    {   gsave                   %保存当前环境
        1 scalefactor scale     %设置当前坐标轴的压缩比例
        trappath                %绘制梯形
        counter 2 mod           %取余(看是否能被2整除)
        0 eq {.5} {0} ifelse    
        setgray fill            %设置灰度,然后进行填充
        grestore } def          %恢复环境
    
    % ------------ Begin Program ----------
    250 350 translate
    
    5
    {   IncreaseCounter         %标记当前的次数
        doATrap                 %绘制梯形
        DecreaseScale           %标记当前的坐标轴y的压缩比例
        0 20 translate          %每次将原点向上移动20个单位
        } repeat
    showpage
    

    7.3、循环

    在POSTSCRIPT中有三个操作符用来建立和控制循环程序。我们已经使用过repeat操作。

    7.3.1、for

    这个运算符实现了计数循环。该操作符需要四个对象:

    起始值、地增量、最终值、重复的过程。

    for操作在每次执行过程之前将计数器的当前值放在堆栈上。

    例:将字幕k在页面上每12个单元打印一次,

    /Times-Italic findfont 10 scalefont setfont
    
    100 100 translate
    
    0 12 600 {0 moveto (k) show } for
    
    showpage 

    数字的变化不一定是整数,例如打印一个zip字符出现阴影效果

    /Times-Italic findfont 30 scalefont setfont
    
    /printZip
    { 0 0 moveto (Zip) show} def
    320 400 translate
    
    .95 -.05 0
    {   setgray 
        printZip 
        -1 .5 translate } for
    
    1 setgray printZip
    
    showpage
    

    7.3.2、loop,exit

    许多程序需要重复一个不确定的数目,一段时间或者永远,或者满足某种条件,这时候就要用到重复。。。直到。。。这种。

    POSTSCRIPT提供了一对运算符:loop,exit。

    loop操作符重复执行其过程,直到遇到退出条件。退出导致程序离开包含该操作符的最内层循环。退出操作符还会终止for,repeat,forall操作符启动的循环。

    例:此程序无限打印howdy。

    {(Howdy ) show} loop
    

    例:为了了解loop-exit如何一起工作,以下程序在当前页面绘制了几个圆  

    /pagewidth 8.5 72 mul def
    
    /doCircle
    {  xpos ypos radius 0 360 arc stroke} def
    
    /increase-x
    {  xpos radius add
        /xpos exch def } def
    
    /lineofcircles %stack: radius y
    {  /ypos exch def 
        /radius exch def 
        /xpos 0 def 
        {   xpos pagewidth le 
            {doCircle increase-x}
            {exit} ifelse
        }loop 
    } def
    
    % --------------- Begin Program -----------
    10 400 lineofcircles
    30 400 lineofcircles
    90 400 lineofcircles
    showpage
    

      

      

      

      

     

     

  • 相关阅读:
    Effective.Java第67-77条(异常相关)
    淘宝店的图片哪里来的
    SEO高手在扯蛋?
    多少人,没能熬过那最初的三厘米!
    网站要提高权重要总结三点
    真正的干货是什么?
    google打不开怎么办?谷歌打不开的解决方法
    StatCounter
    教你如何抢注一个快过期的域名
    正确识别希捷Backup Plus新睿品1TB正品,杜绝奸商猖獗
  • 原文地址:https://www.cnblogs.com/Ansing/p/10019037.html
Copyright © 2020-2023  润新知