19 octubre 2007

Dibujando con la clase TCanvas (I)

La unidad Graphics dispone de la clase TCanvas dedicada al dibujo de objetos sobre la superficie de un control visual. Los controles estándar de Windows tales como Edit o Listbox no requieren canvas, ya que son dibujados por el sistema operativo.


Un objeto Canvas proporciona propiedades, métodos y eventos para realizar tareas como pueden ser:

- Escribir texto especificando fuente, color y estilo.

- Copiar imágenes de una superficie a otra.

- Dibujar líneas, rectángulos y circulos con distintos patrones de color y estilo.

- Leer y modificar cada pixel de la imagen dibujada.

COMO DIBUJAR UN RECTANGULO

Antes de dibujar una figura se pueden seleccionar los colores del margen y de fondo. Supongamos que quiero hacer un rectángulo con un marco de 3 pixels de ancho y de color rojo. El fondo va a ser de color azul. Para ello nos vamos al evento OnPaint del formulario y escribimos lo siguiente:

procedure TFormulario.FormPaint( Sender: TObject );
begin
with Canvas do
begin
Pen.Color := clRed;
Pen.Width := 3;
Brush.Color := clBlue;
Rectangle( 10, 10, 110, 110 );
end;
end;

El resultado es el siguiente:


Hemos utilizado la propiedad Pen para seleccionar el color del marco y su ancho. Con la propiedad Brush establecemos el color de fondo del rectángulo. Y mediante el procedimiento Rectangle hemos dibujado un rectángulo en la posición x = 10 e y = 10 teniendo un ancho y alto de 100x100. El procedimiento Rectangle tiene los siguientes parámetros:

procedure Rectangle( X1, Y1, X2, Y2: Integer );
procedure Rectangle( const Rect: TRect );

X1, Y1 -> Son las coordenadas de la esquina superior izquierda del rectángulo
X2, Y2 -> Son las coordenadas de la esquina inferior derecha del rectángulo

También se podría haber utilizado la estructura de datos TRect (rectángulo) para dibujar el rectángulo del siguiente modo:

var
R: TRect;
begin
with Canvas do
begin
Pen.Color := clRed;
Pen.Width := 3;
Brush.Color := clBlue;
R.Left := 10;
R.Top := 10;
R.Right := 110;
R.Bottom := 110;
Rectangle( R );
end;
end;

La estructura TRect esta definida dentro de la unidad Type del siguiente modo:

TRect = packed record
case Integer of
0: (Left, Top, Right, Bottom: Integer);
1: (TopLeft, BottomRight: TPoint);
end;

donde los valores Left y Top determinan la posición superior izquierda del rectángulo y los valores Right y Bottom la esquina inferior derecha.

También existe otro procedimiento para hacer rectángulos sólo con fondo (sin borde) utilizando el procedimiento:

procedure FillRect( const Rect: TRect );

Si lo hubiésemos utilizado este procedimiento sólo tendríamos un rectángulo con fondo azul. Lo único que tiene en cuenta es la propiedad Brush ignorando el valor de Pen.

Para el caso anterior no es necesario utilizar la estructura TRect, pero si se van a dibujar muchos rectángulos utilizando las mismas rutinas si es interesante utilizarla, evitándonos el tener que declarar las variables x1, y1, x2, y2 para las coordenadas. La estructura TRect es de uso general y no tiene porque estar asociada sólo al dibujo de rectángulos como veremos más adelante.

Las propiedades Pen y Brush son permantentes, es decir, que mientras no se modifiquen todo lo que se dibuje posteriormente tendrá los colores y estilo especificado por ambas. Si las figuras que se van a dibujar tienen mismo color de borde y fondo no es necesario especificar de nuevo el valor de Pen y Brush.

DIBUJANDO UN RECTANGULO CON ESQUINAS REDONDEADAS

Mediante el método RoundRect se pueden crear rectángulos con esquinas suavizadas. Veamos un ejemplo:

with Canvas do
begin
Pen.Color := clGray;
Pen.Width := 3;
Brush.Color := clWhite;
RoundRect( 300, 150, 380, 200, 30, 30 );
end;

Cuyo resultado sería:

