Jump to content


Photo

[RESUELTO] Posicionar un texto exactamente


  • Please log in to reply
10 replies to this topic

#1 Marc

Marc

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1484 posts
  • LocationMallorca

Posted 30 November 2011 - 08:35 AM

Hola amigos.

Me estoy peleando para conseguir algo tan sencillo como colocar un texto en una posición exacta de un formulario en blanco, y no lo consigo. :(

Primero lo he probado poniendo el texto en un Label, y posicionándolo en la coordenada deseada. Pero el texto no empieza donde yo le indico, sino como un 25% más abajo, puesto que el Label deja un espaciado superior e inferior entre donde empieza el label y donde de verdad se escribe texto. No consigo definir un Label con el mismo Height que su Font.Size en píxels.

He probado eliminando el Label y escribiendo directamente en el Canvas de un Image que ocupa todo el formulario. Pero me hace le mismo. Si escribo un texto con un TextOut(x,y, 'texto'), el texto no empieza exactamente en las coordenadas deseadas, sino que empieza un poco por debajo porqué deja un espaciado superior e inferior.

¿ Se os ocurre alguna forma de poder posicionar "exactamente" un texto en un canvas o en un formulario, sin esos espaciados superior e inferior ?.

NOTA: Por cierto, dado que tengo que poner bastantes textos distintos, a tamaños distintos, y en posiciones distintas (es un test de visión), si es posible me gustaría encontrar un solución escribiendo sobre el canvas, y no poblando el formulario de labels.

Gracias.
  • 0

#2 felipe

felipe

    Advanced Member

  • Administrador
  • 3283 posts
  • LocationColombia

Posted 30 November 2011 - 09:08 AM

¿Serviría del algo esto? http://www.delphiacc...-dividir-ancho/
fue algo matemático para distribuir un formulario aunque no sé si aplique mucho a tu caso.


Saludos!
  • 0

#3 Marc

Marc

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1484 posts
  • LocationMallorca

Posted 30 November 2011 - 09:21 AM

Gracias por responder, Felipe.

¿Serviría del algo esto? http://www.delphiacc...-dividir-ancho/
fue algo matemático para distribuir un formulario aunque no sé si aplique mucho a tu caso.


Saludos!


No, esta formula es para dividir un espacio equitativamente, y en mi caso las líneas son de distinto tamaño y su interespaciado también lo será.

Ya he calculado las posiciones donde debo posicionar cada texto.

El problema es que no consigo poner el texto en esas posiciones, siempre me lo escribe más abajo.

Saludos.
  • 0

#4 Marc

Marc

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1484 posts
  • LocationMallorca

Posted 30 November 2011 - 09:29 AM

Para probar el problema, cread un formulario nuevo, ponedle un TImage con Align a alClient.

Y añadid este código :



delphi
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. begin
  3.     Image1.Canvas.Font.Name := 'Arial';
  4.     Image1.Canvas.Font.Size := 100;
  5.     Image1.Canvas.TextOut(0,0,'ABC');
  6. end;



Como podéis ver, al ejecutarlo, el texto no empieza en la esquina superior izquierda, sino un poco más abajo.


  • 0

#5 Sergio

Sergio

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1092 posts
  • LocationMurcia, España

Posted 30 November 2011 - 11:05 AM

Marc, no sera que te sale un poco más arriba de donde tu le dices? Eso sería lo normal.

Los fonts reservan una franja arriba y otra abajo por el tema de las letras con "rabos" para abajo, como la p, o arriba, como la t, y la y que tu le pasa es para el punto inferior de la p: tienes que restarle (para arriba) a tu y esos pixeles "colgantes".

No encontre el codigo para delphi, pero en C# seria asi:

[csharp]
Font myFont = Label1.Font;
FontFamily ff = myFont.FontFamily;

float lineSpace = ff.GetLineSpacing(myFont.Style);
float ascent = ff.GetCellAscent(myFont.Style);
float baseline =  myFont.GetHeight(ev.Graphics) * ascent / lineSpace;

PointF renderPt = new PointF(pt.X, pt.Y  - baseline));
ev.Graphics.DrawString("Render this string", myFont, textBrush, renderPt);
[/csharp]

