public override void ComposeTextElements(Context ctxStatic, ImageSurface surfaceStatic) { ImageSurface surface = new ImageSurface(Format.Argb32, (int)Bounds.InnerWidth + 1, (int)Bounds.InnerHeight + 1); Context ctx = new Context(surface); Font.SetupContext(ctx); fontHeight = (float)Font.GetFontExtents().Height; double radius = scaled(1); double spacing = scaled(unscaledTabSpacing); double padding = scaled(unscaledTabPadding); double xpos = spacing; Font.Color[3] = 0.5; for (int i = 0; i < tabs.Length; i++) { tabWidths[i] = (int)(ctx.TextExtents(tabs[i].Name).Width + 2 * padding + 1); ctx.NewPath(); ctx.MoveTo(xpos, Bounds.InnerHeight); ctx.LineTo(xpos, radius); ctx.Arc(xpos + radius, radius, radius, 180 * GameMath.DEG2RAD, 270 * GameMath.DEG2RAD); ctx.Arc(xpos + tabWidths[i] - radius, radius, radius, -90 * GameMath.DEG2RAD, 0 * GameMath.DEG2RAD); ctx.LineTo(xpos + tabWidths[i], Bounds.InnerHeight); ctx.ClosePath(); double[] color = GuiStyle.DialogDefaultBgColor; ctx.SetSourceRGBA(color[0], color[1], color[2], color[3] * 0.75); ctx.FillPreserve(); ShadePath(ctx, 2); if (AlarmTabs) { notifyFont.SetupContext(ctx); } else { Font.SetupContext(ctx); } DrawTextLineAt(ctx, tabs[i].Name, xpos + padding, (surface.Height - fontHeight) / 2); xpos += tabWidths[i] + spacing; } Font.Color[3] = 1; ComposeOverlays(); generateTexture(surface, ref baseTexture); ctx.Dispose(); surface.Dispose(); }
/// <summary> /// lineX is set to 0 after the second line, lineY is advanced by line height for each line /// </summary> /// <param name="ctx">The context of the text.</param> /// <param name="lines">The preformatted lines of the text.</param> /// <param name="font">The font of the text</param> /// <param name="orientation">The orientation of text (Default: Left)</param> public void DrawMultilineText(Context ctx, CairoFont font, TextLine[] lines, EnumTextOrientation orientation = EnumTextOrientation.Left) { font.SetupContext(ctx); double offsetX = 0; for (int i = 0; i < lines.Length; i++) { TextLine textLine = lines[i]; if (textLine.Text.Length == 0) { continue; } if (orientation == EnumTextOrientation.Center) { offsetX = (textLine.LeftSpace + textLine.RightSpace) / 2; } if (orientation == EnumTextOrientation.Right) { offsetX = textLine.LeftSpace + textLine.RightSpace; } DrawTextLine(ctx, font, textLine.Text, offsetX + textLine.Bounds.X, textLine.Bounds.Y); } }
private void ComposeOverlays() { double radius = scaled(1); double spacing = scaled(unscaledTabSpacing); double padding = scaled(unscaledTabPadding); double width; for (int i = 0; i < tabs.Length; i++) { ImageSurface surface = new ImageSurface(Format.Argb32, tabWidths[i] + 1, (int)tabHeight + 1); Context ctx = genContext(surface); width = tabWidths[i] + 1; ctx.SetSourceRGBA(1, 1, 1, 0); ctx.Paint(); ctx.NewPath(); ctx.MoveTo(width, tabHeight + 1); ctx.LineTo(width, 0); ctx.LineTo(radius, 0); ctx.ArcNegative(0, radius, radius, 270 * GameMath.DEG2RAD, 180 * GameMath.DEG2RAD); ctx.ArcNegative(0, tabHeight - radius, radius, 180 * GameMath.DEG2RAD, 90 * GameMath.DEG2RAD); ctx.ClosePath(); double[] color = GuiStyle.DialogDefaultBgColor; ctx.SetSourceRGBA(color[0], color[1], color[2], color[3]); ctx.Fill(); ctx.NewPath(); ctx.LineTo(1 + width, 1); ctx.LineTo(1, 1); ctx.LineTo(1, tabHeight - 1); ctx.LineTo(1 + width, 1 + tabHeight - 1); float strokeWidth = 2; ctx.SetSourceRGBA(GuiStyle.DialogLightBgColor[0] * 1.6, GuiStyle.DialogStrongBgColor[1] * 1.6, GuiStyle.DialogStrongBgColor[2] * 1.6, 1); ctx.LineWidth = strokeWidth * 1.75; ctx.StrokePreserve(); surface.Blur(3, 0, 0, (int)width - 1, (int)tabHeight - 1); ctx.SetSourceRGBA(new double[] { 45 / 255.0, 35 / 255.0, 33 / 255.0, 1 }); ctx.LineWidth = strokeWidth; ctx.Stroke(); selectedFont.SetupContext(ctx); DrawTextLineAt(ctx, tabs[i].Name, padding + 2, textOffsetY); generateTexture(surface, ref hoverTextures[i]); ctx.Dispose(); surface.Dispose(); } }
/// <summary> /// Draws the text with pre-set breaks. /// </summary> /// <param name="ctx">The context of the text.</param> /// <param name="font">The font of the text.</param> /// <param name="lines">The lines of text.</param> /// <param name="posX">The X position of the text.</param> /// <param name="posY">The Y position of the text.</param> /// <param name="boxWidth">The width of the box containing the text.</param> /// <param name="orientation">The orientation of the text.</param> public void DrawMultilineTextAt(Context ctx, CairoFont font, TextLine[] lines, double posX, double posY, double boxWidth, EnumTextOrientation orientation = EnumTextOrientation.Left) { ctx.Save(); Matrix m = ctx.Matrix; m.Translate(posX, posY); ctx.Matrix = m; font.SetupContext(ctx); DrawMultilineText(ctx, font, lines, orientation); ctx.Restore(); }
/// <summary> /// Turns the supplied text into line of text constrained by supplied flow path and starting at supplied start coordinates /// </summary> /// <param name="font">The font of the text.</param> /// <param name="fulltext">The text of the lines.</param> /// <param name="flowPath">The flow direction of text.</param> /// <param name="startOffsetX">The offset start position for X</param> /// <param name="startY">The offset start position for Y</param> /// <returns>The text broken up into lines.</returns> public TextLine[] Lineize(CairoFont font, string fulltext, TextFlowPath[] flowPath, double startOffsetX = 0, double startY = 0) { if (fulltext == null || fulltext.Length == 0) { return(new TextLine[0]); } ImageSurface surface = new ImageSurface(Format.Argb32, 1, 1); Context ctx = new Context(surface); font.SetupContext(ctx); TextLine[] textlines = Lineize(ctx, fulltext, flowPath, startOffsetX, startY, font.LineHeightMultiplier); ctx.Dispose(); surface.Dispose(); return(textlines); }
/// <summary> /// Gets the number of lines of text. /// </summary> /// <param name="font">The font of the text.</param> /// <param name="text">The text itself.</param> /// <param name="flowPath">The path for the text.</param> /// <param name="lineY">The height of the line</param> /// <returns>The number of lines.</returns> public int GetQuantityTextLines(CairoFont font, string text, TextFlowPath[] flowPath, double lineY = 0) { if (text == null || text.Length == 0) { return(0); } ImageSurface surface = new ImageSurface(Format.Argb32, 1, 1); Context ctx = new Context(surface); font.SetupContext(ctx); int quantityLines = Lineize(ctx, text, flowPath, 0, lineY, font.LineHeightMultiplier).Length; ctx.Dispose(); surface.Dispose(); return(quantityLines); }
public override void ComposeElements(Context ctx, ImageSurface surface) { Font.SetupContext(ctx); Bounds.CalcWorldBounds(); ComposeTextElements(ctx, surface); }
private void ComposeOverlays(bool isNotifyTabs = false) { double radius = scaled(1); double spacing = scaled(unscaledTabSpacing); double padding = scaled(unscaledTabPadding); for (int i = 0; i < tabs.Length; i++) { ImageSurface surface = new ImageSurface(Format.Argb32, tabWidths[i], (int)Bounds.InnerHeight + 1); Context ctx = genContext(surface); double degrees = Math.PI / 180.0; ctx.SetSourceRGBA(1, 1, 1, 0); ctx.Paint(); ctx.NewPath(); ctx.MoveTo(0, Bounds.InnerHeight + 1); ctx.LineTo(0, radius); ctx.Arc(radius, radius, radius, 180 * degrees, 270 * degrees); ctx.Arc(tabWidths[i] - radius, radius, radius, -90 * degrees, 0 * degrees); ctx.LineTo(tabWidths[i], Bounds.InnerHeight + 1); ctx.ClosePath(); double[] color = GuiStyle.DialogDefaultBgColor; ctx.SetSourceRGBA(color[0], color[1], color[2], color[3] * 0.75); ctx.Fill(); ctx.NewPath(); ctx.MoveTo(0, Bounds.InnerHeight); ctx.LineTo(0, radius); ctx.Arc(radius, radius, radius, 180 * degrees, 270 * degrees); ctx.Arc(tabWidths[i] - radius, radius, radius, -90 * degrees, 0 * degrees); ctx.LineTo(tabWidths[i], Bounds.InnerHeight); ShadePath(ctx, 2); if (isNotifyTabs) { notifyFont.SetupContext(ctx); } else { selectedFont.SetupContext(ctx); } DrawTextLineAt(ctx, tabs[i].Name, padding, 1); if (isNotifyTabs) { generateTexture(surface, ref notifyTextures[i]); } else { generateTexture(surface, ref hoverTextures[i]); } ctx.Dispose(); surface.Dispose(); } }
/// <summary> /// Takes a string of text and applies a texture to it. /// </summary> /// <param name="text">The text to texture.</param> /// <param name="font">The font of the text.</param> /// <param name="width">The width of the text.</param> /// <param name="height">The height of the text.</param> /// <param name="background">The background of the text. (default: none/null)</param> /// <returns>The texturized text.</returns> public LoadedTexture GenTextTexture(string text, CairoFont font, int width, int height, TextBackground background = null) { if (background == null) { background = defaultBackground; } ImageSurface surface = new ImageSurface(Format.Argb32, width, height); Context ctx = new Context(surface); if (background?.FillColor != null) { ctx.SetSourceRGBA(background.FillColor); GuiElement.RoundRectangle(ctx, 0, 0, width, height, background.Radius); ctx.Fill(); } if (background?.Shade == true) { ctx.SetSourceRGBA(GuiStyle.DialogLightBgColor[0] * 1.4, GuiStyle.DialogStrongBgColor[1] * 1.4, GuiStyle.DialogStrongBgColor[2] * 1.4, 1); ctx.LineWidth = 5;// background.BorderWidth * 1.75; GuiElement.RoundRectangle(ctx, 0, 0, width, height, background.Radius); ctx.StrokePreserve(); surface.Blur(6.2); ctx.SetSourceRGBA(new double[] { 45 / 255.0, 35 / 255.0, 33 / 255.0, 1 }); ctx.LineWidth = background.BorderWidth; ctx.Stroke(); } if (background?.BorderColor != null) { ctx.SetSourceRGBA(background.BorderColor); GuiElement.RoundRectangle(ctx, 0, 0, width, height, background.Radius); ctx.LineWidth = background.BorderWidth; ctx.Stroke(); } font.SetupContext(ctx); double fontHeight = font.GetFontExtents().Height; string[] lines = text.Split('\n'); for (int i = 0; i < lines.Length; i++) { lines[i] = lines[i].TrimEnd(); ctx.MoveTo(background.Padding, background.Padding + ctx.FontExtents.Ascent + i * fontHeight); if (font.StrokeWidth > 0) { ctx.TextPath(lines[i]); ctx.LineWidth = font.StrokeWidth; ctx.SetSourceRGBA(font.StrokeColor); ctx.StrokePreserve(); ctx.SetSourceRGBA(font.Color); ctx.Fill(); } else { ctx.ShowText(lines[i]); if (font.RenderTwice) { ctx.ShowText(lines[i]); } } } int textureId = capi.Gui.LoadCairoTexture(surface, true); surface.Dispose(); ctx.Dispose(); return(new LoadedTexture(capi) { TextureId = textureId, Width = width, Height = height }); }