Vous êtes sur la page 1sur 9

El Rinconcito de Delphi

Canvas
Nstor Freire
nestorfreire@ElRinconcito.com
El presente artculo pertenece a El Rinconcito de Delphi.
No est permitida su publicacin sin autorizacin expresa.
Canvas

Un lienzo para nuestros dibujos

El Canvas, del tipo TCanvas, es una propiedad que tienen todos los controles que derivan de la
clase TGraphicControl, donde se define por primera vez. Esta palabra, que significa lienzo, nos
permite dibujar sobre ella lneas, rectngulos, textos, BMPs, etc. Es imprescindible en la creacin
de controles visuales, ya que es aqu donde se dibujan. En la mayora de los controles podemos
usarlo sin problemas, pero hay otros que no se dejan. stos, a veces, tienen una propiedad llamada
Style, que tendremos que establecer a xxOwnerDrawFixed o xxOwnerDrawVariable (xx puede
tomar los valores ib, cs, ot... segn el control del que se trate). Tomemos por ejemplo un TListBox.
Si establecemos que sea dibujo fijo (ibOwnerDrawFixed), todos las lneas tendrn el mismo ancho,
largo, altura, etc. En cambio, en el dibujo variable (ibOwnerDrawVariable), en cada elemento
Delphi nos pregunta por su tamao. En el momento en que se vaya a dibujar dicho elemento, se
activa el OnMeasureItem, que nos pregunta por el tamao (si estamos en dibujo variable) y
seguidamente entra en OnDrawItem, que ser donde lo dibujemos realmente. Si preferimos un lugar
para dibujar nosotros solos, podemos usar el TImage, o, an mejor, el TPaintBox.

Para que nuestros dibujos nos queden como queremos, hay tres propiedades esenciales: TFont,
TPen y TBrush. La primera es la conocida propiedad para el texto, en la que establecemos su
tamao, tipo, color, etc. La propiedad Color es del tipo TColor y admite colores predefinidos (por
ejemplo : clBlue, clRed ) o un Valor en hexadecimal que represente el color. Este tendr la forma
$00bbggrr. El smbolo del dlar ($) indica que se trata de un hexadecimal. Los dos siguientes ceros
estn ah en todos los colores, sin que cumplan ninguna funcin (aparte de hacer que el nmero
tenga ocho cifras en total). Despus se sitan los valores del azul (bb), verde (gg) y rojo (rr) que
compongan el color. Estos valores sern en hexadecimal, por supuesto, y tomarn un valor entre
cero (00) y 255 (FF). Sin embargo es ms fcil usar la funcin RGB.

La siguiente propiedad de la fuente es Height, que indica el ancho de las letras. Esto est
relacionado con Size, el tamao total. La frmula que las relaciona es:

Font.Size = -Font.Height * 72 / Font.PixelsPerInch

O lo que es lo mismo:

Font.Height = -Font.Size * Font.PixelsPerInch / 72

La propiedad Name indica la fuente que se est usando, siendo la normal MS Sans Serif, pero
puede tomar el nombre de cualquiera que haya instalado en Windows. Para obtener las fuentes
disponibles, debe usar la propiedad Screen.Fonts, donde estn listadas. Si las quiere incluir todas en
una lista hay un procedimiento bastante rpido:

var
ListFonts : TStrings;
begin
ListFonts := Screen.Fonts;
ListaFuentes.Items := ListFonts;
end;

La ltima propiedad de Font es Style, donde indica cmo se dibujar. Puede tomar una
combinacin de: fsBold: Negrita, fsItalic: Cursiva, fsUnderline: Subrayada y fsStrikeOut: Tachada.
Para aadir o quitar algunos de ellos se hace de la siguiente forma:

TCanvas.Font.Style := TCanvas.Font.Style + [fsBold]; //(Por ejemplo)

TCanvas.Font.Style := TCanvas.Font.Style - [fsItalic]; //(Por ejemplo)


Volvemos al Canvas. Dije que tena tres elementos importantes, el segundo es Pen, del tipo TPen.
Esta propiedad indica cmo se ha de dibujar los contornos de las figuras, o las lneas. Tiene cuatro
propiedades: Color (TPen.Color), el cual funciona igual que el color de las fuentes, grosor en
pxeles (TPen.Widht), estilo de dibujo (TPen.Style) y el modo en que se dibuja (TPen.Mode). De
los dos primeros no hay nada que decir. El estilo puede ser:

