protected override void OnPaint(PaintEventArgs e) { lock (bufferLock) { try { var gifEmotesOnScreen = new List <GifEmoteState>(); if (buffer == null) { buffer = context.Allocate(e.Graphics, ClientRectangle); } var g = buffer.Graphics; //var g = e.Graphics; g.Clear((App.ColorScheme.ChatBackground as SolidBrush).Color); var borderPen = Selected ? App.ColorScheme.ChatBorderFocused : App.ColorScheme.ChatBorder; g.SmoothingMode = SmoothingMode.AntiAlias; // DRAW MESSAGES var M = GetMessagesClone(); if (M != null && M.Length > 0) { var startIndex = Math.Max(0, (int)_scroll.Value); if (startIndex < M.Length) { var yStart = MessagePadding.Top - (int)(M[startIndex].Height * (_scroll.Value % 1)); var h = Height - MessagePadding.Top - MessagePadding.Bottom; if (startIndex < M.Length) { var y = yStart; //for (int i = 0; i < startIndex; i++) //{ // M[i].IsVisible = false; //} for (var i = startIndex; i < M.Length; i++) { var msg = M[i]; //msg.IsVisible = true; MessageRenderer.DrawMessage(g, msg, MessagePadding.Left, y, selection, i, !App.UseDirectX, gifEmotesOnScreen, allowMessageSeperator: AllowMessageSeperator); if (y - msg.Height > h) { //for (; i < M.Length; i++) //{ // M[i].IsVisible = false; //} break; } y += msg.Height; if (AppSettings.ChatShowLastReadMessageIndicator && LastReadMessage == msg && i != M.Length - 1) { g.FillRectangle(lastReadMessageBrush, 0, y, Width, 1); } } GifEmotesOnScreen = gifEmotesOnScreen; } if (App.UseDirectX) { SharpDX.Direct2D1.DeviceContextRenderTarget renderTarget = null; var dc = g.GetHdc(); renderTarget = new SharpDX.Direct2D1.DeviceContextRenderTarget(MessageRenderer.D2D1Factory, MessageRenderer.RenderTargetProperties); renderTarget.BindDeviceContext(dc, new RawRectangle(0, 0, Width, Height)); renderTarget.BeginDraw(); //renderTarget.TextRenderingParams = new SharpDX.DirectWrite.RenderingParams(Fonts.Factory, 1, 1, 1, SharpDX.DirectWrite.PixelGeometry.Flat, SharpDX.DirectWrite.RenderingMode.CleartypeGdiClassic); renderTarget.TextAntialiasMode = SharpDX.Direct2D1.TextAntialiasMode.Grayscale; var y = yStart; var brushes = new Dictionary <RawColor4, SCB>(); var textColor = App.ColorScheme.Text; var textBrush = new SCB(renderTarget, new RawColor4(textColor.R / 255f, textColor.G / 255f, textColor.B / 255f, 1)); for (var i = startIndex; i < M.Length; i++) { var msg = M[i]; foreach (var word in msg.Words) { if (word.Type == SpanType.Text) { SCB brush; if (word.Color == null) { brush = textBrush; } else { var hsl = word.Color.Value; if (App.ColorScheme.IsLightTheme) { if (hsl.Saturation > 0.4f) { hsl = hsl.WithSaturation(0.4f); } if (hsl.Luminosity > 0.5f) { hsl = hsl.WithLuminosity(0.5f); } } else { if (hsl.Luminosity < 0.5f) { hsl = hsl.WithLuminosity(0.5f); } if (hsl.Luminosity < 0.6f && hsl.Hue > 0.54444 && hsl.Hue < 0.8333) { hsl = hsl.WithLuminosity(hsl.Luminosity + (float)Math.Sin((hsl.Hue - 0.54444) / (0.8333 - 0.54444) * Math.PI) * hsl.Saturation * 0.2f); } if (hsl.Luminosity < 0.8f && (hsl.Hue < 0.06 || hsl.Hue > 0.92)) { hsl = hsl.WithLuminosity(hsl.Luminosity + (msg.HasAnyHighlightType(HighlightType.Highlighted) ? 0.27f : 0.1f) * hsl.Saturation); } } if (hsl.Luminosity >= 0.95f) { hsl = hsl.WithLuminosity(0.95f); } float r, _g, b; hsl.ToRGB(out r, out _g, out b); var color = new RawColor4(r, _g, b, 1f); if (!brushes.TryGetValue(color, out brush)) { brushes[color] = brush = new SCB(renderTarget, color); } } if (word.SplitSegments == null) { renderTarget.DrawText((string)word.Value, Fonts.GetTextFormat(word.Font), new RawRectangleF(MessagePadding.Left + word.X, y + word.Y, 10000, 10000), brush); } else { foreach (var split in word.SplitSegments) { renderTarget.DrawText(split.Item1, Fonts.GetTextFormat(word.Font), new RawRectangleF(MessagePadding.Left + split.Item2.X, y + split.Item2.Y, 10000, 10000), brush); } } } } if (y - msg.Height > h) { break; } y += msg.Height; } foreach (var b in brushes.Values) { b.Dispose(); } renderTarget.EndDraw(); textBrush.Dispose(); g.ReleaseHdc(dc); renderTarget.Dispose(); } { var y = yStart; Brush disabledBrush = new SolidBrush(Color.FromArgb(172, (App.ColorScheme.ChatBackground as SolidBrush)?.Color ?? Color.Black)); for (var i = startIndex; i < M.Length; i++) { var msg = M[i]; if (msg.Disabled) { g.SmoothingMode = SmoothingMode.None; g.FillRectangle(disabledBrush, 0, y + 1, Width, msg.Height - 1); } if (y - msg.Height > h) { break; } y += msg.Height; } disabledBrush.Dispose(); } } } g.DrawRectangle(borderPen, 0, 0, Width - 1, Height - 1); OnPaintOnBuffer(g); buffer.Render(e.Graphics); } catch (Exception exc) { exc.Log("graphics"); } } }
protected override void OnPaint(PaintEventArgs e) { var g = e.Graphics; g.FillRectangle(App.ColorScheme.ChatInputOuter, 0, 0, Width - 1, Height - 1); //g.FillRectangle(App.ColorScheme.ChatInputInner, 8, 4, Width - 17, Height - 9); //g.DrawRectangle(chatControl.Focused ? new Pen(App.ColorScheme.TextFocused) : App.ColorScheme.ChatInputBorder, 0, 0, Width - 1, Height - 1); g.DrawRectangle(App.ColorScheme.ChatInputBorder, 0, 0, Width - 1, Height - 1); if (chatControl.Focused) { g.FillRectangle(new SolidBrush(App.ColorScheme.TextFocused), 8, Height - messagePadding.Bottom, Width - 17 - 16, 1); } var sendMessage = Logic.Message; if (AppSettings.ChatInputShowMessageLength) { if (Logic.MessageLength > 1) { var messageLength = Logic.MessageLength.ToString(); var size = TextRenderer.MeasureText(e.Graphics, messageLength, Font, Size.Empty, App.DefaultTextFormatFlags); TextRenderer.DrawText(e.Graphics, messageLength, Font, new Point(Width - size.Width - 4, 0), Logic.MessageLength > 500 ? Color.Red : App.ColorScheme.Text, App.DefaultTextFormatFlags); } } if (sendMessage != null) { var selection = Logic.Selection; MessageRenderer.DrawMessage(e.Graphics, sendMessage, messagePadding.Left, messagePadding.Top, selection, 0, !App.UseDirectX, allowMessageSeperator: false); var spaceWidth = GuiEngine.Current.MeasureStringSize(g, FontType.Medium, " ").Width; var caretRect = new Rectangle?(); var x = 0; var isFirst = true; if (sendMessage.RawMessage.Length > 0) { foreach (var word in sendMessage.Words) { for (var j = 0; j < (word.SplitSegments?.Length ?? 1); j++) { var text = word.SplitSegments?[j].Item1 ?? (string)word.Value; if (j == 0) { if (isFirst) { isFirst = false; } else { if (x == Logic.CaretPosition) { caretRect = new Rectangle(messagePadding.Left + word.X - spaceWidth, word.Y + messagePadding.Top, 1, word.Height); goto end; } x++; } } for (var i = 0; i < text.Length; i++) { if (x == Logic.CaretPosition) { var size = GuiEngine.Current.MeasureStringSize(App.UseDirectX ? null : g, word.Font, text.Remove(i)); caretRect = new Rectangle(messagePadding.Left + (word.SplitSegments?[j].Item2.X ?? word.X) + size.Width, (word.SplitSegments?[j].Item2.Y ?? word.Y) + messagePadding.Top, 1, word.Height); goto end; } x++; } } } var _word = sendMessage.Words[sendMessage.Words.Count - 1]; var _lastSegmentText = _word.SplitSegments?[_word.SplitSegments.Length - 1].Item1; var _lastSegment = _word.SplitSegments?[_word.SplitSegments.Length - 1].Item2; caretRect = _word.SplitSegments == null ? new Rectangle(messagePadding.Left + _word.X + _word.Width, _word.Y + messagePadding.Top, 1, _word.Height) : new Rectangle(messagePadding.Left + _lastSegment.Value.X + GuiEngine.Current.MeasureStringSize(App.UseDirectX ? null : g, _word.Font, _lastSegmentText).Width, _lastSegment.Value.Y + messagePadding.Top, 1, _lastSegment.Value.Height); end: if (caretRect != null) { g.FillRectangle(App.ColorScheme.TextCaret, caretRect.Value); } } if (App.UseDirectX) { SharpDX.Direct2D1.DeviceContextRenderTarget renderTarget = null; var dc = IntPtr.Zero; dc = g.GetHdc(); renderTarget = new SharpDX.Direct2D1.DeviceContextRenderTarget(MessageRenderer.D2D1Factory, MessageRenderer.RenderTargetProperties); renderTarget.BindDeviceContext(dc, new RawRectangle(0, 0, Width, Height)); renderTarget.BeginDraw(); var brushes = new Dictionary <RawColor4, SCB>(); var textColor = App.ColorScheme.Text; var textBrush = new SCB(renderTarget, new RawColor4(textColor.R / 255f, textColor.G / 255f, textColor.B / 255f, 1)); foreach (var word in sendMessage.Words) { if (word.Type == SpanType.Text) { if (word.SplitSegments == null) { renderTarget.DrawText((string)word.Value, Fonts.GetTextFormat(word.Font), new RawRectangleF(messagePadding.Left + word.X, messagePadding.Top + word.Y, 10000, 1000), textBrush); } else { foreach (var split in word.SplitSegments) { renderTarget.DrawText(split.Item1, Fonts.GetTextFormat(word.Font), new RawRectangleF(messagePadding.Left + split.Item2.X, messagePadding.Top + split.Item2.Y, 10000, 1000), textBrush); } } } } renderTarget.EndDraw(); textBrush.Dispose(); g.ReleaseHdc(dc); renderTarget.Dispose(); } } }