programing

Graphics.DrawString ()의 중앙 텍스트 출력

nasanasas 2020. 12. 28. 08:15
반응형

Graphics.DrawString ()의 중앙 텍스트 출력


.NETCF (Windows Mobile) Graphics클래스와 DrawString()메서드를 사용하여 단일 문자를 화면에 렌더링합니다.

문제는 내가 제대로 중앙에 위치하지 못하는 것 같습니다. 문자열 렌더링 위치의 Y 좌표에 대해 설정 한 값에 관계없이 항상 그보다 낮게 나오고 텍스트 크기가 클수록 Y 오프셋이 커집니다.

예를 들어, 텍스트 크기 12에서 오프셋은 약 4이지만 32에서 오프셋은 약 10입니다.

캐릭터가 그려지는 직사각형의 대부분을 세로로 차지하고 가로로 가운데에 배치되기를 원합니다. 다음은 내 기본 코드입니다. this그려지는 사용자 컨트롤을 참조하고 있습니다.

Graphics g = this.CreateGraphics();

float padx = ((float)this.Size.Width) * (0.05F);
float pady = ((float)this.Size.Height) * (0.05F);

float width = ((float)this.Size.Width) - 2 * padx;
float height = ((float)this.Size.Height) - 2 * pady;

float emSize = height;

g.DrawString(letter, new Font(FontFamily.GenericSansSerif, emSize, FontStyle.Regular),
            new SolidBrush(Color.Black), padx, pady);

예, 대신 사용할 수있는 레이블 컨트롤이 있고이를 통해 센터링을 설정할 수 있다는 것을 알고 있지만 실제로는 Graphics클래스를 사용하여 수동으로 수행해야합니다 .


StringFormat 개체에 대한 또 다른 투표를 추가하고 싶습니다. 이것을 사용하여 단순히 "center, center"를 지정할 수 있으며 텍스트는 제공된 직사각형 또는 점의 중앙에 그려집니다.

StringFormat format = new StringFormat();
format.LineAlignment = StringAlignment.Center;
format.Alignment = StringAlignment.Center;

그러나 CF에는 한 가지 문제가 있습니다. 두 값 모두에 Center를 사용하면 TextWrapping이 꺼집니다. 왜 이런 일이 발생하는지 모르겠지만 CF의 버그로 보입니다.


텍스트를 정렬하려면 다음을 사용하십시오.

StringFormat sf = new StringFormat();
sf.LineAlignment = StringAlignment.Center;
sf.Alignment = StringAlignment.Center;
e.Graphics.DrawString("My String", this.Font, Brushes.Black, ClientRectangle, sf);

여기에있는 텍스트는 주어진 경계에 맞춰져 있습니다. 이 샘플에서 이것은 ClientRectangle입니다.


내가 얻은 제안의 조합을 통해 다음과 같은 결과를 얻었습니다.

    private void DrawLetter()
    {
        Graphics g = this.CreateGraphics();

        float width = ((float)this.ClientRectangle.Width);
        float height = ((float)this.ClientRectangle.Width);

        float emSize = height;

        Font font = new Font(FontFamily.GenericSansSerif, emSize, FontStyle.Regular);

        font = FindBestFitFont(g, letter.ToString(), font, this.ClientRectangle.Size);

        SizeF size = g.MeasureString(letter.ToString(), font);
        g.DrawString(letter, font, new SolidBrush(Color.Black), (width-size.Width)/2, 0);

    }

    private Font FindBestFitFont(Graphics g, String text, Font font, Size proposedSize)
    {
        // Compute actual size, shrink if needed
        while (true)
        {
            SizeF size = g.MeasureString(text, font);

            // It fits, back out
            if (size.Height <= proposedSize.Height &&
                 size.Width <= proposedSize.Width) { return font; }

            // Try a smaller font (90% of old size)
            Font oldFont = font;
            font = new Font(font.Name, (float)(font.Size * .9), font.Style);
            oldFont.Dispose();
        }
    }

지금까지 이것은 완벽하게 작동합니다.

The only thing I would change is to move the FindBestFitFont() call to the OnResize() event so that I'm not calling it every time I draw a letter. It only needs to be called when the control size changes. I just included it in the function for completeness.


To draw a centered text:

TextRenderer.DrawText(g, "my text", Font, Bounds, ForeColor, BackColor, 
  TextFormatFlags.HorizontalCenter | 
  TextFormatFlags.VerticalCenter |
  TextFormatFlags.GlyphOverhangPadding);

Determining optimal font size to fill an area is a bit more difficult. One working soultion I found is trial-and-error: start with a big font, then repeatedly measure the string and shrink the font until it fits.

Font FindBestFitFont(Graphics g, String text, Font font, 
  Size proposedSize, TextFormatFlags flags)
{ 
  // Compute actual size, shrink if needed
  while (true)
  {
    Size size = TextRenderer.MeasureText(g, text, font, proposedSize, flags);

    // It fits, back out
    if ( size.Height <= proposedSize.Height && 
         size.Width <= proposedSize.Width) { return font; }

    // Try a smaller font (90% of old size)
    Font oldFont = font;
    font = new Font(font.FontFamily, (float)(font.Size * .9)); 
    oldFont.Dispose();
  }
}

You'd use this as:

Font bestFitFont = FindBestFitFont(g, text, someBigFont, sizeToFitIn, flags);
// Then do your drawing using the bestFitFont
// Don't forget to dispose the font (if/when needed)

You can use an instance of the StringFormat object passed into the DrawString method to center the text.

See Graphics.DrawString Method and StringFormat Class.


Here's some code. This assumes you are doing this on a form, or a UserControl.

Graphics g = this.CreateGraphics();
SizeF size = g.MeasureString("string to measure");

int nLeft = Convert.ToInt32((this.ClientRectangle.Width / 2) - (size.Width / 2));
int nTop = Convert.ToInt32((this.ClientRectangle.Height / 2) - (size.Height / 2));

From your post, it sounds like the ClientRectangle part (as in, you're not using it) is what's giving you difficulty.

ReferenceURL : https://stackoverflow.com/questions/7991/center-text-output-from-graphics-drawstring

반응형