[latex3-commits] [l3svn] branch master updated: Start adding some drawing drivers
noreply at latex-project.org
noreply at latex-project.org
Sun May 15 23:21:29 CEST 2016
This is an automated email from the git hooks/post-receive script.
joseph pushed a commit to branch master
in repository l3svn.
The following commit(s) were added to refs/heads/master by this push:
new 5ae36ee Start adding some drawing drivers
5ae36ee is described below
commit 5ae36ee29ef568eb5d543e9ef80d06e05e719d84
Author: Joseph Wright <joseph.wright at morningstar2.co.uk>
Date: Sun May 15 22:21:19 2016 +0100
Start adding some drawing drivers
This is largely a 'fun' exercise following the recent work on box
clipping. At a driver level the amount of code needed to do drawing is
surprisingly small: the additions here cover much of what pgf can do
(which is largely where the ideas come from).
This first checkin covers only PDF generation, but that includes
pdfTeX and LaTeX in PDF mode, XeTeX (xdvipdfmx) and (u)pTeX using
dvipdfmx. It also covers only the 'more common' drawing steps, lacking
those that need PDF objects declaring. (This means that things like
shadings, opaque ares, masks, etc., are not currently in.)
I'll almost certainly add the matching code for dips and dvisvgm.
What else gets done is not clear at the moment: perhaps picture
mode, perhaps something like the pff base layer, perhaps nothing more
than the driver level, perhaps the more complex operations, ...
---
l3kernel/l3drivers.dtx | 264 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 264 insertions(+)
diff --git a/l3kernel/l3drivers.dtx b/l3kernel/l3drivers.dtx
index 0164460..20cd88a 100755
--- a/l3kernel/l3drivers.dtx
+++ b/l3kernel/l3drivers.dtx
@@ -314,6 +314,270 @@
% \end{macro}
% \end{macro}
%
+% \subsection{Drawing}
+%
+% \begin{macro}[aux]{\@@_draw_literal:n, \@@_draw_literal:x}
+% Pass data through using a dedicated interface.
+% \begin{macrocode}
+\cs_new_eq:NN \__driver_draw_literal:n \__driver_literal:n
+\cs_generate_variant:Nn \__driver_draw_literal:n { x }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_draw_begin:, \@@_draw_end:}
+% No special requirements here, so simply set up a drawing scope.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_draw_begin:
+ { \@@_draw_scope_begin: }
+\cs_new_protected_nopar:Npn \@@_draw_end:
+ { \__driver_draw_scope_end: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_draw_scope_begin:, \@@_draw_scope_end:}
+% In contrast to a general scope, a drawing scope is always done using
+% the PDF operators so is the same for all relevant drivers.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_draw_scope_begin:
+ { \@@_draw_literal:n { q } }
+\cs_new_protected_nopar:Npn \@@_draw_scope_end:
+ { \@@_draw_literal:n { Q } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_draw_moveto:nn, \@@_draw_lineto:nn}
+% \begin{macro}[int]{\@@_draw_curveto:nnnnnn}
+% \begin{macro}[int]{\@@_draw_rectangle:nnnn}
+% Path creation operations all resolve directly to PDF primitive steps, with
+% only the need to convert to \texttt{bp}. Notice that \texttt{x}-type
+% expansion is included here to ensure that any variable values are
+% forced to literals before any possible caching.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_draw_moveto:nn #1#2
+ {
+ \@@_draw_literal:x
+ { \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~ m }
+ }
+\cs_new_protected:Npn \@@_draw_lineto:nn #1#2
+ {
+ \@@_draw_literal:x
+ { \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~ l }
+ }
+\cs_new_protected:Npn \@@_draw_curveto:nnnnnn #1#2#3#4#5#6
+ {
+ \@@_draw_literal:x
+ {
+ \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~
+ \dim_to_decimal_in_bp:n {#3} ~ \dim_to_decimal_in_bp:n {#4} ~
+ \dim_to_decimal_in_bp:n {#5} ~ \dim_to_decimal_in_bp:n {#6} ~
+ c
+ }
+ }
+\cs_new_protected:Npn \@@_draw_rectangle:nnnn #1#2#3#4
+ {
+ \@@_draw_literal:x
+ {
+ \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~
+ \dim_to_decimal_in_bp:n {#3} ~ \dim_to_decimal_in_bp:n {#4} ~
+ re
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}[int]{\@@_draw_eor_bool}
+% The even-odd rule here can be implemented as a simply switch.
+% \begin{macrocode}
+\bool_new:N \@@_draw_eor_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[int]
+% {
+% \@@_draw_closepath: ,
+% \@@_draw_stroke: ,
+% \@@_draw_closestroke: ,
+% \@@_draw_fill: ,
+% \@@_draw_fillstroke: ,
+% \@@_draw_clip: ,
+% \@@_draw_discardpath:
+% }
+% Converting paths to output is again a case of mapping directly to
+% PDF operations.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_draw_closepath:
+ { \@@_draw_literal:n { h } }
+\cs_new_protected_nopar:Npn \@@_draw_stroke:
+ { \@@_draw_literal:n { S } }
+\cs_new_protected_nopar:Npn \@@_draw_closestroke:
+ { \@@_draw_literal:n { s } }
+\cs_new_protected_nopar:Npn \@@_draw_fill:
+ {
+ \@@_draw_literal:x
+ { f \bool_if:NT \@@_draw_eor_bool * }
+ }
+\cs_new_protected_nopar:Npn \@@_draw_fillstroke:
+ {
+ \@@_draw_literal:x
+ { B \bool_if:NT \@@_draw_eor_bool * }
+ }
+\cs_new_protected_nopar:Npn \@@_draw_clip:
+ {
+ \@@_draw_literal:x
+ { W \bool_if:NT \@@_draw_eor_bool * }
+ }
+\cs_new_protected_nopar:Npn \@@_draw_discardpath:
+ { \@@_draw_literal:n { n } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_draw_transformcm:nnnnnn}
+% The first four arguments here are floats (the affine matrix), the last
+% two are a displacement vector. Once again, force evaluation to allow for
+% caching.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_draw_transformcm:nnnnnn #1#2#3#4#5#6
+ {
+ \@@_draw_literal:x
+ {
+ \fp_eval:n {#1} ~ \fp_eval:n {#2} ~
+ \fp_eval:n {#3} ~ \fp_eval:n {#4} ~
+ \dim_to_decimal_in_bp:n {#5} ~ \dim_to_decimal_in_bp:n {#6} ~
+ cm
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_draw_dash:nn}
+% \begin{macro}[aux]{\@@_draw_dash:n}
+% \begin{macro}[int]{\@@_draw_linewidth:n}
+% \begin{macro}[int]{\@@_draw_miterlimit:n}
+% \begin{macro}[int]^^A
+% {
+% \@@_draw_cap_butt:, \@@_draw_cap_round:, \@@_draw_cap_rectangle:,
+% \@@_draw_join_butt:, \@@_draw_join_round:, \@@_draw_join_bevel:
+% }
+% Converting paths to output is again a case of mapping directly to
+% PDF operations.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_draw_dash:nn #1#2
+ {
+ \@@_draw_literal:x
+ {
+ [ ~
+ \clist_map_function:nN {#1} \@@_draw_dash:n
+ ] ~
+ \dim_to_decimal_in_bp:n {#2} ~ d
+
+ }
+ }
+\cs_new:Npn \@@_draw_dash:n #1
+ { \dim_to_decimal_in_bp:n {#1} ~ }
+\cs_new_protected:Npn \@@_draw_linewidth:n #1
+ {
+ \@@_draw_literal:x
+ { \dim_to_decimal_in_bp:n {#1} ~ w }
+ }
+\cs_new_protected:Npn \@@_draw_miterlimit:n #1
+ { \@@_draw_literal:x { \fp_eval:n {#1} ~ M } }
+\cs_new_protected_nopar:Npn \@@_draw_cap_butt:
+ { \@@_draw_literal:n { 0 ~ J } }
+\cs_new_protected_nopar:Npn \@@_draw_cap_round:
+ { \@@_draw_literal:n { 1 ~ J } }
+\cs_new_protected_nopar:Npn \@@_draw_cap_rectangle:
+ { \@@_draw_literal:n { 2 ~ J } }
+\cs_new_protected_nopar:Npn \@@_draw_join_mitre:
+ { \@@_draw_literal:n { 0 ~ j } }
+\cs_new_protected_nopar:Npn \@@_draw_join_round:
+ { \@@_draw_literal:n { 1 ~ j } }
+\cs_new_protected_nopar:Npn \@@_draw_join_bevel:
+ { \@@_draw_literal:n { 2 ~ j } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]
+% {\@@_draw_color_cmyk_fill:nnnn, \@@_draw_color_cmyk_stroke:nnnn}
+% \begin{macro}[int]
+% {\@@_draw_color_gray_fill:n, \@@_draw_color_gray_stroke:n}
+% \begin{macro}[int]
+% {\@@_draw_color_rgb_fill:nnn, \@@_draw_color_rgb_stroke:nnn}
+% Yet more fast conversion, all using the FPU to allow for expressions
+% in numerical input.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_draw_color_cmyk_fill:nnnn #1#2#3#4
+ {
+ \@@_draw_literal:x
+ {
+ \fp_eval:n {#1} ~ \fp_eval:n {#2} ~
+ \fp_eval:n {#3} ~ \fp_eval:n {#4} ~
+ k
+ }
+ }
+\cs_new_protected:Npn \@@_draw_color_cmyk_stroke:nnnn #1#2#3#4
+ {
+ \@@_draw_literal:x
+ {
+ \fp_eval:n {#1} ~ \fp_eval:n {#2} ~
+ \fp_eval:n {#3} ~ \fp_eval:n {#4} ~
+ K
+ }
+ }
+\cs_new_protected:Npn \@@_draw_color_gray_fill:n #1
+ { \@@_draw_literal:x { \fp_eval:n {#1} ~ g } }
+\cs_new_protected:Npn \@@_draw_color_gray_stroke:n #1
+ { \@@_draw_literal:x { \fp_eval:n {#1} ~ G } }
+\cs_new_protected:Npn \@@_draw_color_rgb_fill:nnn #1#2#3
+ {
+ \@@_draw_literal:x
+ { \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ \fp_eval:n {#3} ~ rg }
+ }
+\cs_new_protected:Npn \@@_draw_color_rgb_stroke:nnn #1#2#3
+ {
+ \@@_draw_literal:x
+ { \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ \fp_eval:n {#3} ~ RG }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_draw_hbox:Nnnnnnn}
+% \begin{variable}[aux]{\l_@@_tmp_box}
+% Inserting a \TeX{} box transformed to the requested position and using
+% the current matrix is done using a mixture of \TeX{} and low-level
+% manipulation. The offset can be handled by \TeX{}, so only any rotation/^^A
+% skew/scaling component needs to be done using the matrix operation. As this
+% operation can never be cached, the scope is set directly not using the
+% \texttt{draw} version.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_draw_hbox:Nnnnnnn #1#2#3#4#5#6#7
+ {
+ \hbox_set:Nn \l_@@_tmp_box
+ {
+ \tex_kern:D \__dim_eval:w #6 \__dim_eval_end:
+ \@@_scope_begin:
+ \@@_draw_transformcm:nnnnnn {#2} {#3} {#4} {#5}
+ { 0pt } { 0pt }
+ \box_move_up:nn {#7} { \box_use:N #1 }
+ \@@_scope_end:
+ }
+ \box_set_wd:Nn \l_@@_tmp_box { 0pt }
+ \box_set_ht:Nn \l_@@_tmp_box { 0pt }
+ \box_set_dp:Nn \l_@@_tmp_box { 0pt }
+ \box_use:N \l_@@_tmp_box
+ }
+\box_new:N \l_@@_tmp_box
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+%
% \begin{macrocode}
%</pdfmode>
% \end{macrocode}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the latex3-commits
mailing list