Both Herbert and Alexander have offered solutions for dvips. Here, I'm taking inspiration from those answers plus the more convenient approach available in pdfTeX, plus a modified version of the pgf method for XeTeX, and combining into a single approach. First, note that I'm assuming e-TeX and also using a somewhat 'LaTeX3-like' programming approach. I've also shared as much code as possible.
I'll use a single example but add comments along the way. First, as there are packages for the driver detections I'll load those.
\documentclass{article}
\usepackage{ifpdf,ifxetex}
\makeatletter
The main internal macro takes five arguments: the box to modify, then four dimension expressions to be clipped off the left, bottom, right and top respectively. You could also set up a similar approach to take a final size. The idea here is that the baseline is respected if possible, so there is a bit of care needed with the vertical placement so that the content only moves down while there is some depth available.
\protected\long\def\box@clip#1#2#3#4#5%
{%
\ht#1\dimexpr\ht#1 - \dimexpr#5\relax\relax
\ifdim\dp#1>\dimexpr#3\relax
\dp#1\dimexpr\dp#1 - \dimexpr#3\relax\relax
\else
\setbox#1=\hbox
{\lower\dimexpr\dimexpr#3\relax - \dp#1\relax\box#1}%
\dp#1\z@
\fi
\wd#1\dimexpr\wd#1-\dimexpr#4\relax\relax
\setbox#1=\hbox
{%
\hskip-\dimexpr#2\relax
\box#1%
}%
\ifxetex
\expandafter\box@clip@xdvipdfmx
\else
\ifpdf
\expandafter\expandafter\expandafter\box@clip@pdfmode
\else
\expandafter\expandafter\expandafter\box@clip@dvips
\fi
\fi
#1%
}
For each driver supported, there is an auxiliary. First, for dvips this is Herbert's method slightly altered (pgf makes things very complex):
\protected\long\def\box@clip@dvips#1%
{%
\setbox#1=\hbox
{%
\special
{%
ps:
/mtrxc matrix currentmatrix def
currentpoint gsave
translate
Resolution 72 div VResolution 72 div scale
0 -\to@bp{\dp#1} neg \to@bp{\wd#1} \to@bp{\ht#1 + \dp#1} neg
rectclip
mtrxc setmatrix
}%
\box#1%
\special{ps: grestore }%
}%
}
As I said, pdfTeX makes life very easy :-)
\protected\long\def\box@clip@pdfmode#1%
{%
\pdfxform#1%
\setbox#1=\hbox{\pdfrefxform\pdflastxform}%
}
XeTeX is possibly the most complex one to tackle. The pgf approach is used, but here I've removed a lot of unnecessary transformations. After reading the dvipdfmx manual, it becomes clear that the best approach is as follows
\protected\long\def\box@clip@xdvipdfmx#1%
{%
\setbox#1=\hbox
{%
The first special saves the current point and starts a new 'graphics level'. Using the bcontent operation saves the current location automatically.
\special{pdf:bcontent }%
Draw a rectangle the size of the modified box: in pgf this is done using the lower-level m, l and h operations, but there is no gain in working that way. This will be located at 'current point' TeX-wise.
\special
{%
pdf:literal direct
0 -\to@bp{\dp#1} \to@bp{\wd#1} \to@bp{\ht#1 + \dp#1} re
}%
The W operation specifies a clip, and n finalises the path without any output (it's a 'no-op').
\special{pdf:literal direct W }%
\special{pdf:literal direct n }%
Insert the box and tidy up.
\box#1%
\special{pdf:econtent }%
}%
}
A simple conversion taken from Is there a command to convert cm to bp?
\long\def\to@bp#1{\strip@pt\dimexpr0.99626\dimexpr#1\relax\relax}
Wrap everything up in a user macro and finish the code block
\protected\long\def\boxclip#1#2#3#4#5{\box@clip#1{#2}{#3}{#4}{#5}}
\makeatother
\newbox\testbox
Now for some testing.
\begin{document}
\setbox\testbox=\hbox{Some test text with (g)}
\boxclip{\testbox}{10 pt}{2pt}{5pt}{2 pt}
\noindent\box\testbox{}
\end{document}
(I'll be adding this to LaTeX3 now I know how it works!) If you want to see the effect of various parts of the XeTeX code, comment out the W line to turn off the clipping. You can also replace the n operations by s so that you get a box where the clipping path is.
In earlier versions of the answer, for XeTeX I used the content q operation to save the current location, but this requires a series of manipulations to get the clip path and the box insert to line up. Using the bcontent ... econtent pair is much clearer.
While using the XForm implementation for pdfTeX is convenient, in a case where code is to be shared between branches an alternative approach is possible. (The above could be viewed as an abuse of the XForm object system in any case).
\protected\long\def\box@clip@pdfmode#1%
{%
\setbox#1=\hbox
{%
\pdfsave
\pdfliteral direct
{%
0 -\to@bp{\dp#1} \to@bp{\wd#1} \to@bp{\ht#1 + \dp#1} re W n
}%
\hbox to 0pt{\copy#1\hss}%
\pdfrestore
\hskip \wd#1
}%
}
The zero width box here is used to keep placement correct in the \pdfsave/\pdfrestore pair (which perform the same task as the bcontent/econtent pair for XeTeX but which should be places in the same output position.)
pdftex(which seems to work with\hboxes anyway), so I would be happy to hear about Postscript solutions. The\special{PSfile="#1" .. clip}command I found in thedvips.deffile doesn't help me much in this case. – Martin Scharrer Jul 10 '11 at 23:48dvipdfm, doesn't it? (I'm totally XeTeX ignorant :-( ) – Martin Scharrer Jul 11 '11 at 11:31\clipwith PGF works fine with XeLaTeX. I try to use the same lower level as PGF for as much output driver as possible. The rest will fall back to PGF. – Martin Scharrer Jul 11 '11 at 11:37graphicx. – Martin Scharrer Sep 04 '11 at 08:40\specialPostScript calls anyway, shouldn't it? – Martin Scharrer Nov 10 '11 at 11:50