summaryrefslogtreecommitdiff
path: root/doc/context/sources/general/manuals/graphics/graphics.tex
blob: 7c1000c4e15629ed08990e5f69b4e0fb4485f0c1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
% language=uk

\usemodule[article-basic]
\usemodule[abbreviations-smallcaps]
\usemodule[setups-basics]
\usemodule[scite]

% \setupbodyfont
%   [dejavu]

\loadsetups[context-en]

\definecolor
  [mysetupscolora]
  [a=1,
   t=.25,
   r=.5,
   g=.5]

\definecolor
  [mysetupscolorb]
  [a=1,
   t=.25,
   g=.25,
   b=.25]

\definetextbackground
  [mysetups]
  [before=\blank,
   after=\blank,
   topoffset=10pt,
   leftoffset=10pt,
   location=paragraph,
   backgroundcolor=mysetupscolora,
   backgroundcolor=mysetupscolorb,
   frame=off]

\startsetups xml:setups:start
    \starttextbackground[mysetups]
\stopsetups

\startsetups xml:setups:stop
    \stoptextbackground
\stopsetups

\starttext

\startbuffer[image]
    \startluacode

        local min, max, random = math.min, math.max, math.random

        -- kind of self-explaining:

        local xsize      = 210
        local ysize      = 297
        local colordepth = 1
        local usemask    = true
        local colorspace = "rgb"

        -- initialization:

        local bitmap = graphics.bitmaps.new(xsize,ysize,colorspace,colordepth,usemask)

        -- filling the bitmap:

        local data    = bitmap.data
        local mask    = bitmap.mask
        local minmask = 100
        local maxmask = 200

        for i=1,ysize do
            local d = data[i]
            local m = mask[i]
            for j=1,xsize do
                d[j] = { i, max(i,j), j, min(i,j) }
                m[j] = random(minmask,maxmask)
            end
        end

        -- flushing the lot:

        graphics.bitmaps.tocontext(bitmap)

    \stopluacode
\stopbuffer

\definelayer
   [page]
   [width=\paperwidth,
    height=\paperheight]

\setlayer
   [page]
   {\scale
      [width=\paperwidth]
      {\ignorespaces
       \getbuffer[image]%
       \removeunwantedspaces}}

\setlayer
   [page]
   [preset=rightbottom,
    hoffset=10mm,
    voffset=45mm]
   {\scale
      [width=.6\paperwidth]
      {Graphics}}

% \setlayer
%    [page]
%    [preset=righttop,
%     hoffset=10mm,
%     voffset=20mm]
%    {\rotate{\scale
%       [width=.3\paperheight]
%       {\ConTeXt\ MkIV}}}

\setlayer
   [page]
   [preset=rightbottom,
    hoffset=10mm,
    voffset=20mm]
   {\scale
      [width=.6\paperwidth]
      {Hans Hagen}}

\startpagemakeup
    \flushlayer[page]
    \vfill
\stoppagemakeup

\startsubject[title=Introduction]

This manual is about integrating graphics your document. Doing this is not really
that complex so this manual will be short. Because graphic inclusion is related
to the backend some options will discussed. It's typical one of these manuals
that can grow over time.

\stopsubject

\startsubject[title=Basic formats]

In \TEX\ a graphic is not really known as graphic. The core task of the engine is
to turn input into typeset paragraphs. By the time that happens the input has
become a linked list of so called nodes: glyphs, kerns, glue, rules, boxes and a
couple of more items. But, when doing the job, \TEX\ is only interested in
dimensions.

In traditional \TEX\ an image inclusion happens via the extension primitive
\type {\special}, so you can think of something:

\starttyping
\vbox to 10cm {%
  \hbox to 4cm {%
    \special{image foo.png width 4cm height 10cm}%
    \hss
  }%
}
\stoptyping

When typesetting \TEX\ sees a box and uses its dimensions. It doesn't care what
is inside. The special itself is just a so called whatsit that is not
interpreted. When the page is eventually shipped out, the \DVI|-|to|-|whatever
driver interprets the special's content and embeds the image.