psSolid : Una lnea slida (por defecto).
psDash : Una lnea intermitente.
psDot : Lnea con puntos intercalados.
psDashDot : Lnea que combina la intermitencia con los puntos.
psDashDotDot Parecida a la anterior, pero por cada hueco, hay dos puntos.
psClear : La lnea no se dibuja. Esto puede servir para eliminar el borde en las figuras, pero no es
aconsejable para dibujar lneas :-).


El modo sirve para que se combine el color de la lnea con el color del fondo de diversas maneras.
Hay en total diecisis modos distintos. Aqu pondr algunos, pero en la ayuda de Delphi dispondr
de la lista completa:

pmBlack Se dibuja en negro.
pmWhite Se dibuja en blanco.
pmNot Color inverso del fondo.
pmCopy Color especificado en la propiedad TPen.Color (por defecto).
pmNotCopy El color inverso de la propiedad TPen.Color.
pmMerge Combinacin (AND) del color de fondo con el de TPen.
pmNotMerge Color inverso al de pmMerge.

La ltima propiedad del Canvas que afecta a los dibujos que hagamos es TBrush. Esta propiedad
define cmo se rellenan las figuras. No es aplicable a aquellas que son abiertas (tipo lneas, arcos
que no se cierran...) Slo tiene tres propiedades: la forma en que se rellena: TBrush.Style, el color:
TBrush.Color, y, si queremos que use una imagen: TBrush.Bitmap, del tipo TBitMap.

El estilo indica cmo debe pintarse el interior de las figuras. Excepto en las dos primeras, siempre
se dibuja con lneas finas del color que se indique en Color, dejando ver el fondo:

bsSolid : Rellena toda la figura con el color elegido (por defecto).
bsClear : No rellena la figura.
bsCross : Dibuja una red de lneas horizontales y verticales que divide la figura en cuadritos.
bsDiagCross : Parecido a la anterior, pero con lneas diagonales.
bsBDiagonal : Lnea diagonales inclinadas a la derecha.
bsFDiagonal : Diagonales a la izquierda.
bsHorizontal : Lneas horizontales.
bsVertical : Lneas verticales.

Por ejemplo, dibujar un rectngulo de bordes azules, y rallado en color amarillo.

PaintBox1.Canvas.Pen.Color := clBlue;
PaintBox1.Canvas.Brush.Style := bsHorizontal;
PaintBox1.Canvas.Brush.Color := clYellow;
PaintBox1.Canvas.Rectangle (0,0,300,220);



Con esto he terminado las propiedades bsicas del Canvas. Ahora empezar con las funciones de
dibujo. Muchas de ellas necesitan como parmetro una variable del tipo TRect. Esta define un rea
formada por dos puntos. Se puede indicar el valor de Top, Bottom, Left y Right (igual que los
controles) o el de TopLeft y BottomRight (punto superior-izquierda e inferior-derecha). Algunas de
las funciones admiten esta variable o sus valores equivalentes (X1,Y1,X2,Y2).

Para empezar, la forma ms simple de dibujar algo es hacindolo de pxel en pxel (aunque no es
la ms fcil ni la ms cmoda), pero tambin se pueden leer. Esto se hace con la propiedad
TCanvas.Pixels, que, en realidad, es una matriz de dos dimensiones, por lo que hay que pasarle dos
valores si queremos acceder a alguno de sus elementos. En relacin con la pantalla, el primer valor
corresponde a la coordenada X, y el segundo, a la Y. Esta matriz es del tipo TColor, por lo que
solamente sirve para leer o establecer el color de un punto.

TCanvas.Pixels [10,2] := clRed;
TColor := TCanvas.Pixels [11,5];


Lneas
Para empezar est LineTo y MoveTo. La primera dibuja una lnea hasta el punto que se le diga,
con el color y estilo indicado en TCanvas.Pen. Esta funcin slo lo hace desde el ltimo punto que
se le haya indicado hasta el nuevo, lo que facilita el dibujo de varias lneas unidas. Sin embargo, si
se quieren lneas separadas, o se va a iniciar una serie de lneas unidas, se debe usar la segunda
funcin, que situar el inicio de la lnea donde se indique. Por defecto, empieza a dibujar en (0,0).

TCanvas.MoveTo (4,4);
TCanvas.LineTo (15,20);