El procedimiento RoundRect tiene los siguientes parámetros:

procedure RoundRect( X1, Y1, X2, Y2, X3, Y3: Integer );

donde:

X1, Y1 -> Son las coordenadas de la esquina superior izquierda
X2, Y2 -> Son las coordenadas de la esquina inferior derecha
X3, Y3 -> Es grado de redondeo de las esquinas (cuanto más grande más redondeado)

COMO DIBUJAR UN CIRCULO

Para dibujar un círculo se utiliza el procedimiento Ellipse. Vamos a dibujar un círculo con un borde de color azul oscuro y un fondo de color amarillo:

with Canvas do
begin
Pen.Color := clNavy;
Pen.Width := 5;
Brush.Color := clYellow;
Brush.Style := bsDiagCross;
Ellipse( 160, 10, 260, 110 );
end;

Quedaría así:


A la propiedad Brush le he especificado que me dibuje el fondo amarillo utilizando un patrón de líneas cruzadas diagonales. Al igual que el procedimiento Rectangle, el procedimiento Ellipse utiliza los mismos parámetros:

procedure Ellipse( X1, Y1, X2, Y2: Integer );
procedure Ellipse( const Rect: TRect );

En este otro ejemplo voy a dibujar un círculo chafado horizontalmente (una elipse) con un borde de 1 pixel de color blanco y un fondo gris:

with Canvas do
begin
Pen.Color := clWhite;
Pen.Width := 1;
Brush.Color := clGray;
Brush.Style := bsSolid;
Ellipse( 300, 10, 330, 110 );
end;

Este sería el resultado:


He tenido que volver a dejar la propiedad Style del Brush con el valor bsSolid para que vuelva a dibujarme el fondo sólido porque sino me lo hubiera hecho con líneas cruzadas como lo dejé anteriormente.

COMO DIBUJAR LINEAS

La clase TCanvas dispone de un puntero invisible donde dibujará las líneas si no se especifica posición. Para modificar la posición de dicho puntero existe el método MoveTo:

procedure MoveTo( X, Y: Integer );

Si queremos averiguar donde se ha quedado el puntero disponemos de la propiedad PenPos que es de tipo TPoint:

type TPoint = packed record
X: Longint;
Y: Longint;
end;

Al igual que la estructura de datos TRect está definida en la unidad Types. Veamos como realizar un triángulo de color negro y sin fondo:

with Canvas do
begin
Pen.Color := clBlack;
Pen.Width := 3;
MoveTo( 50, 150 );
LineTo( 100, 220 );
LineTo( 10, 220 );
LineTo( 50, 150 );
end;

El triángulo quedaría así:

Hemos situado el puntero en un punto y a partir de ahí hemos ido tranzando líneas hasta cerrar el triángulo. En este caso la propiedad Brush no tiene ningún valor para el procedimiento LineTo.

COMO DIBUJAR POLIGONOS

El triángulo que hemos hecho anteriormente también podría haberse realizado mediante un polígono. Además los polígonos permiten especificar el color de fondo mediante la propiedad Brush. Por ejemplo vamos a crear un triángulo con un borde amarillo y fondo de color verde:

var
Puntos: array of TPoint;
begin
with Canvas do
begin
Pen.Color := clYellow;
Pen.Width := 3;
Brush.Color := clGreen;
SetLength( Puntos, 3 );
Puntos[0].x := 150;
Puntos[0].y := 150;
Puntos[1].x := 250;
Puntos[1].y := 200;
Puntos[2].x := 150;
Puntos[2].y := 200;
Polygon( Puntos );
end;
end;

Quedaría así:


He creado un array dinámico del tipo TPoint con una longitud de 3. Después he ido especificando cada punto del polígono (en este caso un triángulo) y por último le paso dicho array al procedimiento Polygon.

En el próximo artículo seguiremos exprimiendo las características del Canvas.

Pruebas realizadas en Delphi 7.

1 comentario:

Anónimo dijo...

buenos datos...
solo q m ayudaria un poco mas
si me mostraras que puntos de la figura se necesitan...
n especial los 4 valores que pide para el circulo....


gracias

Publicidad