Ir al contenido


Foto

[MULTILENGUAJE] Encontrar el tamaño en pixels de la caja que contiene un texto multilínea.


  • Por favor identifícate para responder
4 respuestas en este tema

#1 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.111 mensajes
  • LocationMadrid - España

Escrito 28 enero 2012 - 05:01

TCanvas tiene un método que encuentra el tamaño de un texto para la fuente que tiene asignada. El problema es que si el texto es multilínea lo calcula mal, como si de una sola línea se tratase..

A raíz de esta pregunta de TiammatMx he escrito una pequeña función que determine el ancho y alto de un texto multilínea, es decir la caja que lo contendrá. Lo he escrito con la API GetTextExtentPoint32 pero se podría haber hecho de otra manera. Simplemente tendremos que localizar el ancho de la línea mas larga y contar el número de líneas para multiplicarlo por el alto de una línea, con lo que obtenemos el ancho y alto de la caja.

La función sirve tanto para textos de una sola línea como de varias.

Esta es la función:


delphi
  1. // Calcula el tamaño del cuadro que contiene un texto "Multiline"
  2. function GetTextExtentML(Canvas: TCanvas; Text: String): TSize;
  3. var
  4.   Size: TSize;
  5.   nLines, Ini, i, L: integer;
  6. begin
  7.   nLines:= 0; Ini:= 1; L:= Length(Text);
  8.   for i:=1 to L do
  9.   begin
  10.     if (Text[i] = #13) or (i = L) then
  11.     begin
  12.       GetTextExtentPoint32(Canvas.Handle, PCHAR(@Text[Ini]), i-Ini, Size);
  13.       if Result.cx < Size.cx then Result.cx:= Size.cx;
  14.       Ini:= i;
  15.       inc(nLines);
  16.     end;
  17.   end;
  18.   Result.cy:= Size.cy*nLines;
  19. end;



Un ejemplo de uso:


delphi
  1. var
  2. Size: TSize;
  3. begin
  4. Size:= GetTextExtentML(Canvas, 'Hola'+#13#10+'Adios');



Saludos.

Edito para arreglar etiqueta de código alterada
  • 0

#2 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.460 mensajes
  • LocationMéxico

Escrito 29 enero 2012 - 10:40

Amigo, usted siempre sacando una API de la manga :)

Saludos
  • 0

#3 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.111 mensajes
  • LocationMadrid - España

Escrito 29 enero 2012 - 01:21

Amigo, usted siempre sacando una API de la manga :)


En realidad esa API ya la había usado en este otro truco aunque quedó muy camuflada dada la naturaleza compacta de ese código.  :D


Saludos.
  • 0

#4 TiammatMX

TiammatMX

    Advanced Member

  • Miembros
  • PipPipPip
  • 1.750 mensajes
  • LocationUniverso Curvo\Vía Láctea\Sistema Solar\Planeta Tierra\América\México\Ciudad de México\Xochimilco\San Gregorio Atlapulco\Home

Escrito 29 enero 2012 - 01:24

...esta pregunta de TiammatMx he escrito ...


Escafandra, has salvado mi peludo y guango trasero..., muchas y muy sentidas gracias.
  • 0

#5 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.111 mensajes
  • LocationMadrid - España

Escrito 16 febrero 2012 - 05:02

Dada mi afición de presentar los trucos en al menos C/C++ y delphi, traduzco el código de éste, inicialmente escrito en delphi, a C/C++.
 


cpp
  1. // Calcula el tamaño del cuadro que contiene un texto "Multiline"
  2. SIZE GetTextExtentML(HDC hDC, char* Text)
  3. { SIZE Size, Result = {0,0};
  4. int nLines = 0, Ini = 0;
  5. for(int i = 0, L = strlen(Text); i < L; i++){
  6. if (Text== 13 || i+1 == L){
  7. GetTextExtentPoint32(hDC, Text + Ini, i-Ini, &Size);
  8. if(Result.cx < Size.cx) Result.cx = Size.cx;
  9. Ini = i;
  10. nLines++;
  11. }
  12. }
  13. Result.cy = Size.cy*nLines; return Result;
  14. }

Espero que sea de utilidad.

Saludos.

[i]Edito para arreglar etiqueta de código alterada</em>
  • 0




IP.Board spam blocked by CleanTalk.