Antes he dicho que la funcin LineTo facilita el dibujo de mltiples lneas unidas. Sin embargo,
para esto es ms apropiada otra funcin: PolyLine. Esta dibuja una lnea compuesta por lneas
simples, lo que se llama lnea quebrada. Como las lneas simples, est sujeta al TPen. Y puesto que
una imagen vale mil palabras, ahorrar mucho poniendo una (con su correspondiente cdigo):




var
A: array [0..3] of TPoint;
B : TPoint;
begin
Canvas.Pen.Width := 10;
Canvas.Pen.Color := clRed;

B.X := 20;
B.Y := 60;
A [0] := B;

B.X := 70;
B.Y := 120;
A [1] := B;

B.X := 200;
B.Y := 40;
A [2] := B;

B.X := 380;
B.Y := 104;
A [3] := B;

Canvas.Polyline (A);
End;

Consejo: No deje sin definir ningn punto de la matriz, pues aparecera una lnea hacia abajo que
se sale del formulario y no parece tener fin.

La funcin Polygon es casi idntica a la anterior, solo que une el primer punto con el ltimo, y,
adems, por ser una figura cerrada, la propiedad TBrush la rellena. Para compararla con la anterior
funcin, usar el mismo cdigo, solo que la lnea que pone Canvas.Polyline (A); la sustituyo por
esta: Canvas.Polygon (A); y as queda el resultado. Jzguese el parecido:






La funcin PolyBezier se utiliza igual que las anteriores (de hecho, el mismo cdigo vale para las
tres, cambiando el nombre de la funcin). Esta dibuja una lnea con una serie de curvas, que sern
ms o menos fuertes segn cmo de distanciados estn los puntos. Si se usa el cdigo anterior para
esta funcin, queda una lnea con dos curvas, la primera hacia abajo y la segunda hacia arriba.
Empieza y acaba en el primer y ltimo punto de la matriz. Esta lnea no tiene por qu pasar
exactamente por los puntos definidos, aunque si la afectarn.

Crculos
Todos los crculos y derivados son figuras cerradas, por lo que tienen un rea que ser pintada
segn la propiedad TBrush. La nica excepcin es Arc, ya que no termina la circunferencia.

Empezar con un crculo normal y corriente, que puede ser exactamente eso, un crculo, o ser una
elipse. Para dibujarlo, se utiliza el procedimiento Ellipse. Necesita como parmetro una variable del
tipo TRect, de la cual ya he hablado, o sus valores equivalentes. Si los valores corresponden a las
esquinas de un cuadrado, saldr un crculo perfecto, en otro caso, saldr una elipse mas o menos
alargada.

El procedimiento Arc dibuja una elipse sin terminar, dejando dos extremos libres. Chord hace lo
mismo, pero une los dos extremos con una lnea, lo que resulta en una circunferencia a la que le
falta un trozo. La ultima funcin, Pie, es parecida, pero une los dos extremos con el centro. Estas
tres funciones necesitan los mismos valores. Son : X1, Y1: Esquina superior-izquierda del
rectngulo donde va a dibujarse. X2, Y2: esquina inferior-derecha del rectngulo. X3, Y3: Este
punto se unir con el centro. La lnea que resulte (que no se ve en el dibujo final) se corta con el
crculo, y el punto resultante es uno de los extremos que se unirn o dejarn libres segn la funcin
que estemos usando. X4, Y4: Idntico al anterior, pero se obtiene el segundo extremo.

Se dibuja desde el primer punto hasta el segundo en contra de las agujas del reloj, aunque en W
NT existe una funcin del API llamada SetArcDirection que permite cambiarlo. He comprobado
que tambin existe en W98 segunda edicin. Como no es una funcin de dibujo, la dejar para ms
adelante.

La ayuda de Delphi avisa que, en W95, X1 + X2 y Y1 + Y2 deben ser menores de 32768. A la
vez, la suma de estos cuatro, tampoco puede exceder el dicho nmero.

Otros dibujos

Para terminar los dibujos (aunque no el Canvas), hablar de los rectngulos, e imgenes desde
archivos. Los rectngulos tambin son afectados por TBrush.

La funcin Rectangle permite dibujar, como el nombre indica, un rectngulo. Hay dos versiones
de esta funcin, en la primera necesita un parmetro de tipo TRect. En la segunda, sus valores
equivalentes.

