【问题标题】:How to wrap or put ellipsis on text using postscript?如何使用 postscript 在文本上换行或省略号?
【发布时间】:2014-10-20 02:47:30
【问题描述】:

我有一个接受文本输入的后记代码。我想在文本达到特定长度时换行或在其上添加省略号,但我不知道该怎么做。

%%% A4 size
<< /PageSize [595 842] >> setpagedevice
clippath pathbbox /ury exch def /urx exch def /lly exch def /llx exch def

%%% Unit
/cm { 72 2.54 div mul } bind def

%%% Temporary
/Fix_long 4.2 cm def
/Fix_short 3.2 cm def
%%% Set Image Scale
/SetFixScale { 2 copy gt { Fix_long Fix_short }{ Fix_short Fix_long  }ifelse scale } bind def

%%% Set put coordinate
/SetXAdjust { 2 copy gt 
{ X_Step Fix_long sub 2 div floor }
{ Fix_long Fix_short sub 2 div} ifelse /XAdjust exch def 
} bind def
 /YAdjust 2 cm def
%%% Temporary
/Row 4 def
/Column 3 def
/X_Step urx llx sub Row div floor def
/Y_Step ury lly sub Column div floor  def
/Row_pos 0 def
/Column_pos 1 def
/SetPutPosition { 
llx X_Step Row_pos mul add 
ury Y_Step Column_pos mul sub translate
DrawFrame
DrawFileName
XAdjust YAdjust translate
Row 1 sub Row_pos eq { /Row_pos 0 def /Column_pos Column_pos 1 add def }{ /Row_pos Row_pos 1 add def } ifelse  
Column_pos Column gt { /Column_pos 1 def } if
} bind def

/DrawFrame { gsave .5 setlinewidth 0 0 X_Step Y_Step rectstroke grestore } bind def
/DrawFileName { 15 15 moveto 4 -1 roll show } bind def

在 /DrwaFileName 部分,我想包装文本/剪切它并添加一个省略号。我该怎么做?有它的功能吗?

【问题讨论】:

    标签: postscript word-wrap ellipsis


    【解决方案1】:

    没有用于此的内置函数,因此您必须进行一些字符串处理。根据您想要测量“长度”的方式,至少有两种方法。

    对于更简单的情况,我们将“长度”视为字符数。 postscript 运算符length 将返回字符串中的字符数。所以从你的功能开始,

    /DrawFileName { 15 15 moveto 4 -1 roll   show } bind def
    %                                      ^
    % we'll insert our code here, ---------|
    % where the string is on top of the stack,
    % replacing the call to show
    

    首先根据我们希望允许的最大尺寸检查现有长度。

    dup length 10 gt {
    }{
        show
    } ifelse
    

    如果长度不大于 10,else-子句只调用 show。接下来我们将填写 then 子句来修剪字符串。

    dup length 10 gt {
        0 10 getinterval
        show
    }{
        show
    } ifelse
    

    嗯,我不打算谈论优化,但我们现在可以考虑这一点。在添加 省略号 部分之前。两种情况都调用show,所以我们可以在ifelse结构之外调用一次。

    dup length 10 gt {
        0 10 getinterval
    }{
    } ifelse
    show
    

    当然,现在我们不需要ifelse,因为 else 子句是空的。

    dup length 10 gt {
        0 10 getinterval
    } if
    show
    

    这样更好。现在对于省略号,我们可以使用putinterval 运算符从一个字符串复制到另一个字符串。

    dup length 10 gt {
        0 10 getinterval
        dup 7 (...) putinterval
    } if
    show
    

    编辑:当然,既然 postscript 是一种图形语言,我们可能对字符串的页面上的排版长度感兴趣。为此,有stringwidth 运算符返回currentpoint 在调用show 后将移动的数量。因此,如果您只是用stringwidth rmoveto 替换对show 的调用,它将留下适当大小的间隙,但不会设置任何文本。所以,回到开头,替换对show 的调用,即。假设在我们的代码片段开头的堆栈顶部有一个字符串。

    dup stringwidth pop 50 gt {
    } if
    show
    

    对于西方字母,stringwidth 返回的 dy 值将始终为 0。由于上下文是一个文件名,这似乎是一个安全的假设。所以我们只需pop 它并将 dx 结果与 50 个用户空间点进行比较。

    现在,如果它太长了怎么办?在哪里进行切割?这是需要考虑的事情。做一个思考的脸。嗯。如果我们考虑在这里还添加了一个省略号,我们希望从字段宽度中减去它,然后将字符串截断到它的左侧。所以我的计划是逐个字符地遍历字符串并检查并显示每个字符,将省略号字符串留在堆栈中以获取最终的show。这是部分填写。

    dup stringwidth pop 50 gt {      % str
        50 (...) stringwidth pop sub % str Max      new maximum length
        exch                         % Max str
        { % Max c                               forall yields the integer value
            ( ) dup 0 4 3 roll put   % Max (c)    put it back in a string
            dup stringwidth pop      % Max (c) dx 
            2 index 2 copy lt        % Max (c) dx Max dx<Max?
            {                        % Max (c) dx Max      dx<Max
            }{                       % Max (c) dx Max      dx>=Max
            } ifelse
        } forall
        (...)
    } if
    show
    

    遍历每个字符,检查字符串宽度,与最大值进行比较。如果小于最大值,我们要继续显示字符串,并从最大值中减去宽度。 如果不是,我们想清理堆栈并退出循环。

    dup stringwidth pop 50 gt {      % str
        50 (...) stringwidth pop sub % str Max      new maximum length
        exch                         % Max str
        { % Max c                               forall yields the integer value
            ( ) dup 0 4 3 roll put   % Max (c)    put it back in a string
            dup stringwidth pop      % Max (c) dx 
            2 index 2 copy lt        % Max (c) dx Max dx<Max?
            {                        % Max (c) dx Max      dx<Max
                exch sub             % Max (c) Max-dx
                3 1 roll exch pop    % Max-dx (c)
                show                 % Max-dx
            }{                       % Max (c) dx Max      dx>=Max
                pop pop pop pop exit
            } ifelse
        } forall
        (...)   % place (...) on stack for show
    } if
    show
    

    我认为这应该可以完成工作。

    对于环绕文本,我们有点把自己画到一个角落里。剩余的字符串需要通过剩余的迭代来收集,然后重新组装成一个字符串,然后再重新做整个混乱。让我考虑一下。 ...

    或者它可以将当前点重新定位在循环的中间。使用 X 坐标和 Y 增量(或减量,实际上,因为我们可能正在向下移动页面)。类似的东西

    currentpoint exch pop % currentY
    X exch                % X currentY
    dY sub                % X currentY-dY
    moveto
    

    【讨论】:

    • 我删除了我的评论,因为这是我的错误。我忘记更改导致错误的值。
    • 好的,没问题。我想这可能就是发生的事情。
    猜你喜欢
    • 1970-01-01
    • 2012-03-20
    • 1970-01-01
    • 2013-09-15
    • 2020-12-10
    • 2016-06-30
    • 1970-01-01
    • 1970-01-01
    • 2013-11-01
    相关资源
    最近更新 更多