% $Id: dcpic.sty,v 1.31 2007/12/13 17:34:57 pedro Exp pedro $
%% DC-PiCTeX
%% Copyright (c) 1990-2007 Pedro Quaresma de Almeida, Coimbra 
%% 11/1990 (version 1.0); 
%%   10/1991 (version 1.1);
%%    9/1993 (version 1.2);  
%%    3/1995 (version 1.3);
%%  7/1996 (version 2.1);
%%  5/2001 (version 3.0); 
%%   11/2001 (version 3.1);
%%    1/2002 (version 3.2)
%%  5/2002 (version 4.0); 
%%    3/2003 (version 4.1); 
%%      12/2004 (version 4.1.1)
%%       3/2007 (version 4.1.2)

\immediate\write10{Package DCpic 2007/03/01 v4.1.2}

\ProvidesPackage{dcpic}[2007/03/01 v4.1.2]

%% Version X.Y.Z
%%   X - major versions
%%   Y - minor versions
%%   Z - bug corrections
%%
%% Copyright (c) 1990-2007 Pedro Quaresma <pedro@mat.uc.pt>
%% The DCpic package is free software; you can redistribute it and/or
%% modify it under the terms of the GNU General Public License as
%% published by the Free Software Foundation; either version 2 of the
%% License, or (at your option) any later version.
%%
%% The DCpic package is distributed in the hope that it will be
%% useful, but WITHOUT ANY WARRANTY; without even the implied warranty
%% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%% General Public License for more details.
%%
%% You should have received a copy of the GNU General Public License
%% along with this package; if not, write to the Free Software
%% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
%%
%%
%% Coimbra, 13 de Dezembro de 2007
%% Pedro Quaresma de Almeida
%%
%%  DCpic is a package of \TeX\ macros for graph modelling in a
%%  (La)\TeX\ or Con\TeX t document. Its distinguishing features are:
%%  the use of \PiCTeX\ a powerful graphical engine, and a simple
%%  specification syntax. A graph is described in terms of its objects
%%  and its edges. The objects are textual elements and the edges can
%%  have various straight or curved forms. 
%%
%%
%%  A graph in DCpic is a "picture" in \PiCTeX, in which we place our
%%  {\em objects} and {\em morphisms} (edges). The user's commands in
%%  DCpic are: {\tt begindc} and {\tt enddc} which establishe the
%%  coordinate system where the objects will by placed; {\tt obj}, the
%%  command which defines the place and the contents of each object;
%%  {\tt mor}, and {\tt cmor}, the commands which define the
%%  morphisms, linear and curved edges, and its labels. 
%%
%%  Example:
%%   \begindc{\commdiag}[3]
%%    \obj(10,15){$A$}
%%    \obj(25,15){$B$}
%%    \obj(40,15){$C$}
%%    \mor{$A$}{$B$}{$f$}
%%    \mor{$B$}{$C$}{$g$}
%%    \cmor((10,11)(11,7)(15,6)(25,6)(35,6)(39,7)(40,11))
%%     \pup(25,3){$g\circ f$}
%%   \enddc
%%
%% NOTES: 
%%    all the numeric values should be integer values.
%% 
%% Available commands:
%%
%% The environment:
%%   \begindc{#1}[#2]
%%        #1 - Graph type
%%          0 = "commdiag" (commutative diagram)
%%          1 = "digraph" (direct graph)
%%          2 = "undigraph" (undirect graph)
%%          3 = "cdigraph" with incircled objects
%%          4 = "cundigraph" with incircled objects
%%        (optional) #2 - magnification factor (default value, 30)
%%
%%   \enddc
%%
%% Objects:
%%   \obj(#1,#2)[#3]{#4}[#5]
%%            #1 and #2 - coordenates
%% (optional) #3 - Label, to be used in the morphims command, if not
%%                 present the #4 will be used to that purpose
%%            #4 - Object contents
%% (optional) #5 - placement of the object (default value \north)
%%                   0="\pcent", center
%%                   1="\north", north
%%                   2="\northeast", northeast
%%                   3="\east", east
%%                   4="\southeast", southeast
%%                   5="\south", south
%%                   6="\southwest", southwest
%%                   7="\west", west
%%                   8="\northwest", northwest
%%  !!! Note !!!
%%  if you omit the #3 argument (label) and the #4 argument is a
%%  complex LaTeX command this can cause this command to crash. In
%%  this case you must specify a label (the empty label [], if you do
%%  needed it it for nothing).
%%
%% Morphims (linear edges). This commando has to two major variants
%% i) Starting and Ending objects specification
%%   \mor{#1}{#2}[#5,#6]{#7}[#8,#9]
%%
%% As you can see this first form is (intencionaly) badly formed, the
%% arguments #3 and #4 are missing (the actual command is correctly
%% formed). 
%% 
%%        #1 - The starting object reference
%%        #2 - The ending object reference
%%
%% from this two we will obtain the objects coordinates, and also the
%% dimensions of the enclosing box. 
%%
%% The objects box dimensions are used to do an automatic adjustment of
%% the edge width.
%%
%% from #1 we obtain (x,y), (#1,#2) in the second form
%% from #2 we obtain (x',y'), (#3,#4) in the second form
%%
%% this values will be passed to the command second form
%%
%%ii) Two points coordinates specification
%%   \mor(#1,#2)(#3,#4)[#5,#6]{#7}[#8,#9]
%%
%% Now we can describe all the arguments
%%
%%          #1 and #2 - coordinates (beginning)
%%          #3 and #4 - coordinates (ending)
%%(optional)#5,#6 - correction factors (defaul values, 10 and 10)
%%          #5 - actual beginning of the edge 
%%          #6 - actual ending of the edge 
%%          #7 - text (morphism label)
%%(optional)#8,#9
%%          #8 - label placement
%%               1 = \atright, at right, default value
%%              -1 = \atleft, at left
%%          #9 - edge type
%%               0 = "\solidarrow", default edge
%%               1 = "\dasharrow"
%%               2 = "\solidline"
%%               3 = "\dashline"
%%               4 = "\dotline"
%%               5 = "\injectionarrow"   --- old value 3
%%               6 = "\aplicationarrow"  --- old value 4
%%               7 = "\surjectivearrow"  --- old value 5
%%
%% Note: insert a space after the command.
%%
%% Curved Morphisms (quadratic edges):
%%   \cmor(#1) #2(#3,#4){#5}[#6]
%%          #1 - list of points (odd number)
%%          #2 - tip direction
%%              0 = "\pup", pointing up
%%              1 = "\pdown", pointing down
%%              2 = "\pright", pointing right
%%              3 = "\pleft",  pointing left
%%          #3 and #4 - coordenates of the label
%%          #5 - morphism label
%%(optional)#6 - edge type
%%              0 ="\solidarrow", default value
%%              1 = "\dasharrow"
%%              2 = "\solidline"
%%
%% Notes: insert a space after the command.
%%        the space after the list of points is mandatory
%%
%% Exemples:
%%\documentclass[a4paper,11pt]{article}
%%\usepackage{dcpic,pictexwd}
%%
%%\begin{document}
%%\begindc[3]
%%\obj(14,11){$A$}
%%\obj(39,11){$B$}
%%\mor(14,12)(39,12){$f$}%[\atright,\solidarrow]
%%\mor(39,10)(14,10){$g$}%[\atright,\solidarrow]
%%\cmor((10,10)(6,11)(5,15)(6,19)(10,20)(14,19)(15,15)) 
%%  \pdown(2,20){$id_A$}
%%\cmor((40,7)(41,3)(45,2)(49,3)(50,7)(49,11)(45,12)) 
%%  \pleft(54,3){$id_B$}
%%\enddc
%%
%%\begindc{\commdiag}[3]
%%\obj(10,15)[A]{$A$}
%%\obj(40,15)[Aa]{$A$}
%%\obj(25,15)[B]{$B$}
%%\mor{A}{B}{$f$}%[\atright,\solidarrow]
%%\mor{B}{Aa}{$g$}%[\atright,\solidarrow]
%%\cmor((10,11)(11,7)(15,6)(25,6)(35,6)(39,7)(40,11)) 
%%  \pup(25,3){$id_A$}
%%\enddc
%%
%%\newcommand{\barraA}{\vrule height2em width0em depth0em}
%%\newcommand{\barraB}{\vrule height1.6em width0em depth0em}
%%\begindc{\commdiag}[35]
%%\obj(1,1)[Gr]{$G$}
%%\obj(3,1)[Grstar]{$G_{r^*}$}
%%\obj(5,1)[H]{$H$}
%%\obj(2,2)[SigmaG]{$\Sigma^G$}
%%\obj(6,2)[SigmaH]{$\Sigma^H$}
%%\obj(1,3)[Lm]{$L_m$}
%%\obj(3,3)[Krm]{$K_{r,m}$}
%%\obj(5,3)[Rmstar]{$R_{m^*}$}
%%\obj(1,5)[L]{$L$}
%%\obj(3,5)[Lr]{$L_r$}
%%\obj(5,5)[R]{$R$}
%%\obj(2,6)[SigmaL]{$\Sigma^L$}
%%\obj(6,6)[SigmaR]{$\Sigma^R$}
%%\mor{Gr}{SigmaG}{$\lambda^G$}
%%\mor{Grstar}{Gr}{$i_5$}[\atleft,\aplicationarrow]
%%\mor{Grstar}{H}{$r^*$}[\atright,\solidarrow]
%%\mor{H}{SigmaH}{$\lambda^H$}[\atright,\dasharrow]
%%\mor{SigmaG}{SigmaH}{$\varphi^{r^*}$}[\atright,\solidarrow]
%%\mor{Lm}{Gr}{$m$}[\atright,\solidarrow]
%%\mor{Lm}{L}{$i_2$}[\atleft,\aplicationarrow]
%%\mor{Krm}{Lm}{$i_3\quad$}[\atright,\aplicationarrow]
%%\mor{Krm}{Rmstar}{$r$}
%%\mor{Krm}{Lr}{$i_4$}[\atright,\aplicationarrow]
%%\mor{Krm}{Grstar}{$m$}
%%\mor{Rmstar}{R}{$i_6$}[\atright,\aplicationarrow]
%%\mor{Rmstar}{H}{$m^*$}
%%\mor{L}{SigmaL}{$\lambda^L$}
%%\mor{Lr}{L}{$i_1\quad$}[\atright,\aplicationarrow]
%%\mor{Lr}{R}{$r$}
%%\mor{R}{SigmaR}{$\lambda^R$}[\atright,\solidarrow]
%%\mor{SigmaL}{SigmaG}{$\varphi^m$}[\atright,\solidarrow]
%%\mor{SigmaL}{SigmaR}{$\varphi^r$}
%%\mor{SigmaR}{SigmaH}{$\varphi^{m^*}$}
%%\enddc
%%
%%\end{document}
%%-----------------//-------------
%% Modifica{\c c}{\~o}es (9/1993)
%%       argumento "dist{\^a}ncia entre as extremidades da seta e os
%%       objectos" passou a ser opcional; uma nova op{\c c}{\~a}o para as
%%       "setas" (op{\c c}{\~a}o 3). 
%%
%% 2/3/1995 (vers{\~a}o 1.3) 
%%       foi acrescentado o tipo de seta de aplica{\c c}{\~a}o
%%       (op{\c c}{\~a}o 4) a dist{\^a}ncia da etiqueta {\`a} seta respectiva
%%       passou a ser fixa  (10 unidades de medida).
%% 15/7/1996 (vers{\~a}o 2.1)
%%       O comando "\mor" passou a ter uma sintaxe distinta. Os
%%       par{\^a}metros 5 e 6 passaram a ser a dist{\^a}ncia entre os
%%       objectos e os extremos da seta o par{\^a}metro 7 {\'e} o nome do
%%       morfismo e os par{\^a}metros 8 e 9, coloca{\c c}{\~a}o do morfismo
%%       e tipo de morfismo passaram a ser opcionais.
%%
%% 5/2001 (vers{\~a}o 3.0)
%%       Implementa{\c c}{\~a}o do comando "\cmor" baseado no comando
%%       de desenho de curvas quadr{\'a}ticas pelo PiCTeX
%%
%% 11/2001 (vers{\~a}o 3.1)
%%       Modifica{\c c}{\~a}o das pontas das setas de forma a estas ficarem
%%       semelhantes {\`a}s setas (s{\'\i}mbolos) dos TeX.
%%
%% 1/2002  (vers{\~a}o 3.2)
%%       Modifica{\c c}{\~a}o dos comandos "obj" e "mor" de forma a introduzir
%%       a especifica{\c c}{\~a}o l{\'o}gica dos morfismos, isto {\'e}, passa-se a
%%       dizer qual {\'e} o objecto de partida e/ou o objecto de chegada
%%       em vez de ter de especificar o morfismo em termos de
%%       coordenadas. 
%%       Por outro lado o tamanho das setas passa a ser ajustado
%%       automaticamente em rela{\c c}{\~a}o ao tamanho dos objectos.
%%
%% 5/2002 (versão 4.0)
%%       Modificação dos comandos "begindc" e "obj"
%% !!! Modificação da sintaxe destes comandos !!!
%%       O comando "begindc" passou a ter um argumento (obrigatório)
%%       que nos permite especificar o tipo de grafo que estamos a
%%       querer especificar:
%%         "commdiag" (0), para diagramas comutativos
%%         "digraph" (1), para grafos orientados
%%         "undigraph" (2), para grafos não orientados
%%       O comando "obj" modificou a sua sintaxe passou a ter um (após
%%       a especificação das coordenadas, um argumento opcional, um
%%       argumento obrigatório, e um argumento opcional. O primeiro
%%       argumento opcional dá-nos a etiqueta que serve como
%%       referência para a especificação dos morfismos, na sua
%%       ausência usa-se o argumento obrigatório para esse efeito, o
%%       argumento obrigatório dá-nos o "conteúdo" do objecto, nos
%%       diagramas comutativos é centrado no ponto dado pelas
%%       coordenadas sendo o argumento seguinte simplesmente ignorado,
%%       nos grafos o "conteúdo" é colocado numa posição a norte, a
%%       noroeste, a este, ..., sendo que a posição concreta é
%%       especificada pelo último dos argumentos deste comando, o
%%       valor por omissão é o "norte".
%%
%% 3/2003 (versão 4.1)
%%       A pedido de Jon Barker <jeb1@soton.ac.uk> criei um novo tipo
%%       de seta, a seta de sobrejecção.
%%       Para já a dupla seta só fica bem nas setas horizontais ou 
%%       verticais.
%% 12/2004 (versão 4.1.1)
%%       Nova versão das setas de sobrejecção que corrigue
%%       completamente os problemas da solução anterior.
%% 3/2007 (versão 4.1.2)
%%       Acrescenta linhas a tracejado e a ponteado
%%-----------------//-------------

\catcode`!=11 %  ***** THIS MUST NEVER BE OMITTED (Ver PiCTeX)

\newcount\aux%
\newcount\auxa%
\newcount\auxb%
\newcount\m%
\newcount\n%
\newcount\x%
\newcount\y%
\newcount\xl%
\newcount\yl%
\newcount\d%
\newcount\dnm%
\newcount\xa%
\newcount\xb%
\newcount\xmed%
\newcount\xc%
\newcount\xd%
\newcount\ya%
\newcount\yb%
\newcount\ymed%
\newcount\yc%
\newcount\yd
%% "variáveis globais"
\newcount\expansao%
\newcount\tipografo%       versão 4.0
\newcount\distanciaobjmor% versão 4.0
\newcount\tipoarco%        versão 4.0
%\newif\ifarredondada%        versão 4.0 (valor inicial "false")
\newif\ifpara%
%% version 3.2
\newbox\caixa%
\newbox\caixaaux%
\newif\ifnvazia%
\newif\ifvazia%
\newif\ifcompara%
\newif\ifdiferentes%
\newcount\xaux%
\newcount\yaux%
\newcount\guardaauxa%
\newcount\alt%
\newcount\larg%
\newcount\prof%
%% para os ajustes
\newcount\auxqx
\newcount\auxqy
\newif\ifajusta%
\newif\ifajustadist
\def\objPartida{}%
\def\objChegada{}%
\def\objNulo{}%


%% 
%% Stack specification
%%

%%
%% Emtpy stack
%%
\def\!vazia{:}

%%
%% Is Empty? : Stack -> Bool
%%
%% nvazia - True if Not Empy
%% vazia  - True if Empty
\def\!pilhanvazia#1{\let\arg=#1%
\if:\arg\ \nvaziafalse\vaziatrue \else \nvaziatrue\vaziafalse\fi}

%%
%% Push : Elems x Stack -> Stack
%%
\def\!coloca#1#2{\edef\pilha{#1.#2}}

%%
%% Top : Stack -> Elems
%%
%% the empty stack is not taken care
%% the element is "kept" ("guardado") 
\def\!guarda(#1)(#2,#3)(#4,#5,#6){\def\id{#1}%
\xaux=#2%
\yaux=#3%
\alt=#4%
\larg=#5%
\prof=#6%
}

\def\!topaux#1.#2:{\!guarda#1}
\def\!topo#1{\expandafter\!topaux#1}

%%
%% Pop : Stack -> Stack
%%
%% the empty stack is not taken care
\def\!popaux#1.#2:{\def\pilha{#2:}}
\def\!retira#1{\expandafter\!popaux#1}

%%
%% Compares words : Word x Word -> Bool
%%
%% compara - True if equal
%% diferentes - True if not equal
\def\!comparaaux#1#2{\let\argA=#1\let\argB=#2%
\ifx\argA\argB\comparatrue\diferentesfalse\else\comparafalse\diferentestrue\fi}

\def\!compara#1#2{\!comparaaux{#1}{#2}}

%%Comando Interno
%% Valor absoluto (absolute value)
%% \absoluto{n}{absn}
%% entrada
%%  n - natural
%% sa{\'\i}da
%%  absn - o valor absoluto de n
\def\!absoluto#1#2{\n=#1%
  \ifnum \n > 0
    #2=\n
  \else
    \multiply \n by -1
    #2=\n
  \fi}


%% Name definitions for edge types and directions
\def\solidarrow{0}
\def\dasharrow{1}
\def\solidline{2}
\def\dashline{3}
\def\dotline{4}
\def\injectionarrow{5}
\def\aplicationarrow{6}
\def\surjectivearrow{7}
%% Name definitions for edge label placement
\def\atright{-1}
\def\atleft{1}
%% Tip direction for curved edges
\def\pup{0}
\def\pdown{1}
\def\pright{2}
\def\pleft{3}
%% Type of graph
\def\commdiag{0}
\def\digraph{1}
\def\undigraph{2}
\def\cdigraph{3}
\def\cundigraph{4}
%% Posicionamento da etiquetas nos grafos
\def\pcent{0}
\def\north{1}
\def\northeast{2}
\def\east{3}
\def\southeast{4}
\def\south{5}
\def\southwest{6}
\def\west{7}
\def\northwest{8}



%%Comando Interno
%% Ajusta a dist{\^a}ncia entre as setas e os objectos em fun{\c c}{\~a}o das
%% dimens{\~o}es destes {\'u}ltimos
%% \ajusta{x}{xl}{y}{yl}{d}{Objecto}
%% entrada
%%  (x,y) e (xl,yl), coordenadas dos pontos de {\'\i}nicio e fim da seta
%%  d, dist{\^a}ncia especificada pelo utilizador ou 10 (valor por
%%  omiss{\~a}o), Objecto d{\'a}-nos a refer{\^e}ncia do objecto ao qual se est{\'a} a
%%  efectuar o ajuste.
%% sa{\'\i}da
%%  d, dist{\^a}ncia alterada.
%% 
%% A dist{\^a}ncia alterada {\'e} o maior valor entre 10 e as dimens{\~o}es
%% apropriadas da caixa que cont{\^e}m o objecto. 
%% Se o utilizador especificar um valor essa especifica{\c c}{\~a}o
%% n{\~a}o {\'e} alterada.
%%
%% Se a seta {\'e} horizontal usa-se o valor da largura
%% Se a seta {\'e} vertical usa-se:
%%  o valor da altura se a seta est{\'a} no 1o ou 2o quadrante
%%  o valor da profundidade se a seta est{\'a} no 3o ou 4o quadrante
%% Se a seta {\'e} {\'o}bliqua vai-se escolher o valor conforme:
%%  de 315 a  45 graus usa-se a largura
%%  de  45 a 135 graus usa-se a altura
%%  de 135 a 225 graus usa-se a largura
%%  de 225 a 315 graus usa-se a profundidade
\def\!ajusta#1#2#3#4#5#6{\aux=#5%
  \let\auxobj=#6%
  \ifcase \tipografo    % diagramas comutativos
    \ifnum\number\aux=10 
      \ajustadisttrue % se o valor é o valor por omissão ajusta
    \else
      \ajustadistfalse  % caso contrário não ajusta
    \fi
  \else  % grafos (dirigidos, não dirigidos, com molduras)
   \ajustadistfalse
%  \or  % grafos não dirigidos
%   \ajustadistfalse
%  \else % grafos dirigidos com molduras circulares nos objectos
%    \ifnum\number\aux=8 
%      \ajustadisttrue  % se o valor é o valor por omissão ajusta
%    \else
%      \ajustadistfalse % caso contrário não ajusta
%    \fi
  \fi
  \ifajustadist
%  \tiny Vou ajustar %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  \ifnum\number\aux=10% verificar se s{\~a}o os valores por omiss{\~a}o
   \let\pilhaaux=\pilha%
   \loop%
     \!topo{\pilha}%
     \!retira{\pilha}%
     \!compara{\id}{\auxobj}%
     \ifcompara\nvaziafalse \else\!pilhanvazia\pilha \fi%
     \ifnvazia%
   \repeat%
%% rep{\~o}e os valores na pilha
   \let\pilha=\pilhaaux%
   \ifvazia%
    \ifdiferentes%
%%
%% N{\~a}o {\'e} poss{\'\i}vel efectuar o ajuste dado o utilizador n{\~a}o ter
%% especificado uma etiqueta para o objecto em quest{\~a}o. {\'E} dado o
%% valor de 10, igual ao valor por omiss{\~a}o.
%%
     \larg=1310720% n{\~a}o faz o ajuste
     \prof=655360%
     \alt=655360%
    \fi%
   \fi%
   \divide\larg by 131072
   \divide\prof by 65536
   \divide\alt by 65536
   \ifnum\number\y=\number\yl
%% Caso 1 -- seta horizontal
%%
%% divide-se por 131072 para se obter metade da largura da caixa em
%% pontos (pt), isto dado que o texto est{\'a} centrado na caixa. Soma-se
%% mais tr{\^e}s, que constitue um ajuste imp{\'\i}rico.
    \advance\larg by 3
    \ifnum\number\larg>\aux
     #5=\larg
    \fi
   \else
    \ifnum\number\x=\number\xl
     \ifnum\number\yl>\number\y
%% Caso 2.1 -- seta vertical de cima para baixa
%%
      \ifnum\number\alt>\aux
       #5=\alt
      \fi
     \else
%% Caso 2.2 -- seta vertical de baixo para cima
%%
%% divide-se por 65536 para se obter a altura da caixa em pt. O ajuste
%% de 5 foi obtido imp{\'\i}ricamente
      \advance\prof by 5
      \ifnum\number\prof>\aux
       #5=\prof
      \fi
     \fi
    \else
%% Caso 3 -- seta obl{\'\i}qua 
%% Caso 3.1 de 315o a  45o; |x-xl|>|y-yl| e
%% Caso 3.3 de 135o a 225o; |x-xl|>|y-yl|; Largura
     \auxqx=\x
     \advance\auxqx by -\xl
     \!absoluto{\auxqx}{\auxqx}%
     \auxqy=\y
     \advance\auxqy by -\yl
     \!absoluto{\auxqy}{\auxqy}%
     \ifnum\auxqx>\auxqy
      \ifnum\larg<10
       \larg=10
      \fi
      \advance\larg by 3
      #5=\larg
     \else
%% Caso 3.2 de  45o a 135o; |x-xl|<|y-yl| e y>0; Largura
      \ifnum\yl>\y
       \ifnum\larg<10
        \larg=10
       \fi
      \advance\alt by 6
       #5=\alt
      \else
%% Caso 3.4 de 225o a 315o; |x-xl|<|y-yl| e y<0; Profundidade
      \advance\prof by 11
       #5=\prof
      \fi
     \fi
    \fi
   \fi
\fi} % o ramo "else" {\'e} omisso


%%Comando Interno
%% C{\'a}lculo da Raiz Quadrada
%% raiz{n}{m}
%% entrada
%%   n - natural
%% sa{\'\i}da
%%   n - natural
%%   m - maior natural contido na raiz quadrada de n
\def\!raiz#1#2{\n=#1%
  \m=1%
  \loop
    \aux=\m%
    \advance \aux by 1%
    \multiply \aux by \aux%
    \ifnum \aux < \n%
      \advance \m by 1%
      \paratrue%
    \else\ifnum \aux=\n%
      \advance \m by 1%
      \paratrue%
       \else\parafalse%
       \fi
    \fi
  \ifpara%
  \repeat
#2=\m}

%%Comando Interno
%% Calcula os pontos de 
%%       come{\c c}o da "seta"
%%       fim da "seta"
%%   coloca{\c c}{\~a}o do s{\'\i}mbolo
%% 
%% ucoord{x1}{x2}{x3}{x4}{x5}{x6}{+|- 1}
%% entrada
%%   x1,x2,x3,x4,x5
%% sa{\'\i}da
%%   x6
%%  
%%              x2 - x1
%%  x6 = x3 +|- ------- x4
%%                 x5
\def\!ucoord#1#2#3#4#5#6#7{\aux=#2%
  \advance \aux by -#1%
  \multiply \aux by #4%
  \divide \aux by #5%
  \ifnum #7 = -1 \multiply \aux by -1 \fi%
  \advance \aux by #3%
#6=\aux}

%%Comando Interno 
%% C{\'a}lculo do Quadrado da Dist{\^a}ncia Euclidiana entre dois pontos 
%% quadrado{n}{m}{l}
%% entrada
%%   n - natural
%%   m - natural
%% sa{\'\i}da
%%   l = (n-m)*(n-m)
\def\!quadrado#1#2#3{\aux=#1%
  \advance \aux by -#2%
  \multiply \aux by \aux%
#3=\aux}

%%Comando Interno
%% C{\'a}lculo auxiliar para determinar a dist{\^a}ncia entre o nome do
%% morfismo e a seta.
%% entrada
%%     (x,y), (x',y') e o nome do morfismo
%% sa{\'\i}da
%%     dnm - dist{\^a}ncia do nome ao morfismo respectivo devidamente
%%     compensada pelo tamanho do objecto
%% Observa{\c c}{\~o}es
%%     A compensa{\c c}{\~a}o s{\'o} est{\'a} a ser feita para setas
%%     horizontais e verticais. As obl{\'\i}quas s{\~a}o tratadas de
%%     outra forma.
%% algoritmo
%%  caixa0 <- nome do morfismo
%%  se x-xl = 0 entao                   {recta vertical}
%%     aux <- largura da caixa0
%%     dnm <- convers{\~a}o-sp-pt(aux)/2+3
%%  sen{\~a}o                               {recta n{\~a}o vertical}
%%     se y-yl = 0 entao                {recta horizontal}
%%        aux <- altura+profundidade da caixa0
%%        dnm <- convers{\~a}o-sp-pt(aux)/2+3
%%     sen{\~a}o                            {recta obl{\'\i}qua}
%%        dnm <- 3
%%     fimse
%%  fimse
%% fimalgoritmo
\def\!distnomemor#1#2#3#4#5#6{\setbox0=\hbox{#5}%
  \aux=#1
  \advance \aux by -#3
  \ifnum \aux=0
     \aux=\wd0 \divide \aux by 131072
     \advance \aux by 3
     #6=\aux
  \else
     \aux=#2
     \advance \aux by -#4
     \ifnum \aux=0
        \aux=\ht0 \advance \aux by \dp0 \divide \aux by 131072
        \advance \aux by 3
        #6=\aux%
     \else
     #6=3
     \fi
   \fi
}


%%
%% O ambiente "begindc...enddc"
%%
\def\begindc#1{\!ifnextchar[{\!begindc{#1}}{\!begindc{#1}[30]}}
\def\!begindc#1[#2]{\beginpicture 
  \let\pilha=\!vazia
  \setcoordinatesystem units <1pt,1pt>
  \expansao=#2
  \ifcase #1
    \distanciaobjmor=10
    \tipoarco=0         % seta
    \tipografo=0        % diagrama comutativo
  \or
    \distanciaobjmor=2
    \tipoarco=0         % seta 
    \tipografo=1        % grafo orientado
  \or
    \distanciaobjmor=1
    \tipoarco=2         % linha
    \tipografo=2        % grafo não orientado
  \or
    \distanciaobjmor=8
    \tipoarco=0         % seta 
    \tipografo=3        % grafo orientado
%    \arredondadotrue    % objectos com molduras circulares
  \or
    \distanciaobjmor=8
    \tipoarco=2         % linha
    \tipografo=4        % grafo não orientado
%    \arredondadotrue    % objectos com molduras circulares
  \fi}

\def\enddc{\endpicture}


%%
%% Comando para construir a "seta" entre dois objectos
%%
%% Os pontos definidores da seta e da etiqueta respectiva s{\~a}o:
%% 
%%                (xd,yd)
%%                   o
%%                   |
%%  o------o---------o---------o------o
%%(x,y) (xa,ya)   (xm,ym)   (xb,yb)(xl,yl)
%%
\def\mor{%
  \!ifnextchar({\!morxy}{\!morObjA}}
\def\!morxy(#1,#2){%
  \!ifnextchar({\!morxyl{#1}{#2}}{\!morObjB{#1}{#2}}}
\def\!morxyl#1#2(#3,#4){%
  \!ifnextchar[{\!mora{#1}{#2}{#3}{#4}}{\!mora{#1}{#2}{#3}{#4}[\number\distanciaobjmor,\number\distanciaobjmor]}}%
\def\!morObjA#1{%
 \let\pilhaaux=\pilha%
 \def\objPartida{#1}%
 \loop%
    \!topo\pilha%
    \!retira\pilha%
    \!compara{\id}{\objPartida}%
    \ifcompara \nvaziafalse \else \!pilhanvazia\pilha \fi%
   \ifnvazia%
 \repeat%
 \ifvazia%
  \ifdiferentes%
%%
%% Mensagem de erro e atribui{\c c}{\~a}o de valores fict{\'\i}cios aos 
%% argumentos dos comandos que se seguem.
%%
   Error: Incorrect label specification%
   \xaux=1%
   \yaux=1%
  \fi%
 \fi% 
 \let\pilha=\pilhaaux%
 \!ifnextchar({\!morxyl{\number\xaux}{\number\yaux}}{\!morObjB{\number\xaux}{\number\yaux}}}
\def\!morObjB#1#2#3{%
  \x=#1
  \y=#2
 \def\objChegada{#3}%
 \let\pilhaaux=\pilha%
 \loop
    \!topo\pilha %
    \!retira\pilha%
    \!compara{\id}{\objChegada}%
    \ifcompara \nvaziafalse \else \!pilhanvazia\pilha \fi
   \ifnvazia
 \repeat
 \ifvazia
  \ifdiferentes%
%%
%% Mensagem de erro e atribui{\c c}{\~a}o de valores fict{\'\i}cios aos 
%% argumentos dos comandos que se seguem.
%%
   Error: Incorrect label specification
   \xaux=\x%
   \advance\xaux by \x%
   \yaux=\y%
   \advance\yaux by \y%
  \fi
 \fi
 \let\pilha=\pilhaaux
 \!ifnextchar[{\!mora{\number\x}{\number\y}{\number\xaux}{\number\yaux}}{\!mora{\number\x}{\number\y}{\number\xaux}{\number\yaux}[\number\distanciaobjmor,\number\distanciaobjmor]}}
\def\!mora#1#2#3#4[#5,#6]#7{%
  \!ifnextchar[{\!morb{#1}{#2}{#3}{#4}{#5}{#6}{#7}}{\!morb{#1}{#2}{#3}{#4}{#5}{#6}{#7}[1,\number\tipoarco] }}
\def\!morb#1#2#3#4#5#6#7[#8,#9]{\x=#1%
  \y=#2%
  \xl=#3%
  \yl=#4%
  \multiply \x by \expansao%
  \multiply \y by \expansao%
  \multiply \xl by \expansao%
  \multiply \yl by \expansao%
%%
%% calcular a dist{\^a}ncia Euclidiana entre dois pontos
%% d = \sqrt((x-xl)^2+(y-yl)^2)
%%
  \!quadrado{\number\x}{\number\xl}{\auxa}%
  \!quadrado{\number\y}{\number\yl}{\auxb}%
  \d=\auxa%
  \advance \d by \auxb%
  \!raiz{\d}{\d}%
%%
%% o ponto (xa,ya) est{\'a} {\`a} dist{\^a}ncia #5 (valor por omiss{\~a}o 10) do ponto
%% (x,y)
%%
%% como existem dois pontos em considera{\c c}{\~a}o, o ponto de partida e o
%% ponto de chegada, vai sei necess{\'a}rio recuperar de novo os seus
%% valores por pesquisa na pilha
  \auxa=#5
  \!compara{\objNulo}{\objPartida}%
  \ifdiferentes% S{\'o} vai fazer o ajuste quando {\'e} necess{\'a}rio
   \!ajusta{\x}{\xl}{\y}{\yl}{\auxa}{\objPartida}%
   \ajustatrue
   \def\objPartida{}% re-inicializar o valor do Objecto de Partida
  \fi
%% vai guardar o valor de auxa (ap{\'o}s ajuste) para ser usado no caso
%% dos morfismos de injec{\c c}{\~a}o.
  \guardaauxa=\auxa
%%
  \!ucoord{\number\x}{\number\xl}{\number\x}{\auxa}{\number\d}{\xa}{1}%
  \!ucoord{\number\y}{\number\yl}{\number\y}{\auxa}{\number\d}{\ya}{1}%
%% auxa vai ter o valor da dist{\^a}ncia entre os objectos menos a
%% dist{\^a}ncia da seta ao objecto (10 por omiss{\~a}o)
  \auxa=\d%
%%
%% o ponto (xb,yb) est{\'a} {\`a} dist{\^a}ncia #6 (valor por omiss{\~a}o 10) do ponto
%% (xl,yl)
%%
  \auxb=#6
  \!compara{\objNulo}{\objChegada}%
  \ifdiferentes% S{\'o} vai fazer o ajuste quando {\'e} necess{\'a}rio
%   Vou ajustar
   \!ajusta{\x}{\xl}{\y}{\yl}{\auxb}{\objChegada}%
   \def\objChegada{}% re-inicializar o valor do Objecto de Chegada
  \fi
  \advance \auxa by -\auxb%
  \!ucoord{\number\x}{\number\xl}{\number\x}{\number\auxa}{\number\d}{\xb}{1}%
  \!ucoord{\number\y}{\number\yl}{\number\y}{\number\auxa}{\number\d}{\yb}{1}%
  \xmed=\xa%
  \advance \xmed by \xb%
  \divide \xmed by 2
  \ymed=\ya%
  \advance \ymed by \yb%
  \divide \ymed by 2
%%
%% 
  \!distnomemor{\number\x}{\number\y}{\number\xl}{\number\yl}{#7}{\dnm}%
  \!ucoord{\number\y}{\number\yl}{\number\xmed}{\number\dnm}{\number\d}{\xc}{-#8}% 
  \!ucoord{\number\x}{\number\xl}{\number\ymed}{\number\dnm}{\number\d}{\yc}{#8}%
\ifcase #9            % Seta S{\'o}lida
  \arrow <4pt> [.2,1.1] from {\xa} {\ya} to {\xb} {\yb}
\or                   % Seta a Tracejado
  \setdashes
  \arrow <4pt> [.2,1.1] from {\xa} {\ya} to {\xb} {\yb}
  \setsolid
\or                   % Linha S{\'o}lida
  \setlinear
  \plot {\xa} {\ya}  {\xb} {\yb} /
\or                   % Linha Tracejado
  \setdashes
  \setlinear
  \plot {\xa} {\ya}  {\xb} {\yb} /
  \setsolid
\or                   % Linha a Ponteado
  \setdots
  \setlinear
  \plot {\xa} {\ya}  {\xb} {\yb} /
  \setsolid
\or                   % Seta de Injec{\c c}{\~a}o
%% C{\'a}lculos auxiliares
%%
%% 3 valor para o raio do "rabo" da "seta"
%%
%% repor o valor de auxa
  \auxa=\guardaauxa
%% dar a compensa{\c c}{\~a}o para o "rabo"
  \advance \auxa by 3%
%%
%% IMPORTANTE os valores de xa e ya v{\~a}o ser alterados
%%
 \!ucoord{\number\x}{\number\xl}{\number\x}{\number\auxa}{\number\d}{\xa}{1}%
 \!ucoord{\number\y}{\number\yl}{\number\y}{\number\auxa}{\number\d}{\ya}{1}%
 \!ucoord{\number\y}{\number\yl}{\number\xa}{3}{\number\d}{\xd}{-1}%
 \!ucoord{\number\x}{\number\xl}{\number\ya}{3}{\number\d}{\yd}{1}%
%% Constru{\c c}{\~a}o da "seta"
  \arrow <4pt> [.2,1.1] from {\xa} {\ya} to {\xb} {\yb}
%% e do seu "rabo"
  \circulararc -180 degrees from {\xa} {\ya} center at {\xd} {\yd}
\or                   % Seta de Aplica{\c c}{\~a}o ("|-->")
  \auxa=3% valor para o meio-segmento do "rabo" da "seta"
%% c{\'a}lculo dos pontos (xmed,ymed) e (xd,yd) para o segmento de recta que
%% define o "rabo" da seta
 \!ucoord{\number\y}{\number\yl}{\number\xa}{\number\auxa}{\number\d}{\xmed}{-1}%
 \!ucoord{\number\x}{\number\xl}{\number\ya}{\number\auxa}{\number\d}{\ymed}{1}%
 \!ucoord{\number\y}{\number\yl}{\number\xa}{\number\auxa}{\number\d}{\xd}{1}%
 \!ucoord{\number\x}{\number\xl}{\number\ya}{\number\auxa}{\number\d}{\yd}{-1}%
%% Constru{\c c}{\~a}o da "seta"
  \arrow <4pt> [.2,1.1] from {\xa} {\ya} to {\xb} {\yb}
%% e do seu "rabo"
  \setlinear
  \plot {\xmed} {\ymed}  {\xd} {\yd} /
\or                   % Seta de Sobrejec{\c c}{\~a}o ("-->>")
  \arrow <4pt> [.2,1.1] from {\xa} {\ya} to {\xb} {\yb}
%% e da segunda "seta"
  \setlinear
  \arrow <6pt> [0,.72] from {\xa} {\ya} to {\xb} {\yb}
\fi
%% Coloca{\c c}{\~a}o do nome do morfismo.
%% Se os morfismos s{\~a}o horizontais ou verticais constro{\'\i} uma caixa
%% centrada no ponto pr{\'e}viamente calculado. Se as setas s{\~a}o
%% obl{\'\i}quas coloca a caixa de forma a n{\~a}o colidir com o morfismo 
%% tendo em aten{\c c}{\~a}o o quadrante assim como a posi{\c c}{\~a}o
%% relativa do morfismo e do respectivo nome.
\auxa=\xl
\advance \auxa by -\x%
\ifnum \auxa=0 
  \put {#7} at {\xc} {\yc}
\else
  \auxb=\yl
  \advance \auxb by -\y%
  \ifnum \auxb=0 \put {#7} at {\xc} {\yc}
  \else 
    \ifnum \auxa > 0 
      \ifnum \auxb > 0
        \ifnum #8=1
          \put {#7} [rb] at {\xc} {\yc}
        \else 
          \put {#7} [lt] at {\xc} {\yc}
        \fi
      \else
        \ifnum #8=1
          \put {#7} [lb] at {\xc} {\yc}
        \else 
          \put {#7} [rt] at {\xc} {\yc}
        \fi
      \fi
    \else
      \ifnum \auxb > 0 
        \ifnum #8=1
          \put {#7} [rt] at {\xc} {\yc}
        \else 
          \put {#7} [lb] at {\xc} {\yc}
        \fi
      \else
        \ifnum #8=1
          \put {#7} [lt] at {\xc} {\yc}
        \else 
          \put {#7} [rb] at {\xc} {\yc}
        \fi
      \fi
    \fi
  \fi
\fi
}

%%
%% Comando para construir a "seta" curvilinea entre dois objectos
%%
%% \cmor(<lista de pontos (n. impar)>){<etiqueta>}
%%
%% Em primeiro lugar {\'e} necess{\'a}rio modificar o comando plot de forma a
%% que a sintaxe de utiliza{\c c}{\~a}o do novo comando seja coerente com a
%% sintaxe dos restantes comandos
%%
\def\modifplot(#1{\!modifqcurve #1}
\def\!modifqcurve(#1,#2){\x=#1%
  \y=#2%
  \multiply \x by \expansao%
  \multiply \y by \expansao%
  \!start (\x,\y)
  \!modifQjoin}
\def\!modifQjoin(#1,#2)(#3,#4){\x=#1%
  \y=#2%
  \xl=#3%
  \yl=#4%
  \multiply \x by \expansao%
  \multiply \y by \expansao%
  \multiply \xl by \expansao%
  \multiply \yl by \expansao%
  \!qjoin (\x,\y) (\xl,\yl)             % \!qjoin  is defined in QUADRATIC
  \!ifnextchar){\!fim}{\!modifQjoin}}
\def\!fim){\ignorespaces}

%%
%% O comando para desenhar a seta vai receber a lista de pontos da qual
%% retira o {\'u}ltimo par de pontos, dependente da escolha dada pelo
%% utilizador a seta vai ser desenhada para cima, para baixo, para a
%% direita ou para a esquerda
%%
\def\setaxy(#1{\!pontosxy #1}
\def\!pontosxy(#1,#2){%
  \!maispontosxy}
\def\!maispontosxy(#1,#2)(#3,#4){%
  \!ifnextchar){\!fimxy#3,#4}{\!maispontosxy}}
\def\!fimxy#1,#2){\x=#1%
  \y=#2
  \multiply \x by \expansao
  \multiply \y by \expansao
  \xl=\x%
  \yl=\y%
  \aux=1%
  \multiply \aux by \auxa%
  \advance\xl by \aux%
  \aux=1%
  \multiply \aux by \auxb%
  \advance\yl by \aux%
  \arrow <4pt> [.2,1.1] from {\x} {\y} to {\xl} {\yl}}


%%
%% Temos agora a defini{\c c}{\~a}o do comando "cmor"
%%
\def\cmor#1 #2(#3,#4)#5{%
  \!ifnextchar[{\!cmora{#1}{#2}{#3}{#4}{#5}}{\!cmora{#1}{#2}{#3}{#4}{#5}[0] }}
\def\!cmora#1#2#3#4#5[#6]{%
  \ifcase #2% para cima "\pup" (pointing up)
      \auxa=0% x mant{\^e}m-se
      \auxb=1% o y "sobe" 
    \or% para baixo "\pdown" (pointing down)
      \auxa=0% x mant{\^e}m-se
      \auxb=-1% o y "desce" 
    \or% para a direita "\pright" (pointing right)
      \auxa=1% o x move-se para a direita
      \auxb=0% o y mant{\^e}m-se
    \or% para a esquerda "\pleft" (pointing left)
      \auxa=-1% o x move-se para a esquerda
      \auxb=0% o y mant{\^e}m-se
    \fi  % constru{\c c}{\~a}o do arco
  \ifcase #6  % arco (com seta) s{\'o}lido
    \modifplot#1% Desenhar o arco
    % constru{\c c}{\~a}o da seta
    \setaxy#1
  \or  % arco (com seta) a tracejado
    \setdashes
    \modifplot#1% Desenhar o arco
    \setaxy#1
    \setsolid
  \or  % arco sem seta
    \modifplot#1% Desenhar o arco
  \fi  % seta de injec{\c c}{\~a}o
%% coloca{\c c}{\~a}o da etiqueta do morfismo
  \x=#3%  
  \y=#4%
  \multiply \x by \expansao%
  \multiply \y by \expansao%
  \put {#5} at {\x} {\y}}

%%
%% Comando para construir os Objectos
%%  \obj(x,y){<texto>}[<etiqueta>]
%% 
\def\obj(#1,#2){%
  \!ifnextchar[{\!obja{#1}{#2}}{\!obja{#1}{#2}[Nulo]}}
\def\!obja#1#2[#3]#4{%
  \!ifnextchar[{\!objb{#1}{#2}{#3}{#4}}{\!objb{#1}{#2}{#3}{#4}[1]}}
\def\!objb#1#2#3#4[#5]{%
  \x=#1%
  \y=#2%
  \def\!pinta{\normalsize$\bullet$}% para definir o tamanho normal das pintas
  \def\!nulo{Nulo}%
  \def\!arg{#3}%
  \!compara{\!arg}{\!nulo}%
  \ifcompara\def\!arg{#4}\fi%
  \multiply \x by \expansao%
  \multiply \y by \expansao%
  \setbox\caixa=\hbox{#4}%
  \!coloca{(\!arg)(#1,#2)(\number\ht\caixa,\number\wd\caixa,\number\dp\caixa)}{\pilha}%
  \auxa=\wd\caixa \divide \auxa by 131072 
  \advance \auxa by 5
  \auxb=\ht\caixa
  \advance \auxb by \number\dp\caixa
  \divide \auxb by 131072 
  \advance \auxb by 5
%(\number\auxa,
%\number\auxb)
%  \aux=\ht\caixa \divide \auxa by 131072 
% \advance \auxa by 5 
%  \auxb=\dp\caixa \divide \auxb by 131072 
%  \advance \auxb by 8
  \ifcase \tipografo    % diagramas comutativos
    \put{#4} at {\x} {\y}
  \or                   % grafos dirigidos
    \ifcase #5 % c=0
      \put{#4} at {\x} {\y}
    \or        % n=1
      \put{\!pinta} at {\x} {\y}
      \advance \y by \number\auxb  % height+depth+5
      \put{#4} at {\x} {\y}
    \or        % ne=2
      \put{\!pinta} at {\x} {\y}
      \advance \auxa by -2  % para fazer o ajuste (imperfeito)
      \advance \auxb by -2  % ao raio da circunferência de centro (x,y)
      \advance \x by \number\auxa  % width+5
      \advance \y by \number\auxb  % height+depth+5
      \put{#4} at {\x} {\y}   
    \or        % e=3
      \put{\!pinta} at {\x} {\y}
      \advance \x by \number\auxa  % width+5
      \put{#4} at {\x} {\y}   
    \or        % se=4
      \put{\!pinta} at {\x} {\y}
      \advance \auxa by -2  % para fazer o ajuste (imperfeito)
      \advance \auxb by -2  % ao raio da circunferência de centro (x,y)
      \advance \x by \number\auxa  % width+5
      \advance \y by -\number\auxb  % height+depth+5
      \put{#4} at {\x} {\y}   
    \or        % s=5
      \put{\!pinta} at {\x} {\y}
      \advance \y by -\number\auxb  % height+depth+5
      \put{#4} at {\x} {\y}   
    \or        % sw=6
      \put{\!pinta} at {\x} {\y}
      \advance \auxa by -2  % para fazer o ajuste (imperfeito)
      \advance \auxb by -2  % ao raio da circunferência de centro (x,y)
      \advance \x by -\number\auxa  % width+5
      \advance \y by -\number\auxb  % height+depth+5
      \put{#4} at {\x} {\y}   
    \or        % w=7
      \put{\!pinta} at {\x} {\y}
      \advance \x by -\number\auxa  % width+5
      \put{#4} at {\x} {\y}   
    \or        % nw=8
      \put{\!pinta} at {\x} {\y}
      \advance \auxa by -2  % para fazer o ajuste (imperfeito)
      \advance \auxb by -2  % ao raio da circunferência de centro (x,y)
      \advance \x by -\number\auxa  % width+5
      \advance \y by \number\auxb  % height+depth+5
      \put{#4} at {\x} {\y}   
    \fi
  \or                   % grafos não dirigidos
    \ifcase #5 % c=0
      \put{#4} at {\x} {\y}
    \or        % n=1
      \put{\!pinta} at {\x} {\y}
      \advance \y by \number\auxb  % height+depth+5
      \put{#4} at {\x} {\y}
    \or        % ne=2
      \put{\!pinta} at {\x} {\y}
      \advance \auxa by -2  % para fazer o ajuste (imperfeito)
      \advance \auxb by -2  % ao raio da circunferência de centro (x,y)
      \advance \x by \number\auxa  % width+5
      \advance \y by \number\auxb  % height+depth+5
      \put{#4} at {\x} {\y}   
    \or        % e=3
      \put{\!pinta} at {\x} {\y}
      \advance \x by \number\auxa  % width+5
      \put{#4} at {\x} {\y}   
    \or        % se=4
      \put{\!pinta} at {\x} {\y}
      \advance \auxa by -2  % ver acima
      \advance \auxb by -2
      \advance \x by \number\auxa  % width+5
      \advance \y by -\number\auxb % height+depth+5
      \put{#4} at {\x} {\y}   
    \or        % s=5
      \put{\!pinta} at {\x} {\y}
      \advance \y by -\number\auxb % height+depth+5
      \put{#4} at {\x} {\y}   
    \or        % sw=6
      \put{\!pinta} at {\x} {\y}
      \advance \auxa by -2  % ver acima
      \advance \auxb by -2
      \advance \x by -\number\auxa % width+5
      \advance \y by -\number\auxb % height+depth+5
      \put{#4} at {\x} {\y}   
    \or        % w=7
      \put{\!pinta} at {\x} {\y}
      \advance \x by -\number\auxa % width+5
      \put{#4} at {\x} {\y}   
    \or        % nw=8
      \put{\!pinta} at {\x} {\y}
      \advance \auxa by -2  % ver acima
      \advance \auxb by -2
      \advance \x by -\number\auxa % width+5
      \advance \y by \number\auxb  % height+depth+5
      \put{#4} at {\x} {\y}   
    \fi
%  \or % grafos dirigidos com molduras circulares nos objectos
%    \advance \auxa by 4
%    \put{\circle{\auxa}} [Bl] at {\x} {\y}
%    \put{#4} at {\x} {\y}
%  \or % grafos não dirigidos com molduras circulares nos objectos
   \else % grafos com molduras circulares nos objectos
     \ifnum\auxa<\auxb % determina a maior das dimensões
       \aux=\auxb
     \else
       \aux=\auxa
     \fi
% se a largura da caixa é menor do que 1em então o tamanho 
% tamanho é ajustado para esse valor mínimo
     \ifdim\wd\caixa<1em
       \dimen99 = 1em
       \aux=\dimen99 \divide \aux by 131072 
       \advance \aux by 5
     \fi
     \advance\aux by -2 %folga entre o objecto e a moldura
     \multiply\aux by 2 % 
     \ifnum\aux<30
       \put{\circle{\aux}} [Bl] at {\x} {\y}
     \else
       \multiply\auxa by 2
       \multiply\auxb by 2
       \put{\oval(\auxa,\auxb)} [Bl] at {\x} {\y}
     \fi
     \put{#4} at {\x} {\y}
   \fi   
}


\catcode`!=12 %  *****  THIS MUST NEVER BE OMITTED (Ver PiCTeX)