El segundo y ltimo procedimiento de rectngulos es RoundRect. ste dibuja un rectngulo con
las esquinas redondeadas. Necesita seis parmetros: X1, Y1: esquina superior-izquierda. X2, Y2:
esquina inferior-derecha. X3: Ancho de la elipse que se dibujar en lugar de esquinas. Y3: Alto de
dicha elipse.

Hay una funcin que permite dibujar una imagen desde un archivo y es Draw. Los nicos
parmetros que necesita son dnde dibujar y cul es la imagen.


var
G : TBitMap;
begin
G := TBitMap.Create;
G.LoadFromFile ('C:\Imagen.bmp');
Canvas.Draw (10,10,G);
G.Free;
end;

Aviso: No use el tipo TGraphic como parmetro. Le dara una excepcin del tipo EAbtractError en
ejecucin, cuando intente dibujarlo.

Textos
Para textos slo hay cuatro funciones. La propiedad Font del Canvas es aqu donde se usa, y no se
vuelve a necesitar. He creado un apartado exclusivo para estas funciones por su importancia en la
creacin de controles, en los que, casi siempre, aparece algo escrito.

La funcin ms fcil para mostrar texto es TextOut. Se le indica dnde estar el principio del texto
y el texto en s:

TCanvas.TextOut(10,10 Hola);

La otra funcin es TextRect. Como indica el nombre, se necesita una variable del tipo TRect, que
define la zona donde se dibujar el texto. Si el texto es demasiado grande, se recorta. Los dos
siguientes parmetros indican dnde se inicia el texto y por ltimo, el propio texto, que no tiene
porqu empezar en el sitio que diga el TRect, pero si no se sita dentro, puede ocurrir lo de la
imagen:


Var
F : TRect;
Begin
F.Top := 10;
F.Left := 10;
F.Right := 300;
F.Bottom := 200;
Canvas.Font.Size := 25;
Canvas.Font.Style := Canvas.Font.Style + [fsBold];
Canvas.TextRect(F,0,0, 'Hola, Cmo ests?');
End;

Las otras dos funciones son TextHeight y TextWidth. Devuelven el alto y ancho (respectivamente)
de un texto. Aunque su nico parmetro es el texto a medir, le afecta mucho la propiedad Font, ya
que el resultado depende del tipo de letra, el estilo utilizado y el tamao.

Var
Tamano : integer;
Begin
Canvas.Font.Size := 10;
Tamano := Canvas.TextHeight (Texto);
End;

Tambin se puede usar TextExtent, que devuelve una variable TSize. En esta variable estn
incluidas el alto y el ancho, por lo que puede sustituir a las anteriores. Se usa igual que aquellas. La
declaracin de este tipo es:

type
TSize = record

cx: Longint;
cy: Longint;

end;


Otras funciones
Hay varias funciones que no dibujan nada, pero es importante conocerlas.

El procedimiento Refresh se utiliza para que TBrush, TPen y TFont tomen sus valores originales.

SetArcDirection es una funcin del API que afecta al dibujado de:

Arc
Chord
Ellipse
Pie
Rectangle
RoundRect

Lo que hace es que se dibujen en el sentido de las agujas del reloj o al contrario. Necesita dos
parmetros: el primero identifica el dispositivo de contexto (el handle del Canvas)y el segundo debe
tomar uno de estos valores:

AD_COUNTERCLOCKWISE (Contra las agujas del reloj)
AD_CLOCKWISE (Hacia las agujas del reloj)

En W. 95 no est disponible y en W. NT s. Tambin la he encontrado en W. 98 segunda edicin.

TControl.SetArcDirection (TCanvas.Handle,AD_ClockWise);


La funcin StretchDraw encoge o agranda una imagen. Dicha imagen se dibujar en el espacio
definido por una variable TRect. Si el espacio definido por ste es mayor que la imagen original,
queda agrandada. En caso que sea menor, se reduce.

TCanvas.StretchDraw (TRect, TGraphic);

Para terminar, cuatro procedimientos que afectan a las aplicaciones multi-hilo (multi-thread). Lock
sirve para que no se pueda dibujar en el Canvas. Cada llamada a este procedimiento aumenta en uno
la variable LockCount. El procedimiento UnLock disminuye esta variable, pero hasta que no llega a
cero no se puede dibujar. La funcin TryLock comprueba si est bloqueado, y en caso contrario lo
bloquea y devuelve True.

Vous aimerez peut-être aussi