summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/reflectgraphics/reflectgraphics.dtx
blob: 8bae768b3cb313891d8633f8a0d46b98a12072de (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
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
% \iffalse meta-comment
%
% Copyright (C) 2015 by Oliver Reiche <oliver.reiche@gmail.com>
% ---------------------------------------------------------------------------
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
% of this license or (at your option) any later version.
% The latest version of this license is in
%   http://www.latex-project.org/lppl.txt
% and version 1.3 or later is part of all distributions of LaTeX
% version 2005/12/01 or later.
%
% This work has the LPPL maintenance status `maintained'.
%
% The Current Maintainer of this work is Oliver Reiche.
%
% This work consists of the files reflectgraphics.dtx and reflectgraphics.ins
% and the derived filebase reflectgraphics.sty.
%
% \fi
%
% \iffalse
%<*driver>
\ProvidesFile{reflectgraphics.dtx}
%</driver>
%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<package>\ProvidesPackage{reflectgraphics}
%<*package>
    [2015/07/07 v0.2c Fancy reflections for LaTeX graphics]
%</package>
%
%<*driver>
\IfFileExists{example.jpg}{%
  \documentclass{ltxdoc}
}{%
  \documentclass[draft]{ltxdoc}
  \overfullrule=0pt
}%
\usepackage{xdoc2}
\usepackage{reflectgraphics}[2015/07/07]
\usepackage{microtype}
\usepackage[defaultlines=2,all]{nowidow}
\usepackage{titlesec}
\usepackage{needspace}

\titleformat{\section}{%
  \needspace{0.1\textheight}\Large\bfseries}{\thesection}{1em}{}
\titleformat{\subsection}{%
  \needspace{0.1\textheight}\large\bfseries}{\thesubsection}{1em}{}

\DeclareRobustCommand\package[1]{\textsf{#1}}
\DeclareRobustCommand\option[1]{\texttt{#1}}
\newenvironment{key}[2]{%
  \noindent%
  \leavevmode%
  \GenericDescribePrint{\MacroFont#2 \normalfont key}%
  \ignorespaces%
}{}%

\EnableCrossrefs
\RecordChanges
\begin{document}
  \DocInput{reflectgraphics.dtx}
  \PrintChanges
\end{document}
%</driver>
% \fi
%
% \CheckSum{309}
%
% \CharacterTable
%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%   Digits        \0\1\2\3\4\5\6\7\8\9
%   Exclamation   \!     Double quote  \"     Hash (number) \#
%   Dollar        \$     Percent       \%     Ampersand     \&
%   Acute accent  \'     Left paren    \(     Right paren   \)
%   Asterisk      \*     Plus          \+     Comma         \,
%   Minus         \-     Point         \.     Solidus       \/
%   Colon         \:     Semicolon     \;     Less than     \<
%   Equals        \=     Greater than  \>     Question mark \?
%   Commercial at \@     Left bracket  \[     Backslash     \\
%   Right bracket \]     Circumflex    \^     Underscore    \_
%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%   Right brace   \}     Tilde         \~}
%
%
% \changes{v0.1}{2013/10/28}{Initial version}
% \changes{v0.2}{2013/10/31}{Support for options 'scale' and 'angle'}
% \changes{v0.2b}{2013/11/25}{Fixed 'angle' for values <0 and >90}
% \changes{v0.2c}{2015/07/07}{Replaced non-free Lenna image}
%
% \DoNotIndex{\newcommand,\newenvironment}
%
% \providecommand*{\url}{\texttt}
% \GetFileInfo{reflectgraphics.dtx}
% \title{The \textsf{reflectgraphics} package}
% \author{Oliver Reiche \\ \url{oliver.reiche@gmail.com}}
% \date{\fileversion~from \filedate}
%
% \maketitle
%
% \begin{abstract}
%   This small package provides a new macro, which adds fancy reflections at
%   the bottom of graphics. To keep things simple, this new macro can be used
%   in a similar way to the |\includegraphics| macro of the \package{graphicx}
%   package.
% \end{abstract}
%
% \section{Introduction}
% \label{sec:introduction}
% Having a fading reflection or mirroring effect at the bottom of graphics can
% dramatically increase the fancyness of documents and in particular of
% presentations. Such an effect can be achieved by creating the reflection
% beforehand with an image editing software or by using the \package{tikz}
% package. Using Ti\textit{k}Z can be very tricky and many users might not be
% familiar with describing graphics by writing code. In particular when
% applying image manipulation operations (like scaling, rotating, trimming) on
% graphics, handling Ti\textit{k}Z code and positioning nodes correctly can be
% challenging.
%
% To remove this obstacle for inexperienced users and allow them to easily
% include graphics with fancy reflections, this package offers a simple
% alternative. By just specifying a graphics file, the macros provided by this
% package will render it and its reflection automatically.
%
% \section{Usage}
% \label{sec:usage}
% No big surprise, the package is loaded using:
% \begin{quote}
%   |\usepackage|\oarg{options}|{reflectgraphics}|
% \end{quote}
% The options specified as \meta{options} are globally set for the whole
% document and can be obliterated by locally defined options. A description of
% valid options can be found in subsection~\ref{sec:options}.
%
% \subsection{Macros}
% \label{sec:macros}
% The only new macro provided by this package is:
% \begin{quote}
%   \DescribeMacro{\reflectgraphics}|\reflectgraphics|\oarg{options}\marg{path}
% \end{quote}
% It can be used to render graphics together with their reflections at the
% bottom, which are fading from a particular starting opacity to fully
% transparent. The dimensions of a graphic and the properties of its reflection
% can be defined by \meta{options} (see subsection~\ref{sec:options}).
%
% The mandatory argument \meta{path} must contain a valid path to a graphics
% file of a supported file type. This package internally uses
% |\includegraphics|. Therefore, basically every graphics type that is
% supported by |\includegraphics| is also supported by this package. The file
% extension may be omitted in \meta{path}. To see some examples have a look at
% subsection~\ref{sec:examples}.
%
% \subsection{Options}
% \label{sec:options}
% Options can be specified globally with the |\usepackage| statement or locally
% for each |\reflectgraphics| statement. Local options override values of
% global options. There are two types of options: the ones that affect graphics
% and the ones that affect only the rendering of reflections.
%
% \paragraph{graphics} The following options describe the properties of
% graphics.
%
% To set the dimensions of the graphic to render, the options
% \describeoption{width}\option{width}=\meta{dim} and
% \describeoption{height}\option{height}=\meta{dim} can be specified. If only
% one of these options is specified, the original aspect ratio will be left
% untouched. Values passed to these options must be typical \TeX{} dimensions
% with units like \texttt{cm}, \texttt{em}, \texttt{pt}, and so on.
%
% Instead of a manually defining graphics dimensions, the option
% \describeoption{scale}\option{scale}=\meta{float} can be set as well. Hereby
% the original aspect ratio and size will be chosen scaled by the provided
% floating point value. Valid values are all values that are greater than $0$.
% If either \option{width} or \option{height} is specified, the \option{scale}
% option will be ignored.
%
% The graphics and corresponding reflections can be rotated by specifying the
% option \describeoption{angle}\option{angle}=\meta{float}. This floating point
% value describes the rotation angle in degrees. Valid angle values can be
% positive as well as negative.
%
% Similar to |\includegraphics| trimming and clipping can be applied to render
% only subregions of graphics. This can be done by defining the option
% \describeoption{trim}\option{trim}=\meta{dim}\ \meta{dim}\ \meta{dim}\
% \meta{dim}. The option takes four dimension arguments that define the trimming
% in the following order: \emph{left bottom right top}. If the dimension unit
% is omitted than \texttt{bp} is used by default, which is similar to
% |\includegraphics|. Unlike |\includegraphics| the \option{clip} option does
% not have to be specified.
%
% \paragraph{reflections} The following options describe the properties of
% graphics reflections.
%
% The distance between the actual graphic and its reflection can be defined by
% setting the option \describeoption{distance}\option{distance}=\meta{dim}. If
% it is not set, a default value of $3.0$\,\texttt{pt} will be used. The
% specified value must be a \TeX{} dimension.
%
% To set the size of the graphics reflection, specify the option
% \describeoption{length}\option{length}=\meta{float}. This option defines a
% percentage value, which represents the length (i.\,e.\ the height) of the
% reflection with respect to the height of the corresponding graphic. Its value
% is a floating point number and must lie within the interval $[0,1]$. The
% default value is set to $0.5$, which results in a reflection height that is
% equal to $50$\,\% of the graphics height.
%
% Changing the starting opacity for the fading of the reflection influences the
% impression how \emph{strong} the reflection is. The opacity can be modified
% by setting the \describeoption{opacity}\option{opacity}=\meta{float} option.
% Its value is a floating point number within the interval $[0,1]$. The default
% value is $0.5$, which equates to $50$\,\% opacity.
%
% \subsection{Examples}
% \label{sec:examples}
% The simplest way to use |\reflectgraphics| is to omit all optional arguments
% and let the underlaying |\includegraphics| macro choose the dimensions of the
% graphic:\\
% \begin{minipage}[t]{\textwidth}
%   \begin{verbatim}
% \reflectgraphics{example.jpg}
%   \end{verbatim}
% \end{minipage}
%
% To change the graphics size in a way whereat the aspect ratio should be kept
% as it is, define either \option{width}, \option{height} or use the
% \option{scale} option:\\
% \begin{minipage}[t]{\textwidth}
%   \begin{verbatim}
% \reflectgraphics[width=4cm]{example.jpg}
% \reflectgraphics[height=4cm]{example.jpg}
% \reflectgraphics[scale=0.25]{example.jpg}
%   \end{verbatim}
%   \begin{center}
%     \reflectgraphics[width=4cm, height=4cm]{example.jpg}
%   \end{center}
% \end{minipage}\bigskip
%
% If a specific aspect ratio should be forced, both dimensions have to be
% specified explicitly:\\
% \begin{minipage}[t]{\textwidth}
%   \begin{verbatim}
% \reflectgraphics[width=4cm, height=2cm]{example.jpg}
%   \end{verbatim}
%   \begin{center}
%     \reflectgraphics[width=4cm, height=2cm]{example.jpg}
%   \end{center}
% \end{minipage}\bigskip
%
% Rotating graphics can be enabled by specifying the \option{angle} option.
% Note that rotation will increase the rectangular space (bounding box) that is
% taken by the graphic and its reflection. In particular the overall height can
% expand drastically, because the increased height of both the graphic and the
% reflection add up.\\
% \begin{minipage}[t]{\textwidth}
%   \begin{verbatim}
% \reflectgraphics[width=1.5cm, angle=45]{example.jpg}
%   \end{verbatim}
%   \begin{center}
%     \reflectgraphics[width=1.5cm, height=1.5cm, angle=15]{example.jpg}
%     \reflectgraphics[width=1.5cm, height=1.5cm, angle=30]{example.jpg}
%     \reflectgraphics[width=1.5cm, height=1.5cm, angle=45]{example.jpg}
%     \reflectgraphics[width=1.5cm, height=1.5cm, angle=60]{example.jpg}
%     \reflectgraphics[width=1.5cm, height=1.5cm, angle=75]{example.jpg}
%   \end{center}
% \end{minipage}\bigskip
%
% To trim and clip graphics together with the corresponding reflection (e.\,g.\
% to highlight the olives only), one can straightforward proceed the same way as
% using |\includegraphics|, except that the \option{clip} option can be
% omitted:\\
% \begin{minipage}[t]{\textwidth}
%   \begin{verbatim}
% \reflectgraphics[trim=115 60 80 100]{example.jpg}
%   \end{verbatim}
%   \begin{center}
%     \reflectgraphics[width=1.55cm, height=2cm, trim=115 60 80 100]{example.jpg}
%   \end{center}
% \end{minipage}\bigskip
%
% In order to get a stronger and more crisp reflection, the options
% \option{opacity} and \option{length} can be set. For instance, to get a
% stronger starting opacity of $75$\,\% and a much shorter reflection length of
% only $20$\,\% of the graphics height, set the following values:\\
% \begin{minipage}[t]{\textwidth}
%   \begin{verbatim}
% \reflectgraphics[opacity=0.75, length=0.2]{example.jpg}
%   \end{verbatim}
%   \begin{center}
%     \reflectgraphics[width=4cm, height=4cm, opacity=0.75, length=0.2]{example.jpg}
%   \end{center}
% \end{minipage}\bigskip
%
% To automatically modify the distance between a graphic and its reflection
% when dimensions change, the distance and the graphics height can be set in
% relation to each other. The following code renders graphics with a height of
% $4$\,\texttt{cm} and sets the distance of the reflection to $10$\,\% of the
% graphics height ($0.4$\,\texttt{cm}$\null=0.1\cdot4$\,\texttt{cm}):\\
% \begin{minipage}[t]{\textwidth}
%   \begin{verbatim}
% \newlength{\len}
% \setlength{\len}{4cm}
% \reflectgraphics[height=\len, distance=0.1\len]{example.jpg}
%   \end{verbatim}
%   \begin{center}
%     \reflectgraphics[width=4cm, height=4cm, distance=0.4cm]{example.jpg}
%   \end{center}
% \end{minipage}\bigskip
%
% \StopEventually{}
%
% \section{Implementation}
%
% \iffalse
%<*package>
% \fi
%
%    \begin{macrocode}
\RequirePackage{kvoptions, keyval, graphicx, calc, tikz}
\usetikzlibrary{fadings}
\makeatletter
%    \end{macrocode}
% Holds the debug condition provided by option \option{debug}.
%    \begin{macrocode}
\newif\ifrg@debug
%    \end{macrocode}
% Holds the width length provided by option \option{width}.
%    \begin{macrocode}
\newlength\rg@width
%    \end{macrocode}
% Holds the height length provided by option \option{height}.
%    \begin{macrocode}
\newlength\rg@height
%    \end{macrocode}
% Holds the distance length provided by option \option{distance}.
%    \begin{macrocode}
\newlength\rg@distance
%    \end{macrocode}
%
% \begin{macro}{\rg@scale}
% Holds the scale factor provided by option \option{scale}.
%    \begin{macrocode}
\def\rg@scale{}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\rg@angle}
% Holds the angle value provided by option \option{angle}.
%    \begin{macrocode}
\def\rg@angle{}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\rg@length}
% Holds the length factor for the reflection provided by option \option{length}.
%    \begin{macrocode}
\def\rg@length{}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\rg@opacity}
% Holds the opacity factor for starting the reflection provided by option
% \option{opacity}.
%    \begin{macrocode}
\def\rg@opacity{}
%    \end{macrocode}
% \end{macro}
%
% \noindent Hold the trim lengths provided by option \option{trim}:
%
% Left trim length
%    \begin{macrocode}
\newlength\rg@triml
%    \end{macrocode}
% Bottom trim length
%    \begin{macrocode}
\newlength\rg@trimb
%    \end{macrocode}
% Right trim length
%    \begin{macrocode}
\newlength\rg@trimr
%    \end{macrocode}
% Top trim length
%    \begin{macrocode}
\newlength\rg@trimt
%    \end{macrocode}
% Dimension holding the default unit for converting dimensions.
%    \begin{macrocode}
\newdimen\rg@unit \rg@unit=1bp%
%    \end{macrocode}
% Dimension temporarily used for storing converted dimensions.
%    \begin{macrocode}
\newdimen\rg@trim@dim%
%    \end{macrocode}
%
% \begin{macro}{\rg@convtodim}
% Macro for converting an argument without unit to dimension with default unit.
%    \begin{macrocode}
\def\rg@convtodim#1#2{%
%    \end{macrocode}
% Set unit variable to default unit.
%    \begin{macrocode}
  \let\rg@unit@cur\rg@unit%
%    \end{macrocode}
% Macro for clearing the unit variable.
%    \begin{macrocode}
  \def\rg@unit@off{\let\rg@unit@cur\relax}%
%    \end{macrocode}
% Clear unit variable after next assignment.
%    \begin{macrocode}
  \afterassignment\rg@unit@off%
%    \end{macrocode}
% Assign argument |#2| to dimension.
%    \begin{macrocode}
  \rg@trim@dim#2\rg@unit@cur%
%    \end{macrocode}
% Copy resulting dimension to argument |#1|.
%    \begin{macrocode}
  \setlength#1{\the\rg@trim@dim}%
}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\rg@trim@parse}
% Macro for parsing trim values from single argument to |\rg@trim[lbrt]| and
% convert to dimension if no unit is specified.
%    \begin{macrocode}
\def\rg@trim@parse#1 #2 #3 #4 #5\\{%
  \rg@convtodim{\rg@triml}{#1}%
  \rg@convtodim{\rg@trimb}{#2}%
  \rg@convtodim{\rg@trimr}{#3}%
  \rg@convtodim{\rg@trimt}{#4}%
}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\rg@checkval}
% Macro for checking whether value is in range or not.
%    \begin{macrocode}
\def\rg@checkval#1#2#3#4{%
  \ifdim#1pt<#3pt%
    \PackageError{reflectgraphics}{%
      The specified #2 value '#1' is less than #3%
    }{%
      Specify the #2 value within the interval [#3,#4].%
    }%
  \else\ifdim#1pt>#4pt%
    \PackageError{reflectgraphics}{%
      The specified #2 value '#1' is greater than #4%
    }{%
      Specify the #2 value within the interval [#3,#4].%
    }%
  \fi\fi%
}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{key}{reflectgraphics}{debug}
% Sets debug condition.
%    \begin{macrocode}
\define@key{reflectgraphics}{debug}[true]{%
  \csname rg@debug\ifx\relax#1\relax true\else#1\fi\endcsname}
%    \end{macrocode}
% \end{key}
%
%
% \begin{key}{reflectgraphics}{width}
% Sets width length.
%    \begin{macrocode}
\define@key{reflectgraphics}{width}{%
  \setlength\rg@width{#1}}
%    \end{macrocode}
% \end{key}
%
%
% \begin{key}{reflectgraphics}{height}
% Sets height length.
%    \begin{macrocode}
\define@key{reflectgraphics}{height}{%
  \setlength\rg@height{#1}}
%    \end{macrocode}
% \end{key}
%
%
% \begin{key}{reflectgraphics}{scale}
% Sets scale factor.
%    \begin{macrocode}
\define@key{reflectgraphics}{scale}{%
  \def\rg@scale{#1}}
%    \end{macrocode}
% \end{key}
%
%
% \begin{key}{reflectgraphics}{angle}
% Sets angle factor.
%    \begin{macrocode}
\define@key{reflectgraphics}{angle}{%
  \def\rg@angle{#1}}
%    \end{macrocode}
% \end{key}
%
%
% \begin{key}{reflectgraphics}{trim}
% Sets trim lengths.
%    \begin{macrocode}
\define@key{reflectgraphics}{trim}{%
  \rg@trim@parse#1 \\}
%    \end{macrocode}
% \end{key}
%
%
% \begin{key}{reflectgraphics}{clip}
% Accept but ignore option \option{clip}.
%    \begin{macrocode}
\define@key{reflectgraphics}{clip}[true]{}
%    \end{macrocode}
% \end{key}
%
%
% \begin{key}{reflectgraphics}{distance}
% Sets reflection distance length.
%    \begin{macrocode}
\define@key{reflectgraphics}{distance}{%
  \setlength\rg@distance{#1}}
%    \end{macrocode}
% \end{key}
%
%
% \begin{key}{reflectgraphics}{length}
% Sets reflection length factor after checking that value is in range.
%    \begin{macrocode}
\define@key{reflectgraphics}{length}{%
  \rg@checkval{#1}{length}{0}{1}%
  \def\rg@length{#1}}
%    \end{macrocode}
% \end{key}
%
%
% \begin{key}{reflectgraphics}{opacity}
% Sets reflection starting opacity after checking that value is in range.
%    \begin{macrocode}
\define@key{reflectgraphics}{opacity}{%
  \rg@checkval{#1}{opacity}{0}{1}%
  \def\rg@opacity{#1}}
%    \end{macrocode}
% \noindent Set default values.
%    \begin{macrocode}
\setkeys{reflectgraphics}{%
  debug=false,%
  width=0pt,%
  height=0pt,%
  scale=1.0,%
  angle=0,%
  trim=0 0 0 0,%
  distance=3pt,%
  length=0.5,%
  opacity=0.5%
}
%    \end{macrocode}
% \end{key}
%
% Process package options by defined keys.
%    \begin{macrocode}
\ProcessKeyvalOptions*
%    \end{macrocode}
% Holds width of the graphic including extra space when rotated.
%    \begin{macrocode}
\newlength{\rg@grp@width}
%    \end{macrocode}
% Holds height of the graphic including extra space when rotated.
%    \begin{macrocode}
\newlength{\rg@grp@height}
%    \end{macrocode}
% Holds height of the reflection including extra space when rotated.
%    \begin{macrocode}
\newlength{\rg@ref@height}
%    \end{macrocode}
% Holds overall height, which is used for clipping.
%    \begin{macrocode}
\newlength{\rg@clp@height}
%    \end{macrocode}
% Hold $y$ offset of graphics node, which is used for positioning.
%    \begin{macrocode}
\newlength{\rg@grp@offset}
%    \end{macrocode}
% Hold $y$ offset of reflections node, which is used for positioning.
%    \begin{macrocode}
\newlength{\rg@ref@offset}
%    \end{macrocode}
%
% \begin{macro}{\reflectgraphics}
% This is the actual macro doing all the work.
%    \begin{macrocode}
\newcommand{\reflectgraphics}[2][]{%
%    \end{macrocode}
% Open new group so global options will not be overridden.
%    \begin{macrocode}
  \begingroup%
%    \end{macrocode}
% Load local options from first argument.
%    \begin{macrocode}
  \setkeys{reflectgraphics}{#1}%
%    \end{macrocode}
% Determine graphics dimensions. Use |\includegraphics| in \option{draft} mode
% to do that. If both the \option{width} and \option{height} options are
% specified, there is nothing that needs to be done here.
%    \begin{macrocode}
  \ifdim\rg@width=0pt\ifdim\rg@height=0pt
    \settowidth{\rg@width}{%
      \includegraphics[%
        draft,%
        scale=\rg@scale,%
        trim={\rg@triml} {\rg@trimb} {\rg@trimr} {\rg@trimt}]{#2}}%
    \settoheight{\rg@height}{%
      \includegraphics[%
        draft,%
        scale=\rg@scale,%
        trim={\rg@triml} {\rg@trimb} {\rg@trimr} {\rg@trimt}]{#2}}%
  \else% if width=0 && height!=0
    \settowidth{\rg@width}{%
      \includegraphics[%
        draft,%
        height=\rg@height,%
        trim={\rg@triml} {\rg@trimb} {\rg@trimr} {\rg@trimt}]{#2}}%
  \fi\else\ifdim\rg@height=0pt% && width!=0
    \settoheight{\rg@height}{%
      \includegraphics[%
        draft,%
        width=\rg@width,%
        trim={\rg@triml} {\rg@trimb} {\rg@trimr} {\rg@trimt}]{#2}}%
  \fi\fi%
%    \end{macrocode}
% Determine dimensions of the graphics bounding box if rotation is enabled.
% Again, |\includegraphics| in \option{draft} mode could be used to calculate
% the boundary size, but calling |\heightof| results in strange values for
% $\textrm{\option{angle}}<0$ and $\textrm{\option{angle}}>90$. Therefore,
% computing the boundary size is done manually using \package{pgfmath}, which
% turns out to be a little bit slower.
%    \begin{macrocode}
  \ifdim\rg@angle pt=0pt%
    \setlength{\rg@grp@width}{\rg@width}%
    \setlength{\rg@grp@height}{\rg@height}%
  \else%
%    \end{macrocode}
% This is totally strange: A simple division gets completely messed up if
% dividing a length by a larger length. So I need to take care to divide
% lengths only by smaller ones.
%    \begin{macrocode}
    \ifdim\rg@height>\rg@width%
      \pgfmathsetmacro{\rg@alpha}{atan(\rg@height/\rg@width)}%
    \else%
      \pgfmathsetmacro{\rg@alpha}{atan(1/(\rg@width/\rg@height)}%
    \fi%
    \pgfmathsetmacro{\rg@corner}{abs(cos(\rg@alpha))}%
    \pgfmathsetmacro{\rg@cornera}{abs(cos(\rg@alpha+\rg@angle))}%
    \pgfmathsetmacro{\rg@cornerb}{abs(cos(180-\rg@alpha+\rg@angle))}%
    \pgfmathsetmacro{\rg@scale@x}{%
      max(\rg@cornera/\rg@corner,\rg@cornerb/\rg@corner)}%
    \pgfmathsetmacro{\rg@corner}{abs(sin(\rg@alpha))}%
    \pgfmathsetmacro{\rg@cornera}{abs(sin(\rg@alpha+\rg@angle))}%
    \pgfmathsetmacro{\rg@cornerb}{abs(sin(180-\rg@alpha+\rg@angle))}%
    \pgfmathsetmacro{\rg@scale@y}{%
      max(\rg@cornera/\rg@corner,\rg@cornerb/\rg@corner)}%
    \setlength{\rg@grp@width}{\rg@scale@x\rg@width}%
    \setlength{\rg@grp@height}{\rg@scale@y\rg@height}%
  \fi%
%    \end{macrocode}
% Compute height of reflection.
%    \begin{macrocode}
  \setlength{\rg@ref@height}{%
    \rg@length\rg@grp@height}%
%    \end{macrocode}
% Compute $y$ offset of the reflection that is used for node positioning. The
% center of the reflection node is moved to the origin of the coordinate
% system. This is done, because it seems that fading with a specific size can
% only be applied in a reasonable way at the origin (with option \option{fit
% fading} set to \emph{false}).
%    \begin{macrocode}
  \setlength{\rg@ref@offset}{%
    0.5\rg@grp@height-0.5\rg@ref@height}%
%    \end{macrocode}
% Compute $y$ offset of the graphics node.
%    \begin{macrocode}
  \setlength{\rg@grp@offset}{%
    0.5\rg@ref@height+\rg@distance+0.5\rg@grp@height}%
%    \end{macrocode}
% Compute overall height, which is used for clipping.
%    \begin{macrocode}
  \setlength{\rg@clp@height}{%
    \rg@grp@height+\rg@distance+\rg@ref@height}%
%    \end{macrocode}
% The following |\tikzfadingfrompicture| macro does not work with
% Ti\textit{k}Z externalize. Therefore, if the Ti\textit{k}Z library
% \package{external} is loaded it must be disabled for the whole rendering.
%    \begin{macrocode}
  \ifdefined\tikzexternaldisable%
    \tikzexternaldisable%
  \fi%
%    \end{macrocode}
% Define custom fading \option{fade south}, which starts at $0$\,\%
% transparency and ends at $100$\,\%. The height of this fading equates to the
% height of the reflection. |\tikzfadingfrompicture| is used instead of
% |\tikzfading| because of its possibility to define shades with specific
% sizes. By doing so, this fading is not stretched across the whole node and
% therefore it can be used to hide a specific part of the reflection node.
%    \begin{macrocode}
  \begin{tikzfadingfrompicture}[name=fade south]%
    \shade[top color=transparent!0, bottom color=transparent!100]%
      (0,0) rectangle (\rg@grp@width,\rg@ref@height);%
  \end{tikzfadingfrompicture}%
%    \end{macrocode}
% Start the actual rendering.
%    \begin{macrocode}
  \begin{tikzpicture}%
%    \end{macrocode}
% Draw help lines if \option{debug} option is specified.
%    \begin{macrocode}
    \ifrg@debug%
      \def\rg@padding{0.25\rg@grp@height}%
      \draw[help lines]%
        (-0.5\rg@grp@width-\rg@padding,%
          -0.5\rg@ref@height-\rg@distance-\rg@grp@height-\rg@padding)%
        grid (0.5\rg@grp@width+\rg@padding,%
          0.5\rg@ref@height+\rg@distance+\rg@grp@height+\rg@padding);%
    \fi%
%    \end{macrocode}
% Clip the following nodes to graphics width |\rg@grp@width| and clipping
% height |\rg@clp@height|. This is necessary to get rid of the remaining
% transparent part of the reflection node, which still consumes much space,
% even though nothing is visible.
%    \begin{macrocode}
    \clip {(-0.5\rg@grp@width,\rg@clp@height-0.5\rg@ref@height)%
      rectangle ++(\rg@grp@width,-\rg@clp@height)};%
%    \end{macrocode}
% Draw the graphics node.
%    \begin{macrocode}
    \node at (0,\rg@grp@offset) {%
%    \end{macrocode}
% Draw graphics using |\includegraphics|.
%    \begin{macrocode}
      \includegraphics[%
        width=\rg@width,%
        height=\rg@height,%
        angle=\rg@angle,%
        trim={\rg@triml} {\rg@trimb} {\rg@trimr} {\rg@trimt},%
        clip]{#2}%
    };%
%    \end{macrocode}
% Draw the reflection node with previously defined custom fading
% \option{fade south} and with the opacity value specified by option
% \option{opacity}.
%    \begin{macrocode}
    \node at (0,-\rg@ref@offset) [%
      opacity=\rg@opacity,%
      scope fading=fade south,%
      fit fading=false%
    ] {%
%    \end{macrocode}
% Flip reflection node content vertically.
%    \begin{macrocode}
      \scalebox{1}[-1]{%
%    \end{macrocode}
% Draw graphics using |\includegraphics|.
%    \begin{macrocode}
        \includegraphics[%
          width=\rg@width,%
          height=\rg@height,%
          angle=\rg@angle,%
          trim={\rg@triml} {\rg@trimb} {\rg@trimr} {\rg@trimt},%
          clip]{#2}%
      }%
    };%
  \end{tikzpicture}%
%    \end{macrocode}
% Close group.
%    \begin{macrocode}
  \endgroup%
}
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
\makeatother
%    \end{macrocode}

%
% \iffalse
%</package>
% \fi
%
% \Finale
\endinput