# Create an adapted pgfpicture with fixed width for RTL context

Here an example of fixed width pgfpicture in RTL context (lualatex engine)

\documentclass{article}
\usepackage{pgf}
\usepackage[showframe]{geometry}

\parindent0pt

\begin{document}

\pagedir TRT \pardir TRT \textdir TRT \bodydir TRT

A {\textdir TLT\begin{pgfpicture}{0pt}{0bp}{50pt}{3cm}
\color{red}
\pgfpathrectangle{\pgfpointorigin}{\pgfpoint{10cm}{2cm}}
\pgfpathmoveto{\pgfpointorigin}
\pgfpathlineto{\pgfpoint{10cm}{2cm}}
\pgfusepath{stroke}
\pgfpathmoveto{\pgfpointorigin}
\pgfpathqcircle{3pt}
\pgfsetfillcolor{blue}
\pgfusepath{fill}
\end{pgfpicture}} B

\end{document}


So with \begin{pgfpicture}{0pt}{0pt}{50pt}{3cm} contents of environment appears on the margin but in RTL pgfpic box should appears left of A point not right of B.

My question is there a solution which consist of redefining \pgfpicture to allow a correct result in RTL context (pgfpicture contents in the page not outside).

Result in RTL context should look like this

• It's not really clear how youwant this to behave, after all pgfpicture is doing exactly what you ask it to do (\pardir TRT sets the starting point of the paragraph on the right side, \textdir TLT requests that this are written from left to right and therefore protrude on the right side. Adding space for this change in direction is explicitly suppressed by setting the width to zero.) Redefining pgfpicture would probably break other components which expect pfgpicture to work correctly. Oct 15 '20 at 23:37
• If you use pgfpictureboxed instead of pgfpicture you can see, that the right amount of space is reserved for your content. You are simply drawing outside of the pgfpicture...
– DG'
Oct 19 '20 at 10:37
• @DG' In reallity pgfpicture place its contents in \pgfpic box with 0pt width and with the end of environment it makes series of shifts and then puts the box after text which come just before start of environment. Oct 19 '20 at 10:51

Here my attempt: two pgfpicture environments the second is void just to create bounding box, look if there is a possibility to use just one pgfpicture environment.

\documentclass{article}
\usepackage{pgf}
\usepackage[showframe]{geometry}

\parindent0pt

\makeatletter

\newbox\pgfrtlpic

\newdimen\pgf@rtlpicminx
\newdimen\pgf@rtlpicmaxx
\newdimen\pgf@rtlpicminy
\newdimen\pgf@rtlpicmaxy

\def\rtlpgfpicture#1#2#3#4{%
\pgf@rtlpicminx=#1\relax%
\pgf@rtlpicminy=#2\relax%
\pgf@rtlpicmaxx=#3\relax%
\pgf@rtlpicmaxy=#4\relax%
\setbox\pgfrtlpic\hbox dir TLT to 0pt\bgroup\hss\pgfpicture%
}

\def\endrtlpgfpicture{%
\endpgfpicture\egroup%
\hbox to 0pt{\hskip-\pgf@rtlpicminx\box\pgfrtlpic\hss}%
\pgfpicture{\pgf@rtlpicminx}{\pgf@rtlpicminy}{\pgf@rtlpicmaxx}{\pgf@rtlpicmaxy}%
\endpgfpicture%
}

\makeatother

\begin{document}

\pagedir TRT \pardir TRT \textdir TRT \bodydir TRT

A {%
\begin{rtlpgfpicture}{0pt}{0pt}{50pt}{3cm}
\color{red}
\pgfpathrectangle{\pgfpointorigin}{\pgfpoint{10cm}{2cm}}
\pgfpathmoveto{\pgfpointorigin}
\pgfpathlineto{\pgfpoint{10cm}{2cm}}
\pgfusepath{stroke}
\pgfpathmoveto{\pgfpointorigin}
\pgfpathqcircle{3pt}
\pgfsetfillcolor{blue}
\pgfusepath{fill}
\end{rtlpgfpicture}%
} B

\end{document}


This is a longer comment.

As I understand it, the first four arguments of \pgfpicture is one way to hard-code the bounding box of the picture. For example, you specify that the bounding box is from (0, 0) to (50pt, 3cm); but your picture actually extends to (10cm, 2cm). So it exceeds the right margin.

If, instead, some line goes to (-5cm, 0), then that line will exceed the left margin. This has nothing to do with LTR or LTR text; it's about on which side your contents exceed the bounding box you specify.

