public static void DrawString(this SpriteBatch spriteBatch, SpriteFont spriteFont, string text, Rectangle bounds, Color color, TextAlignment align) { Vector2 size = spriteFont.MeasureString(text); Vector2 pos = bounds.Center.ToVector2(); Vector2 origin = size * 0.5f; if (align.HasFlag(TextAlignment.Left)) { origin.X += bounds.Width / 2.0f - size.X / 2; } if (align.HasFlag(TextAlignment.Right)) { origin.X -= bounds.Width / 2.0f - size.X / 2; } if (align.HasFlag(TextAlignment.Top)) { origin.Y += bounds.Height / 2.0f - size.Y / 2; } if (align.HasFlag(TextAlignment.Bottom)) { origin.Y -= bounds.Height / 2.0f - size.Y / 2; } spriteBatch.DrawString(spriteFont, text, pos, color, 0f, origin, Vector2.One, SpriteEffects.None, 0f); }
public static void DrawImages(Graphics drawer, IEnumerable <Bitmap> images, long spacing, TextAlignment alignment, Rectangle box) { var bitmap = CalculateBounds(images, spacing); int x, y; if (alignment.HasFlag(TextAlignment.Left)) { x = box.X; } else if (alignment.HasFlag(TextAlignment.Right)) { x = box.Right - bitmap.Width + 1; } else { x = (box.Left + box.Right - bitmap.Width) >> 1; } if (alignment.HasFlag(TextAlignment.Top)) { y = box.Top; } else if (alignment.HasFlag(TextAlignment.Bottom)) { y = box.Bottom - bitmap.Height + 1; } else { y = (box.Top + box.Bottom - bitmap.Height) >> 1; } if (x < box.Left) { x = box.Left; } if (y < box.Top) { y = box.Top; } foreach (var image in images) { if (image == null) { continue; } drawer.DrawImage(image, x, y); x += image.Width + (int)spacing; } }
// TODO: support for multiline strings plus angle public StringMetrics DrawString(string text, RectangleF rect, float angle, TextAlignment align, float realFontSize, Color4 color, CoordinateType coordinateType) { if (string.IsNullOrWhiteSpace(text)) { return(new StringMetrics()); } var hl = align.HasFlag(TextAlignment.Left); var vt = align.HasFlag(TextAlignment.Top); if (hl && vt) { return(DrawString(text, new Vector2(rect.X, rect.Y), angle, realFontSize, color, coordinateType)); } var hc = align.HasFlag(TextAlignment.HorizontalCenter); var vc = align.HasFlag(TextAlignment.VerticalCenter); var m = MeasureString(angle == 0f ? text : "00", angle, realFontSize, coordinateType); var p = new Vector2( hl ? rect.X : hc ? rect.X + rect.Width / 2 - m.Size.X / 2 : rect.Right - m.Size.X, vt ? rect.Y : vc ? rect.Y + rect.Height / 2 - m.Size.Y / 2 : rect.Bottom - m.Size.Y); if (angle != 0f) { var o = m.Size / 2f; o.Y /= 2f; p += o - SpriteRenderer.Rotate(o, (float)Math.Sin(angle), (float)Math.Cos(angle)); p -= SpriteRenderer.Rotate( GetOffset(MeasureString(text, 0f, realFontSize, coordinateType)) - GetOffset(MeasureString("00", 0f, realFontSize, coordinateType)), (float)Math.Sin(angle), (float)Math.Cos(angle)); } return(DrawString(text, p, angle, realFontSize, color, coordinateType)); Vector2 GetOffset(StringMetrics stringMetrics) { var xm = hl ? 0f : hc ? stringMetrics.Size.X / 2 : stringMetrics.Size.X; var ym = vt ? 0f : vc ? stringMetrics.Size.Y / 2 : stringMetrics.Size.Y; return(new Vector2(xm, ym)); } }
public void DrawText(float x, float y, string text, SDL.SDL_Color color, TextAlignment alignment = TextAlignment.Default, DisplayFont font = null) { var surfacePtr = SDL_ttf.TTF_RenderUNICODE_Solid(font?.Font ?? _font, text, color); SDL.SDL_Surface surface = (SDL.SDL_Surface)Marshal.PtrToStructure(surfacePtr, typeof(SDL.SDL_Surface)); var texture = SDL.SDL_CreateTextureFromSurface(_renderer, surfacePtr); int w = surface.w; int h = surface.h; int xx = (int)(x * ActualWidth); int yy = (int)(y * ActualHeight); if (alignment.HasFlag(TextAlignment.HorizontalCenter)) { xx -= w / 2; } else if (alignment.HasFlag(TextAlignment.HorizontalRight)) { xx -= w; } if (alignment.HasFlag(TextAlignment.VerticalCenter)) { yy -= h / 2; } else if (alignment.HasFlag(TextAlignment.VerticalBottom)) { yy -= h; } SDL.SDL_FreeSurface(surfacePtr); var src = new SDL.SDL_Rect() { x = 0, y = 0, w = w, h = h }; var target = new SDL.SDL_Rect() { x = xx, y = yy, w = w, h = h }; SDL.SDL_RenderCopy(_renderer, texture, ref src, ref target); SDL.SDL_DestroyTexture(texture); }
// TODO: support for multiline strings plus angle public StringMetrics DrawString(string text, RectangleF rect, float angle, TextAlignment align, float realFontSize, Color4 color, CoordinateType coordinateType) { if (align.HasFlag(TextAlignment.Top) && align.HasFlag(TextAlignment.Left)) { return(DrawString(text, new Vector2(rect.X, rect.Y), angle, realFontSize, color, coordinateType)); } var m = MeasureString(text, angle, realFontSize, coordinateType); var y = align.HasFlag(TextAlignment.Top) ? rect.Top : align.HasFlag(TextAlignment.VerticalCenter) ? rect.Top + rect.Height / 2 - m.Size.Y / 2 : rect.Bottom - m.Size.Y; var p = new Vector2( align.HasFlag(TextAlignment.Left) ? rect.X : align.HasFlag(TextAlignment.HorizontalCenter) ? rect.X + rect.Width / 2 - m.Size.X / 2 : rect.X + rect.Width - m.Size.X, y); if (angle != 0f) { var o = m.Size / 2f; o.Y /= 2f; p += o - SpriteRenderer.Rotate(o, (float)Math.Sin(angle), (float)Math.Cos(angle)); } return(DrawString(text, p, angle, realFontSize, color, coordinateType)); }
public StringMetrics DrawString(string text, Vector2 position, float angle, TextAlignment align, float realFontSize, Color4 color) { float left, top, width, height; if (align.HasFlag(TextAlignment.HorizontalCenter)) { left = -10e3f + position.X; width = 20e3f; } else if (align.HasFlag(TextAlignment.Right)) { left = -20e3f + position.X; width = 20e3f; } else { left = position.X; width = 20e3f; } if (align.HasFlag(TextAlignment.VerticalCenter)) { top = -10e3f + position.Y; height = 20e3f; } else if (align.HasFlag(TextAlignment.Bottom)) { top = -20e3f + position.Y; height = 20e3f; } else { top = position.Y; height = 20e3f; } return(DrawString(text, new RectangleF(left, top, width, height), angle, align, realFontSize, color, CoordinateType.Absolute)); }
/// <summary> /// Calculates the position and origin vectors that should be used when calling a SpriteBatch.DrawString method. /// </summary> /// <param name="font">The SpriteFont that will be used to draw the string.</param> /// <param name="text">The string that will be rendered.</param> /// <param name="bounds">The rendering boundary.</param> /// <param name="alignment">The alignment of the string.</param> /// <param name="shiftPositionUsingOrigin"> /// If true the position will be at the center of the bounding box and origin will be modified to move text into place. /// If false, the origin will remain at 0,0 and the position will be directly modified. /// </param> public static TextRenderingSettings CreateTextRenderingSettings(SpriteFont font, string text, Rectangle bounds, TextAlignment alignment, bool shiftPositionUsingOrigin) { // Start by determining the amount of space the text will require Vector2 sizeOfText = font.MeasureString(text); float halfWidthOfBoundary = bounds.Width * 0.5f; float halfHeightOfBoundary = bounds.Height * 0.5f; float halfOfWidthRequiredToRenderText = sizeOfText.X * 0.5f; float halfOfHeightRequiredToRenderText = sizeOfText.Y * 0.5f; float deltaBetweenHalfWidthOfBoundaryAndHalfOfWidthRequiredToRenderText = halfWidthOfBoundary - halfOfWidthRequiredToRenderText; float deltaBetweenHalfHeightOfBoundaryAndHalfOfHeightRequiredToRenderText = halfHeightOfBoundary - halfOfHeightRequiredToRenderText; Vector2 position; Vector2 origin; if(shiftPositionUsingOrigin == true) { // Position the text at the center of the allowed boundry position = new Vector2(halfWidthOfBoundary + bounds.X, halfHeightOfBoundary + bounds.Y); // Set the origin at the center of the text origin = new Vector2(halfOfWidthRequiredToRenderText, halfOfHeightRequiredToRenderText); } else { // Position the text at the center of the allowed boundry position = new Vector2(deltaBetweenHalfWidthOfBoundaryAndHalfOfWidthRequiredToRenderText, deltaBetweenHalfHeightOfBoundaryAndHalfOfHeightRequiredToRenderText); // Position the origin at the center of the allowed boundry origin = Vector2.Zero; } // // The below code can seem a bit tricky at first glance, but it works because shifting // the origin in a direction, causes the text to be moved in the opposite direction. // if (alignment.HasFlag(TextAlignment.Left)) { if (shiftPositionUsingOrigin == true) { // Shift the origin to the right origin.X += deltaBetweenHalfWidthOfBoundaryAndHalfOfWidthRequiredToRenderText; } else { // Shift the position to the left position.X -= deltaBetweenHalfWidthOfBoundaryAndHalfOfWidthRequiredToRenderText; } } if (alignment.HasFlag(TextAlignment.Right)) { if (shiftPositionUsingOrigin == true) { // Shift the origin to the left origin.X -= deltaBetweenHalfWidthOfBoundaryAndHalfOfWidthRequiredToRenderText; } else { // Shift the position to the right position.X += deltaBetweenHalfWidthOfBoundaryAndHalfOfWidthRequiredToRenderText; } } if (alignment.HasFlag(TextAlignment.Top)) { if (shiftPositionUsingOrigin == true) { // Shift the origin down origin.Y += deltaBetweenHalfHeightOfBoundaryAndHalfOfHeightRequiredToRenderText; } else { // Shift the position up position.Y -= deltaBetweenHalfHeightOfBoundaryAndHalfOfHeightRequiredToRenderText; } } if (alignment.HasFlag(TextAlignment.Bottom)) { if (shiftPositionUsingOrigin == true) { // Shift the origin up origin.Y -= deltaBetweenHalfHeightOfBoundaryAndHalfOfHeightRequiredToRenderText; } else { // Shift the position down position.Y += deltaBetweenHalfHeightOfBoundaryAndHalfOfHeightRequiredToRenderText; } } TextRenderingSettings renderingSettings = new TextRenderingSettings(text, origin + position, origin, sizeOfText); return renderingSettings; }
public StringMetrics DrawString(string text, RectangleF rect, TextAlignment align, float realFontSize, Color4 color, CoordinateType coordinateType) { //If text is aligned top and left, no adjustment has to be made if (align.HasFlag(TextAlignment.Top) && align.HasFlag(TextAlignment.Left)) { return(DrawString(text, new Vector2(rect.X, rect.Y), realFontSize, color, coordinateType)); } text = text.Replace("\r", ""); var rawTextMetrics = MeasureString(text, realFontSize, coordinateType); var mMetrics = MeasureString("m", realFontSize, coordinateType); float startY; if (align.HasFlag(TextAlignment.Top)) { startY = rect.Top; } else if (align.HasFlag(TextAlignment.VerticalCenter)) { startY = rect.Top + rect.Height / 2 - rawTextMetrics.Size.Y / 2; } else //Bottom { startY = rect.Bottom - rawTextMetrics.Size.Y; } var totalMetrics = new StringMetrics(); //break text into lines var lines = text.Split('\n'); foreach (var line in lines) { float startX; if (align.HasFlag(TextAlignment.Left)) { startX = rect.X; } else { var lineMetrics = MeasureString(line, realFontSize, coordinateType); if (align.HasFlag(TextAlignment.HorizontalCenter)) { startX = rect.X + rect.Width / 2 - lineMetrics.Size.X / 2; } else //Right { startX = rect.Right - lineMetrics.Size.X; } } var lineMetrics2 = DrawString(line, new Vector2(startX, startY), realFontSize, color, coordinateType); float lineHeight; if (mMetrics.Size.Y < 0) { lineHeight = Math.Min(lineMetrics2.Size.Y, mMetrics.Size.Y); } else { lineHeight = Math.Max(lineMetrics2.Size.Y, mMetrics.Size.Y); } startY += lineHeight; totalMetrics.Merge(lineMetrics2); } return(totalMetrics); }