It will be clear that this will only work correctly when the image dimensions are
communicated. That can happen in real dimensions, but using scale factors is also
a variant. In the latter case one has to somehow determine the original dimensions
in order to calculate the scale factor. When you embed \EPS\ images, which is the
usual case in for instance \DVIPS, you can use \TEX\ macros to figure out the
(high res) boundingbox, but for bitmaps that often meant that some external
program had to do the analysis.

It sounds complex but in practice this was all quite doable. I say \quote {was}
because nowadays most \TEX\ users use an engine like \PDFTEX\ that doesn't need
an external program for generating the final output format. As a consequence it
has built-in support for analyzing and including images. There are additional
primitives that analyze the image and additional ones that inject them.

\starttyping
\pdfximage
  {foo.png}%
\pdfrefximage
  \pdflastximage
  width 4cm
  height 10cm
\relax
\stoptyping

A difference with traditional \TEX\ is that one doesn't need to wrap them into a
box. This is easier on the user (not that it matters much as often a macro
package hides this) but complicates the engine because suddenly it has to check a
so called extension whatsit node (representing the image) for dimensions.

Therefore in \LUATEX\ this model has been replaced by one where an image
internally is a special kind of rule, which in turn means that the code for
checking the whatsit could go away as rules are already taken into account. The
same is true for reuseable boxes (xforms in \PDF\ speak).

\starttyping
\useimageresource
  {foo.png}%
\saveimageresource
  \lastsavedimageresourceindex
  width 4cm
  height 10cm
\relax
\stoptyping

While \DVIPS\ supported \EPS\ images, \PDFTEX\ and \LUATEX\ natively support
\PNG, \JPG\ en \PDF\ inclusion. The easiest to support is \JPG\ because the PDF\
format supports so called \JPG\ compression in its full form. The engine only has
to pass the image blob plus a bit of extra information. Analyzing the file for
resolution, dimensions and colorspace is relative easy: consult some tables that
have this info and store it. No special libraries are needed for this kind of
graphics.

A bit more work is needed for \PDF\ images. A \PDF\ file is a collection of
(possibly compressed) objects. These objects can themselves refer to other
objects so basically we we have a tree of objects. This means that when we embed
a page from a \PDF\ file, we start with embedding the (content stream of the)
page object and then embed all the objects it refers to, which is a recursive
process because those objects themselves can refer to objects. In the process we
keep track of which objects are copied so that when we include another page we
don't copy duplicates.

A dedicated library is used for opening the file, and looking for objects that
tell us the dimensions and fetching objects that we need to embed. In \PDFTEX\
the poppler library is used, but in \LUATEX\ we have switched to pplib which is
specially made for this engine (by Pawel Jackowski) as a consequence of some
interchange that we had at the 2018 Bacho\TEX\ meeting. This change of library
gives us a greater independency and a much smaller code base. After all, we only
need access to \PDF\ files and its objects.

One can naively think that \PNG\ inclusion is as easy as \JPG\ inclusion because
\PDF\ supports \PNG\ compression. Well, this is indeed true, but it only supports
so called \PNG\ filter based compression. The image blob in a \PNG\ file
describes pixels in rows and columns where each row has a filter byte telling how
that row is to be interpreted. Pixel information can be derived from preceding
pixels, pixels above it, or a combination. Also some averaging can come into
play. This way repetitive information can (for instance) become for instance a
sequence of zeros because no change in pixel values took place. And such a
sequence can be compressed very well which is why the whole blob is compressed
with zlib.

In \PDF\ zlib compression can be applied to object streams so that bit is
covered. In addition a stream can be \PNG\ compressed, which means that it can
have filter bytes that need to be interpreted. But the \PNG\ can do more: the
image blob is actual split in chunks that need to be assembled. The image
information can be interlaced which means that the whole comes in 7~seperate
chunks thet get overlayed in increasing accuracy. Then there can be an image mask
part of the blob and that mask needs to be separated in \PDF\ (think of
transparency). Pixels can refer to a palette (grayscale or color) and pixels can
be codes in~1, 2, 4, 8 or 16~bits where color images can have 3~bytes. When
multiple pixels are packed into one byte they need to be expanded.

