By the time the lines are in your screen, there is no notion of "near" and "far" (except for the pixel depth values, but that's beside the point); the relative distance of your geometry is represented by its scale (if you use perspective projection).
The width is automatically constant if you do the widening after transforming the line geometry (points of the yet non-widened line) to clip space (that is, multiplying by world * view * projection). You don't have to calculate the inverse of anything in this manner; you simply just output the lines with the desired width.
The shader setup would be as follows (metacode):
-transform incoming line points by wvp
-take the incoming line segment
-calculate the rectangle representing said line segment in widened form
-generate two triangles for that rectangle, and output them for rasterization
-optionally, output some kind of line caps as well to prevent "breaking" of the line at its cusps
If you want to generate line caps, adjacency information for the line geometry is very useful. With it, you can read the adjacent points of the line segment in the GS as well, and you are better equipped to handle the joint geometry between the lines as you see fit. For simple round joints and caps, adjacency is not needed, though.
These steps can easily be implemented in pure software, too, in case you don't target a platform with GS capabilities.
Edited by Nik02, 08 October 2013 - 08:33 AM.