I would recommend using \hbox to 50pt{\hss your pgf picture } to right-align your pgf picture. You can definitely define a new environment that puts \hss on the correct side of the pgf picture (using an \if condition that knows text direction).

Here is an MWE

\documentclass{article}
\usepackage{tikz}
\usepackage[showframe]{geometry}

\parindent0pt

\begin{document}

A
{\textdir TLT%
\hbox to 7cm{%
\begin{pgfpicture}
\pgfpathrectangle{\pgfpointorigin}{\pgfpoint{10cm}{2cm}}
\pgfusepath{stroke}
\end{pgfpicture}%
\hss
}%
}
B

C
{\textdir TLT%
\hbox to 7cm{%
\tikz\draw(0,0)rectangle(10,2);
\hss
}%
}
D

\pagedir TRT \pardir TRT \textdir TRT \bodydir TRT

A
{\textdir TLT%
\hbox to 7cm{%
\hss
\begin{pgfpicture}
\pgfpathrectangle{\pgfpointorigin}{\pgfpoint{10cm}{2cm}}
\pgfusepath{stroke}
\end{pgfpicture}%
}%
}
B

C
{\textdir TLT%
\hbox to 7cm{%
\hss
\tikz\draw(0,0)rectangle(10,2);%
}%
}
D

\end{document}


Remark: As I am reading the source code, specifying bounding box after \pgfpicture seems to be obsolete and is not documented in the current 1321-page manual. Consider using \pgfinterruptboundingbox.

# Edit

Here are more atomic operations that can achieve a variety of goals

\documentclass{article}
\usepackage{tikz}
\usepackage[showframe]{geometry}

\parindent0pt

\begin{document}

\pagedir TRT \pardir TRT \textdir TRT \bodydir TRT

\def\examplebox{
\pgfpathrectangle{\pgfpointorigin}{\pgfpoint{5cm}{2cm}}
\foreach\x in{1,...,4}{
\pgfpathmoveto{\pgfpoint{\x cm}{0cm}}
\pgfpathlineto{\pgfpoint{\x cm}{.5cm}}
}
\pgfusepath{stroke}
}

Respect the natural xmin%
{\textdir TLT%
\begin{pgfpicture}
\examplebox
\makeatletter
\global\pgf@picmaxx=4cm
\end{pgfpicture}%
}%
align x=4cm to the right boundary

Respect the natural xmax%
{\textdir TLT%
\begin{pgfpicture}
\examplebox
\makeatletter
\global\pgf@picminx=1cm
\end{pgfpicture}%
}%
align x=1cm to the left boundary

Align x=4cm to the right boundary%
{\textdir TLT%
\begin{pgfpicture}
\examplebox
\makeatletter
\global\pgf@picminx=1cm
\global\pgf@picmaxx=4cm
\end{pgfpicture}%
}%
align x=1cm to the left boundary

Align x=3.5cm to the right boundary%
{\textdir TLT%
\begin{pgfpicture}
\examplebox
\makeatletter
\global\pgf@picmaxx=3.5cm
\global\pgf@picminx=\dimexpr 3.5cm-2.5cm\relax
\end{pgfpicture}%
}%
and set the width to be 2.5cm

Align x=1.5cm to the left boundary%
{\textdir TLT%
\begin{pgfpicture}
\examplebox
\makeatletter
\global\pgf@picminx=1.5cm
\global\pgf@picmaxx=\dimexpr 1.5cm+3cm\relax
\end{pgfpicture}%
}%
and set the width to be 3cm

Align the natural xmax to the right boundary%
{\textdir TLT%
\begin{pgfpicture}
\examplebox
\makeatletter
\global\pgf@picminx=\dimexpr\pgf@picmaxx-3.5cm\relax
\end{pgfpicture}%
}%
and set the width to 3.5cm

Align the natural xmin to the left boundary%
{\textdir TLT%
\begin{pgfpicture}
\examplebox
\makeatletter
\global\pgf@picmaxx=\dimexpr\pgf@picminx+4.5cm\relax
\end{pgfpicture}%
}%
and set the width to 4.5cm

\end{document}

• I have tried with \hbox to 50pt{\hss pgfpicture } but it does not succeed the real dimension of \pgfpic box containning drawing is 0pt. Jul 21 at 20:20
• The problem is that in left-to-right context text and drawing go in same direction but in right-to-left text and drawing go in opposite directions Jul 21 at 20:27
• How about something like \begin{pgfpicture}{1cm}{0cm}{3cm}{3cm}, and how about height of picture box ? Jul 21 at 22:14
• I added an Edit section that demonstrated how to achieve a variety of alignment goals. I don't know what you want, so let me know what else I can do for you. Jul 22 at 0:12