This all means that embedding \PNG\ file can demand a conversion and when you
have to do that each run, it has a performance hit. Normally, in a print driven
workflow, one will have straightforward \PNG\ images: 1 byte or 3 bytes which no
mask and not interlaced. These can be transferred directly to the \PDF\ file. In
all other cases it probably makes sense to convert the images beforehand (to
simple \PNG\ or just \PDF).

So, to summarize the above: a modern \TEX\ engine supports image inclusion
natively but for \PNG\ images you might need to convert them beforehand if
runtime matters and one has to run many times.

\stopsubject

\startsubject[title=Inclusion]

The command to include an image is:

\showsetup{externalfigure}

and its related settings are:

\showsetup{setupexternalfigure}

So you can say:

\starttyping[option=TEX]
\externalfigure[cow.pdf][width=4cm]
\stoptyping

The suffix is optional, which means that this will also work:

\starttyping[option=TEX]
\externalfigure[cow][width=4cm]
\stoptyping

\stopsubject

\startsubject[title=Defining]

{\em todo}

\showsetup{useexternalfigure}
\showsetup{defineexternalfigure}
\showsetup{registerexternalfigure}

\stopsubject

\startsubject[title=Analyzing]

{\em todo}

\showsetup{getfiguredimensions}

\showsetup{figurefilename}
\showsetup{figurefilepath}
\showsetup{figurefiletype}
\showsetup{figurefullname}
\showsetup{figureheight}
\showsetup{figurenaturalheight}
\showsetup{figurenaturalwidth}
\showsetup{figuresymbol}
\showsetup{figurewidth}

\showsetup{noffigurepages}

\stopsubject

\startsubject[title=Collections]

{\em todo}

\showsetup{externalfigurecollectionmaxheight}
\showsetup{externalfigurecollectionmaxwidth}
\showsetup{externalfigurecollectionminheight}
\showsetup{externalfigurecollectionminwidth}
\showsetup{externalfigurecollectionparameter}
\showsetup{startexternalfigurecollection}

\stopsubject

\startsubject[title=Conversion]

{\em todo}

\stopsubject

\startsubject[title=Figure databases]

{\em todo}

\showsetup{usefigurebase}

\stopsubject

\startsubject[title=Overlays]

{\em todo}

\showsetup{overlayfigure}
\showsetup{pagefigure}

\stopsubject

\startsubject[title=Scaling]

Images are normally scaled proportionally but if needed you can give an
explicit height and width. The \type {\scale} command shares this property
and can be used to scale in the same way as \type {\externalfigure}. I will
illustrate this with an example.

You can define your own bitmaps, like I did with the cover of this manual:

\typebuffer[image][option=LUA]

The actually inclusion of this image happened with:

\starttyping[option=TEX]
\scale
  [width=\paperwidth]
  {\getbuffer[image]}
\stoptyping

\stopsubject

% \startsubject[title=The backend]
%
% Traditionally \TEX\ sees an image as just a box with dimensions and in \LUATEX\
% it is actually a special kind of rule that carries information about what to
% inject in the final (\PDF) file. In regular \LUATEX\ the core formats \type
% {pdf}, \type {png}, \type {jpg} and \type {jp2} are dealt with by the backend but
% in \CONTEXT\ we can use \LUA\ instead. We might default to that method at some
% point but for now you need to enable that explicitly:
%
% \starttyping[option=TEX]
% \enabledirectrive[graphics.pdf.uselua]
% \enabledirectrive[graphics.jpg.uselua]
% \enabledirectrive[graphics.jp2.uselua]
% \enabledirectrive[graphics.png.uselua]
% \stoptyping
%
% All four can be enabled with:
%
% \starttyping[option=TEX]
% \enabledirectrive[graphics.uselua]
% \stoptyping
%
% Performance|-|wise only \PNG\ inclusion can be less efficient, but only when you
% use interlaced images or large images with masks. It makes no real sense in a
% professional workflow to use the (larger) interlaced images, and masks are seldom
% used at high resolutions, so in practice one will not really notice loss of
% performance.
%
% The advantage of this method is that we can provide more options, intercept bad
% images that make the backend abort and lessen the dependency on libraries.
%
% \stopsubject

\stoptext