Está en la página 1de 9

El Rinconcito de Delphi

Canvas
Nstor Freire
nestorfreire@wanadoo.es

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 (ibOwnerDrawFix ed), 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 n uestros 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 W indows. 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 pmWhite pmNot pmCopy pmNotCopy pmMerge pmNotMerge Se dibuja en negro. Se dibuja en blanco. Color inverso del fondo. Color especificado en la propiedad TPen.Color (por defecto). El color inverso de la propiedad TPen.Color. Combinacin (AND) del color de fondo con el de TPen. 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 aguja s 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.

También podría gustarte