Lo encontre aqui: http://stackoverflow...a-numericupdown
  • 0

#6 seoane

seoane

    Advanced Member

  • Administrador
  • 1259 posts
  • LocationEspaña

Posted 30 November 2011 - 11:16 AM

Pues como dice Sergio ese espacio es necesario. Si en tu ejemplo, usamos esto


delphi
  1. Image1.Canvas.TextOut(0,0,'ABCÍ');


Veras que la "Í" ocupa todo el espacio.
  • 0

#7 Marc

Marc

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1484 posts
  • LocationMallorca

Posted 30 November 2011 - 11:21 AM

Gracias Sergio.

Marc, no sera que te sale un poco más arriba de donde tu le dices? Eso sería lo normal.

Los fonts reservan una franja arriba y otra abajo por el tema de las letras con "rabos" para abajo, como la p, o arriba, como la t, y la y que tu le pasa es para el punto inferior de la p: tienes que restarle (para arriba) a tu y esos pixeles "colgantes".

No encontre el codigo para delphi, pero en C# seria asi:

[csharp]
Font myFont = Label1.Font;
FontFamily ff = myFont.FontFamily;

float lineSpace = ff.GetLineSpacing(myFont.Style);
float ascent = ff.GetCellAscent(myFont.Style);
float baseline =  myFont.GetHeight(ev.Graphics) * ascent / lineSpace;

PointF renderPt = new PointF(pt.X, pt.Y  - baseline));
ev.Graphics.DrawString("Render this string", myFont, textBrush, renderPt);
[/csharp]

Lo encontre aqui: http://stackoverflow...a-numericupdown


No, sale más abajo de donde le digo, precisamente porqué en la posición que le marco, pone el espaciado reservado para "rabos", y por tanto el texto de verdad, aparece un poco más abajo.

La fuente que voy a poner nunca ocupa esos espacios reservados, puesto que es una fuente TrueType que me modificado, con carácteres especiales, de anchura y altura siempre igual y fija.

El ejemplo que me das hace justo lo que necesito, resta ese "baseline" para que suba todo y por tanto el texto de verdad, quede justo en la posición deseada.

El problema es que para calcular el "baseline" utiliza las funciones GetLineSpacing y GetCellAscent, que forman parte de .NET y no identifico los equivalentes en Delphi (si es que existen).

Voy a ver si con esta información consigo avanzar algo más.

Gracias.
  • 0

#8 Marc

Marc

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1484 posts
  • LocationMallorca

Posted 30 November 2011 - 11:25 AM

Pues como dice Sergio ese espacio es necesario. Si en tu ejemplo, usamos esto


delphi
  1. Image1.Canvas.TextOut(0,0,'ABCÍ');


Veras que la "Í" ocupa todo el espacio.


Es que en realidad no utilizo una fuente normal, sino una fuente creada por mi (bueno, más bien la he modificado) que tiene todos los carácteres de exactamente el mismo tamaño (y que nunca utiliza esos espacios reservados superior e inferior).
  • 0

#9 cadetill

cadetill

    Advanced Member

  • Moderadores
  • PipPipPip
  • 994 posts
  • LocationEspaña

Posted 30 November 2011 - 11:38 AM

Pues acabo de probar el código que has puesto (pero con una "Í") y me lo hace correctamente, el acento está pegadito pegadito a la parte superior
  • 0

#10 Marc

Marc

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1484 posts
  • LocationMallorca

Posted 30 November 2011 - 11:45 AM

Pues acabo de probar el código que has puesto (pero con una "Í") y me lo hace correctamente, el acento está pegadito pegadito a la parte superior


Es que no tengo acentos, en realidad lo utilizo con unos carácteres especiales para poner en pantalla un test de visión (sin acentos).
  • 0

#11 Marc

Marc

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1484 posts
  • LocationMallorca

Posted 30 November 2011 - 11:47 AM

Gracias amigos,

Ya lo he resuelto, sabiendo (cosa que antes no sabía) que ese espacio formaba parta de un espacio reservado en la fuente TrueType, he modificado la fuente y le he quitado ese espacio.

Ahora ya me pone los textos como quería, posicionando realmente donde se escribe.
  • 0




IP.Board spam blocked by CleanTalk.