9

Short version

I want to fill one or more rectangular areas on a page using a regular pattern. The area should span the page width and stretch vertically to fill remaining space. The pattern should be included in the generated PDF only once, using the PDF pattern facilities, as opposed to repeatedly emitting the same drawing instructions for each copy of the basic cell. Using specials that only work for pdflatexis acceptable.

Long version

My aim is to create sheets with alternating problem statements and answer areas. The answer areas (and only these) should be patterned using a grid of 5mm squares. (In Germany this is usually called “Karopapier”, and judging from Wikipedia, the US term probably would be “graph paper” or more specifically “quadrille paper”.)

Black lines for the squares are too small, and gray lines won't reproduce correctly in the final result from an offset printing press. So the squares have to be made up by tiny dots, 10 per edge.

I currently have code to do this, adapted from some other code I don't fully understand. It creates a single suqare by saving the result of a pictureenvironment to a box. That box is then repeated using \cleaders to fill one row, and repeated again to fill a block. It works, but the result has many drawbacks. Apparently the PDF will contain separate drawing instructions for each and every dot. This makes the files very large, causes my PDF viewer to become very slwo when scrolling through these documents, and will cost considerable time to print as well.

I know that it is possible to define patterns in PDF, and to fill shapes using these patterns. I want to leverage this from within the LaTeX document. I'd hope to write some macros so that I can simply invoke one macro like \graphpaper{\textwidth}{fill} or similar to create such a box. Everything else should be hidden behind the scenes.

Sketch of a possible solution

I have a rough idea of how I'd go about solving this, using features provided by the pdfTeX engine resp. the pdflatex command.

  1. Use \pdfsavepos to mark the start position
  2. Use \pdflastxpos and \pdflastypos to write that position to some helper file
  3. Create space for the box, using the dimensions provided
  4. Mark and write the end position like 1. and 2.
  5. Reserve an object number using \pdfobj reserveobjnum
  6. Write the object number to the output file as well
  7. Insert some \special as a placeholder for the box, referencing the above object
  8. Replace \output with something that calls the original \output up front
  9. Before doing the actual output, open the helper file for output
  10. After the output, read the file back in to obtain positions and object numbers
  11. For each region to be patterned, compute the required dimensions by subtracting marked positions and rounding down to a multiple of the square size.
  12. Create the corresponding object using \pdfobj useobjnum
  13. For the first page which needs it, create an object to represent the pattern itself

I'm not completely sure this would work as intended. In particular, I still have some doubts about whether I'd be able to include more than one region per page, and I'm also somewhat fuzzy whether the above single-pass approach would actually work.

Questions

My core question is this:

Do you know of any easier way to achieve what I'm trying to do?

I'll be happy about references to a package which already provides what I need. Lacking that, I'll also value references to code which does something similar, upon which I might build my stuff. If anyone has particular comments about the approach I outlined above, and whether it would work, that would be useful too.

5
  • Instead of inserting a pattern, cannot you just insert many straight lines? (This will be easier and do don't need to concern about: "The pattern should be included in the generated PDF only once.") If you want the lines to be made of dots, that can be doable as well (even simple picture and \multiput would do). This would reduce the problem to determining the empty space on a page.
    – yo'
    Oct 2, 2012 at 15:27
  • @tohecz, solid lines are unacceptable, I need them dotted. Furthermore, I want the dots at a regular phase, so that lines will meet exactly in their dots. picture has the problem that it will output all dot drawing commands to PDF, with the problems I described. Furthermore, stretching a picture to fill available space appears nontrivial, particularly in a single-pass setup. I guess that if I knew the size, I might be able to code suitable PDF drawing instructions to draw the lines using \special, but if I got that far, doing the pattern fill doesn't seem a big step either.
    – MvG
    Oct 2, 2012 at 15:39
  • I believe you have it wrong. Draw a dot = 1 instruction. Draw a texture = many instructions, because the texture is usually a complicated image. If you are seeking for efficiency, go for an algorithm that draws many dots. I regularly deal with images containing up to 1,000,000 dots (these take no more than a minute to load) and you don't need more than couple thousands of them.
    – yo'
    Oct 2, 2012 at 15:43
  • 1
    @tohecz, the algorithm has to be in the viewer, as PDF won't store program code, and even if it did, like PS does, the viewer would still have to print all these dots with no chance for optimization. Looking at the PDF ref section 4.6, I want to fill a rectangle with an uncolored tiling pattern without distortion. Then the viewer knows that he may achieve suitable output by blitting copies of complete squares, instead of drawing individual dots. At least so I hope.
    – MvG
    Oct 2, 2012 at 16:01
  • 1
    I think this bug (well not really) here tex.stackexchange.com/questions/65268/… can be a feature for you if you change the stars to dotted lines as a pattern.
    – percusse
    Oct 2, 2012 at 18:07

1 Answer 1

6

Here's the beginning of a solution. Needs much more work, but I don't have time now. Maybe someone will pick this up and improve it. For example, it could properly hook into the pdftex colour stack mechanism...

\documentclass{article}
\usepackage{xcolor}
%First  define the pattern:
\immediate\pdfobj stream attr{%
/Type /Pattern
/PatternType 1
/PaintType 1
/TilingType 1
/BBox [0 0 20 20]
/XStep 14.1732283 % 5mm step
/YStep 14.1732283 % 5mm step
/Resources << >>}{%
2.83465 0 0 2.83465 0 0 cm % use mm as units
1 J % rounded caps (to make dots)
0.25 w % line 0.25 units wide
[0 0.5] 0 d % dots every 0.5 units
1 1 m 1 6 l 6 6 l S % draw two edges of the unit square
}
%Now add pattern to the page resource dictionary:
\edef\myn{\the\pdflastobj}
\begingroup
   \edef\x{\endgroup
     \pdfpageresources{%
       \the\pdfpageresources /Pattern <</Mydots \myn\space0 R>>
     }%
   }%
\x

%Define a command to use the pattern:
\makeatletter
\newcommand{\mypattern}[1]{\pdfliteral{/Pattern cs /Mydots scn}#1\reset@color}
\makeatother

\begin{document}
Normal:\hrule height 10pt

%draw whatever you want. here i am using some text and a solid rule for demonstration
\mypattern{\Huge\textbf{\textsf{Patterned:}}\hrule height 40pt}

Normal:\hrule height 10pt

\end{document}
2
  • Using the \special only to select the pattern, but keeping the drawing to latex, sure makes things a lot easier. I haven't figured yet how to draw a filled box which stretches automatically using this method. I don't see how this approach could restrict the drawing to only drawing complete squares, rounding the dimensions down accordingly, but the added elegance makes up for that lack in features.
    – MvG
    Oct 2, 2012 at 19:03
  • \mypattern{\leaders\hrule\vfill} works well. Thanks a lot!
    – MvG
    Oct 4, 2012 at 8:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .