public static Gdk.Color GetGdkColor(TextColor textColor) { if (textColor == null) { throw new ArgumentNullException("textColor"); } return GetGdkColor(textColor.HexCode); }
public void ToStringPerformance() { int runs = 1000; var color = new TextColor(0, 0, 0); DateTime start, stop; start = DateTime.UtcNow; for (int i = 0; i < runs; i++) { color.ToString(); } stop = DateTime.UtcNow; Console.WriteLine( "ToString(): avg: {0:0.00} ms", (stop - start).TotalMilliseconds / runs ); }
public TextMessagePartModel(TextColor fgColor, TextColor bgColor, bool underline, bool bold, bool italic, string text, bool highlight) : base(highlight) { if (fgColor != null) { f_ForegroundColor = fgColor; } else { f_ForegroundColor = TextColor.None; } if (bgColor != null) { f_BackgroundColor = bgColor; } else { f_BackgroundColor = TextColor.None; } f_Underline = underline; f_Bold = bold; f_Italic = italic; f_Text = text; }
public TextMessagePartModel() : base() { f_ForegroundColor = new TextColor(); f_BackgroundColor = new TextColor(); }
public override MessageBuilder AppendMessage(string msg) { msg = msg ?? ""; if (msg.Length == 0) { return(this); } // strip color and formatting if configured if (StripColors) { msg = Regex.Replace(msg, (char)IrcControlCode.Color + "[0-9]{1,2}(,[0-9]{1,2})?", String.Empty); } if (StripFormattings) { msg = Regex.Replace(msg, String.Format("({0}|{1}|{2}|{3})", (char)IrcControlCode.Bold, (char)IrcControlCode.Clear, (char)IrcControlCode.Italic, (char)IrcControlCode.Underline), String.Empty); } // convert * / _ to mIRC control characters string[] messageParts = msg.Split(new char[] { ' ' }); // better regex? \*([^ *]+)\* //string pattern = @"^({0})([A-Za-z0-9]+?){0}$"; string pattern = @"^({0})([^ *]+){0}$"; for (int i = 0; i < messageParts.Length; i++) { messageParts[i] = Regex.Replace(messageParts[i], String.Format(pattern, @"\*"), (char)IrcControlCode.Bold + "$1$2$1" + (char)IrcControlCode.Bold); messageParts[i] = Regex.Replace(messageParts[i], String.Format(pattern, "_"), (char)IrcControlCode.Underline + "$1$2$1" + (char)IrcControlCode.Underline); messageParts[i] = Regex.Replace(messageParts[i], String.Format(pattern, "/"), (char)IrcControlCode.Italic + "$1$2$1" + (char)IrcControlCode.Italic); } msg = String.Join(" ", messageParts); // crash: ^C^C0,7Dj Ler #Dj KanaL?na Girmek ZorunDaD?rLar UnutMay?N @>'^C0,4WwW.MaViGuL.NeT ^C4]^O ^C4]' // parse colors bool bold = false; bool underline = false; bool italic = false; bool color = false; TextColor fg_color = IrcTextColor.Normal; TextColor bg_color = IrcTextColor.Normal; bool controlCharFound; do { string submessage; int controlPos = msg.IndexOfAny(IrcControlChars); if (controlPos > 0) { // control char found and we have normal text infront controlCharFound = true; submessage = msg.Substring(0, controlPos); msg = msg.Substring(controlPos); } else if (controlPos != -1) { // control char found controlCharFound = true; char controlChar = msg.Substring(controlPos, 1)[0]; IrcControlCode controlCode = (IrcControlCode)controlChar; string controlChars = controlChar.ToString(); switch (controlCode) { case IrcControlCode.Clear: #if LOG4NET && MSG_DEBUG Logger.Debug("AppendMessage(): found clear control character"); #endif bold = false; underline = false; italic = false; color = false; fg_color = IrcTextColor.Normal; bg_color = IrcTextColor.Normal; break; case IrcControlCode.Bold: #if LOG4NET && MSG_DEBUG Logger.Debug("AppendMessage(): found bold control character"); #endif bold = !bold; break; case IrcControlCode.Underline: #if LOG4NET && MSG_DEBUG Logger.Debug("AppendMessage(): found underline control character"); #endif underline = !underline; break; case IrcControlCode.Italic: #if LOG4NET && MSG_DEBUG Logger.Debug("AppendMessage(): found italic control character"); #endif italic = !italic; break; case IrcControlCode.Color: #if LOG4NET && MSG_DEBUG Logger.Debug("AppendMessage(): found color control character"); #endif color = !color; string colorMessage = msg.Substring(controlPos); #if LOG4NET && MSG_DEBUG Logger.Debug("AppendMessage(): colorMessage: '" + colorMessage + "'"); #endif Match match = Regex.Match(colorMessage, "^" + (char)IrcControlCode.Color + "(?<fg>[0-9][0-9]?)(,(?<bg>[0-9][0-9]?))?"); if (match.Success) { controlChars = match.Value; int color_code; if (match.Groups["fg"] != null) { #if LOG4NET && MSG_DEBUG Logger.Debug("AppendMessage(): match.Groups[fg].Value: " + match.Groups["fg"].Value); #endif try { color_code = Int32.Parse(match.Groups["fg"].Value); fg_color = IrcColorToTextColor(color_code); } catch (FormatException) { fg_color = IrcTextColor.Normal; } } if (match.Groups["bg"] != null) { #if LOG4NET && MSG_DEBUG Logger.Debug("AppendMessage(): match.Groups[bg].Value: " + match.Groups["bg"].Value); #endif try { color_code = Int32.Parse(match.Groups["bg"].Value); bg_color = IrcColorToTextColor(color_code); } catch (FormatException) { bg_color = IrcTextColor.Normal; } } } else { controlChars = controlChar.ToString(); fg_color = IrcTextColor.Normal; bg_color = IrcTextColor.Normal; } #if LOG4NET && MSG_DEBUG Logger.Debug("AppendMessage(): fg_color.HexCode: " + String.Format("0x{0:X6}", fg_color.HexCode)); Logger.Debug("AppendMessage(): bg_color.HexCode: " + String.Format("0x{0:X6}", bg_color.HexCode)); #endif break; } #if LOG4NET && MSG_DEBUG Logger.Debug("AppendMessage(): controlChars.Length: " + controlChars.Length); #endif // check if there are more control chars in the rest of the message int nextControlPos = msg.IndexOfAny(IrcControlChars, controlPos + controlChars.Length); if (nextControlPos != -1) { // more control chars found submessage = msg.Substring(controlChars.Length, nextControlPos - controlChars.Length); msg = msg.Substring(nextControlPos); } else { // no next control char // skip the control chars submessage = msg.Substring(controlChars.Length); msg = String.Empty; } } else { // no control char, nothing to do controlCharFound = false; submessage = msg; } TextMessagePartModel msgPart = new TextMessagePartModel(); msgPart.Text = submessage; msgPart.Bold = bold; msgPart.Underline = underline; msgPart.Italic = italic; msgPart.ForegroundColor = fg_color; msgPart.BackgroundColor = bg_color; AppendText(msgPart); } while (controlCharFound); return(this); }
public bool Equals(TextColor value) { if ((object) value == null) { return false; } return f_Value == value.Value; }
public static TextColor GetBestTextColor(TextColor fgColor, TextColor bgColor) { return GetBestTextColor(fgColor, bgColor, TextColorContrast.Medium); }
public static double GetBritnessDifference(TextColor color1, TextColor color2) { double br1 = (299d * color1.Red + 587d * color1.Green + 114d * color1.Blue) / 1000d; double br2 = (299d * color2.Red + 587d * color2.Green + 114d * color2.Blue) / 1000d; return Math.Abs(br1 - br2); }
public static TextColor GetBestTextColor(TextColor fgColor, TextColor bgColor) { return(GetBestTextColor(fgColor, bgColor, TextColorContrast.Medium)); }
public static Color GetColor(TextColor textColor) { return GetColor(textColor.HexCode); }
public TextMessagePartModel(TextColor fgColor, TextColor bgColor, bool underline, bool bold, bool italic, string text) : this(fgColor, bgColor, underline, bold, italic, text, false) { }
private string _GetTextTagName(TextColor fgColor, TextColor bgColor) { string hexcode; string tagname; if (fgColor != null) { hexcode = fgColor.HexCode; tagname = "fg_color:" + hexcode; } else if (bgColor != null) { hexcode = bgColor.HexCode; tagname = "bg_color:" + hexcode; } else { return null; } if (_OutputTextTagTable.Lookup(tagname) == null) { int red = Int16.Parse(hexcode.Substring(0, 2), NumberStyles.HexNumber); int green = Int16.Parse(hexcode.Substring(2, 2), NumberStyles.HexNumber); int blue = Int16.Parse(hexcode.Substring(4, 2), NumberStyles.HexNumber); Gdk.Color c = new Gdk.Color((byte)red, (byte)green, (byte)blue); Gtk.TextTag tt = new Gtk.TextTag(tagname); if (fgColor != null) { tt.ForegroundGdk = c; } else if (bgColor != null) { tt.BackgroundGdk = c; } #if LOG4NET _Logger.Debug("_GetTextTagName(): adding: " + tagname + " to _OutputTextTagTable"); #endif _OutputTextTagTable.Add(tt); } return tagname; }
/* public static TextColor GetBestTextColor(TextColor fgColor, TextColor bgColor) { if (fgColor == null) { throw new ArgumentNullException("fgColor"); } if (bgColor == null) { throw new ArgumentNullException("bgColor"); } int bestColor = fgColor.Value; int minDiff = int.Parse("303030", NumberStyles.HexNumber); // Min difference int maxHex = int.Parse("FFFFFF", NumberStyles.HexNumber); // White, so we don't get higher. int fgIntColor = fgColor.Value; int bgIntColor = bgColor.Value; int lowerDiff; if (bgIntColor - minDiff > 0) { // If the bgColor - the difference is still less than black... lowerDiff = bgIntColor - minDiff; // ... set lower diff to the value. } else { // else set it to black. lowerDiff = 0; } int upperDiff; if (bgIntColor + minDiff < maxHex) { // If the bgColor + the difference is still less than white... upperDiff = bgIntColor + minDiff; // ... set the upper diff to the value. } else { // Else set it to white. upperDiff = maxHex; } if (fgIntColor > lowerDiff && fgIntColor < upperDiff) { // If the foreground color is within the range of the minimum accepted difference... bestColor = maxHex - fgIntColor; // ... invert the color. if (bestColor > lowerDiff && bestColor < upperDiff) { // If it happens that it's still within the range after the inversion... if (bestColor < bgIntColor ) { // ... see if it's bigger or smaller than the background color... bestColor = fgIntColor - minDiff; // ... so we can either substract the difference ... } else { bestColor = fgIntColor + minDiff; // ... or add the difference. } } } // cap color to allowed values if (bestColor < 0) { bestColor = 0; } if (bestColor > maxHex) { bestColor = maxHex; } return new TextColor(bestColor); } */ public static TextColor GetBestTextColor(TextColor fgColor, TextColor bgColor) { if (fgColor == null) { throw new ArgumentNullException("fgColor"); } if (bgColor == null) { throw new ArgumentNullException("bgColor"); } int[] fgColors = { fgColor.Red, fgColor.Green, fgColor.Blue }; int[] bgColors = { bgColor.Red, bgColor.Green, bgColor.Blue }; int[] bestColors = new int[3]; for (int i = 0; i < 3; i++ ) { bestColors[i] = (Math.Abs(bgColors[i] - fgColors[i]) < 0x40) ? fgColors[i] | 0x80 : fgColors[i]; } return new TextColor((byte) bestColors[0], (byte) bestColors[1], (byte) bestColors[2]); }
public void GetBestTextColorPerformance() { var colors = new List <TextColor>(); colors.Add(TextColor.Parse("#000000")); colors.Add(TextColor.Parse("#000000")); colors.Add(TextColor.Parse("#FF0000")); colors.Add(TextColor.Parse("#00FF00")); colors.Add(TextColor.Parse("#0000FF")); colors.Add(TextColor.Parse("#FF00FF")); colors.Add(TextColor.Parse("#FFFF00")); colors.Add(TextColor.Parse("#FFFFFF")); colors.Add(TextColor.Parse("#1E0DD6")); colors.Add(TextColor.Parse("#1E0DD6")); colors.Add(TextColor.Parse("#219207")); colors.Add(TextColor.Parse("#429FB0")); colors.Add(TextColor.Parse("#352878")); colors.Add(TextColor.Parse("#52248B")); colors.Add(TextColor.Parse("#603D40")); colors.Add(TextColor.Parse("#872F56")); colors.Add(TextColor.Parse("#97608C")); colors.Add(TextColor.Parse("#055A4F")); colors.Add(TextColor.Parse("#05730C")); colors.Add(TextColor.Parse("#A45DDA")); colors.Add(TextColor.Parse("#279C2A")); colors.Add(TextColor.Parse("#D24F81")); colors.Add(TextColor.Parse("#45D6FA")); colors.Add(TextColor.Parse("#31DD0B")); colors.Add(TextColor.Parse("#429FB0")); colors.Add(TextColor.Parse("#05FC8F")); colors.Add(TextColor.Parse("#C1FFEF")); colors.Add(TextColor.Parse("#C1FFEF")); colors.Add(TextColor.Parse("#E4DA22")); var colorCombinations = new List <KeyValuePair <TextColor, TextColor> >(); // bright background var bgBright = TextColor.Parse("#EBEBEB"); foreach (var color in colors) { colorCombinations.Add( new KeyValuePair <TextColor, TextColor>(color, bgBright) ); } // dark background var bgDark = TextColor.Parse("#2E3436"); foreach (var color in colors) { colorCombinations.Add( new KeyValuePair <TextColor, TextColor>(color, bgDark) ); } // warmup the TextColorTools cache (trigger static ctors) TextColorTools.GetBestTextColor(TextColor.Black, TextColor.Black); DateTime dstart = DateTime.UtcNow; DateTime dstop = DateTime.UtcNow; Console.WriteLine("DateTime took: " + (dstop - dstart).TotalMilliseconds + " ms"); int i = 0; foreach (var colorCombination in colorCombinations) { DateTime start, stop; start = DateTime.UtcNow; var best = TextColorTools.GetBestTextColor( colorCombination.Key, colorCombination.Value ); stop = DateTime.UtcNow; Console.WriteLine( "GetBestTextColor(): #{0:00} {1}|{2}={3} took: {4:0.00} ms", i++, colorCombination.Key, colorCombination.Value, best, (stop - start).TotalMilliseconds ); } }
public static TextColor GetNearestColor(TextColor color, IEnumerable<TextColor> palette) { if (palette == null) { throw new ArgumentNullException("palette"); } TextColor nearestColor = null; Dictionary<TextColor, TextColor> cache; if (NearestColors.TryGetValue(palette, out cache)) { if (cache.TryGetValue(color, out nearestColor)) { return nearestColor; } } else { cache = new Dictionary<TextColor, TextColor>(1024); NearestColors.Add(palette, cache); } var hslColor1 = ToHSL(color); double nearestDifference = Double.MaxValue; foreach (var color2 in palette) { // compute the Euclidean distance between the two HSL colors // without root square as we only compare the values // see http://en.wikipedia.org/wiki/Color_difference#Delta_E var hslColor2 = ToHSL(color2); var H1 = hslColor1.Hue; var S1 = hslColor1.Saturation; var L1 = hslColor1.Lightness; var H2 = hslColor2.Hue; var S2 = hslColor2.Saturation; var L2 = hslColor2.Lightness; var Hdelta = H1 - H2; var Sdelta = S1 - S2; var Ldelta = L1 - L2; var deltaE = (Hdelta * Hdelta) + (Sdelta * Sdelta) + (Ldelta * Ldelta); if (deltaE < nearestDifference) { nearestDifference = deltaE; nearestColor = color2; } if (deltaE == 0d) { // found perfect match, can't get better than that break; } } cache.Add(color, nearestColor); return nearestColor; }
public static TextColor GetBestTextColor(TextColor fgColor, TextColor bgColor, TextColorContrast neededContrast) { if (fgColor == null) { throw new ArgumentNullException("fgColor"); } if (bgColor == null) { throw new ArgumentNullException("bgColor"); } TextColor bestColor; int key = fgColor.Value ^ bgColor.Value ^ (int)neededContrast; if (f_BestContrastColors.TryGetValue(key, out bestColor)) { return(bestColor); } double brDiff = GetBritnessDifference(bgColor, TextColor.White); int modifier = 0; // for bright backgrounds we need to go from bright to dark colors // for better contrast and for dark backgrounds the opposite if (brDiff < 127) { // bright background modifier = -10; } else { // dark background modifier = 10; } double lastDifference = 0; bestColor = fgColor; int attempts = 1; while (true) { double difference = GetLuminanceDifference(bestColor, bgColor); double needed = ((int)neededContrast) / 10d; if (difference > needed) { break; } #if LOG4NET && COLOR_DEBUG f_Logger.Debug("GetBestTextColor(): color has bad contrast: " + bestColor + " difference: " + difference + " needed: " + needed); #endif // change the fg color int red = bestColor.Red + modifier; int green = bestColor.Green + modifier; int blue = bestColor.Blue + modifier; // cap to allowed values if (modifier > 0) { if (red > 255) { red = 255; } if (green > 255) { green = 255; } if (blue > 255) { blue = 255; } } else { if (red < 0) { red = 0; } if (green < 0) { green = 0; } if (blue < 0) { blue = 0; } } bestColor = new TextColor((byte)red, (byte)green, (byte)blue); // in case we found no good color if (bestColor == TextColor.White || bestColor == TextColor.Black) { break; } attempts++; } #if LOG4NET && COLOR_DEBUG f_Logger.Debug( String.Format( "GetBestTextColor(): found good contrast: {0}|{1}={2} " + "({3}) attempts: {4}", fgColor, bgColor, bestColor, neededContrast, attempts ) ); #endif f_BestContrastColors.Add(key, bestColor); return(bestColor); }
// algorithm ported from JavaScript to C# from: // http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript internal static HslColor ToHSL(TextColor color) { var R = color.Red / 255d; var G = color.Green / 255d; var B = color.Blue / 255d; var max = Math.Max(Math.Max(R, G), B); var min = Math.Min(Math.Min(R, G), B); double H = 0d, S, L; var range = max + min; L = range / 2d; if (max == min) { S = 0d; // achromatic } else { var diff = max - min; S = L > 0.5d ? diff / (2 - diff) : diff / range; if (max == R) { H = (G - B) / diff + (G < B ? 6d : 0d); } else if (max == G) { H = (B - R) / diff + 2; } else if (max == B) { H = (R - G) / diff + 4; } H /= 6; } return new HslColor(H, S, L); }
public override bool Equals(object obj) { TextColor value = obj as TextColor; return(Equals(value)); }
void ParseStyle(XmlNode style, TextMessagePartModel submodel) { if (style == null) { return; } var properties = style.InnerText.Split(';'); foreach (string property in properties) { var colonpos = property.IndexOf(':'); if (colonpos == -1) { continue; } string name = property.Substring(0, colonpos).Trim(); string value = property.Substring(colonpos + 1).Trim(); switch (name) { case "background": value = value.Split(' ')[0]; submodel.BackgroundColor = TextColor.Parse(value); break; case "background-color": submodel.BackgroundColor = TextColor.Parse(value); break; case "color": submodel.ForegroundColor = TextColor.Parse(value); break; case "font-style": if (value == "normal") { submodel.Italic = false; } else if (value == "inherit") { } else { submodel.Italic = true; } break; case "font-weight": if (value == "normal") { submodel.Bold = false; } else if (value == "inherit") { } else { submodel.Bold = true; } break; case "text-decoration": { foreach (string val in value.Split(' ')) { if (val == "underline") { submodel.Underline = true; } } } break; case "font-family": case "font-size": case "text-align": case "margin-left": case "margin-right": default: // ignore formatting break; } } }
// algorithm ported from PHP to C# from: // http://www.splitbrain.org/blog/2008-09/18-calculating_color_contrast_with_php public static double GetLuminanceDifference(TextColor color1, TextColor color2) { double L1 = 0.2126d * Math.Pow(color1.Red / 255d, 2.2d) + 0.7152d * Math.Pow(color1.Green / 255d, 2.2d) + 0.0722d * Math.Pow(color1.Blue / 255d, 2.2d); double L2 = 0.2126d * Math.Pow(color2.Red / 255d, 2.2d) + 0.7152d * Math.Pow(color2.Green / 255d, 2.2d) + 0.0722d * Math.Pow(color2.Blue / 255d, 2.2d); if (L1 > L2) { return (L1 + 0.05d) / (L2 + 0.05d); } else { return (L2 + 0.05d) / (L1 + 0.05d); } }
public TextMessagePartModel(TextMessagePartModel msgPart) { if (msgPart == null) { throw new ArgumentNullException("msgPart"); } f_ForegroundColor = msgPart.ForegroundColor; f_BackgroundColor = msgPart.BackgroundColor; f_Underline = msgPart.Underline; f_Bold = msgPart.Bold; f_Italic = msgPart.Italic; f_Text = msgPart.Text; }
public static TextColor GetBestTextColor(TextColor fgColor, TextColor bgColor, TextColorContrast neededContrast) { if (fgColor == null) { throw new ArgumentNullException("fgColor"); } if (bgColor == null) { throw new ArgumentNullException("bgColor"); } TextColor bestColor; int key = fgColor.Value ^ bgColor.Value ^ (int) neededContrast; if (f_BestContrastColors.TryGetValue(key, out bestColor)) { return bestColor; } double brDiff = GetBritnessDifference(bgColor, TextColor.White); int modifier = 0; // for bright backgrounds we need to go from bright to dark colors // for better contrast and for dark backgrounds the opposite if (brDiff < 127) { // bright background modifier = -10; } else { // dark background modifier = 10; } double lastDifference = 0; bestColor = fgColor; int attempts = 1; while (true) { double difference = GetLuminanceDifference(bestColor, bgColor); double needed = ((int) neededContrast) / 10d; if (difference > needed) { break; } #if LOG4NET && COLOR_DEBUG f_Logger.Debug("GetBestTextColor(): color has bad contrast: " + bestColor + " difference: " + difference + " needed: " + needed); #endif // change the fg color int red = bestColor.Red + modifier; int green = bestColor.Green + modifier; int blue = bestColor.Blue + modifier; // cap to allowed values if (modifier > 0) { if (red > 255) { red = 255; } if (green > 255) { green = 255; } if (blue > 255) { blue = 255; } } else { if (red < 0) { red = 0; } if (green < 0) { green = 0; } if (blue < 0) { blue = 0; } } bestColor = new TextColor((byte) red, (byte) green, (byte) blue); // in case we found no good color if (bestColor == TextColor.White || bestColor == TextColor.Black) { break; } attempts++; } #if LOG4NET && COLOR_DEBUG f_Logger.Debug( String.Format( "GetBestTextColor(): found good contrast: {0}|{1}={2} " + "({3}) attempts: {4}", fgColor, bgColor, bestColor, neededContrast, attempts ) ); #endif f_BestContrastColors.Add(key, bestColor); return bestColor; }
protected override void SetObjectData(SerializationReader sr) { base.SetObjectData(sr); f_ForegroundColor = new TextColor(sr.ReadInt32()); f_BackgroundColor = new TextColor(sr.ReadInt32()); f_Underline = sr.ReadBoolean(); f_Bold = sr.ReadBoolean(); f_Italic = sr.ReadBoolean(); f_Text = sr.ReadString(); }
private string GetTextTagName(TextColor fgColor, TextColor bgColor) { string hexcode; string tagname; if (fgColor != null) { hexcode = fgColor.HexCode; tagname = "fg_color:" + hexcode; } else if (bgColor != null) { hexcode = bgColor.HexCode; tagname = "bg_color:" + hexcode; } else { return null; } if (_MessageTextTagTable.Lookup(tagname) == null) { int red = Int16.Parse(hexcode.Substring(0, 2), NumberStyles.HexNumber); int green = Int16.Parse(hexcode.Substring(2, 2), NumberStyles.HexNumber); int blue = Int16.Parse(hexcode.Substring(4, 2), NumberStyles.HexNumber); Gdk.Color c = new Gdk.Color((byte)red, (byte)green, (byte)blue); Gtk.TextTag tt = new Gtk.TextTag(tagname); if (fgColor != null) { tt.ForegroundGdk = c; } else if (bgColor != null) { tt.BackgroundGdk = c; } _MessageTextTagTable.Add(tt); } return tagname; }
private void _IrcMessageToMessageModel(ref MessageModel msg, string message) { // strip color and formatting if configured if ((bool)Session.UserConfig["Interface/Notebook/StripColors"]) { message = Regex.Replace(message, (char)IrcControlCode.Color + "[0-9]{1,2}(,[0-9]{1,2})?", String.Empty); } if ((bool)Session.UserConfig["Interface/Notebook/StripFormattings"]) { message = Regex.Replace(message, String.Format("({0}|{1}|{2}|{3})", (char)IrcControlCode.Bold, (char)IrcControlCode.Clear, (char)IrcControlCode.Italic, (char)IrcControlCode.Underline), String.Empty); } // convert * / _ to mIRC control characters string[] messageParts = message.Split(new char[] {' '}); // better regex? \*([^ *]+)\* //string pattern = @"^({0})([A-Za-z0-9]+?){0}$"; string pattern = @"^({0})([^ *]+){0}$"; for (int i = 0; i < messageParts.Length; i++) { messageParts[i] = Regex.Replace(messageParts[i], String.Format(pattern, @"\*"), (char)IrcControlCode.Bold + "$1$2$1" + (char)IrcControlCode.Bold); messageParts[i] = Regex.Replace(messageParts[i], String.Format(pattern, "_"), (char)IrcControlCode.Underline + "$1$2$1" + (char)IrcControlCode.Underline); messageParts[i] = Regex.Replace(messageParts[i], String.Format(pattern, "/"), (char)IrcControlCode.Italic + "$1$2$1" + (char)IrcControlCode.Italic); } message = String.Join(" ", messageParts); // crash: ^C^C0,7Dj Ler #Dj KanaL?na Girmek ZorunDaD?rLar UnutMay?N @>'^C0,4WwW.MaViGuL.NeT ^C4]^O ^C4]' // parse colors bool bold = false; bool underline = false; bool italic = false; bool color = false; TextColor fg_color = IrcTextColor.Normal; TextColor bg_color = IrcTextColor.Normal; bool controlCharFound; do { string submessage; int controlPos = message.IndexOfAny(_IrcControlChars); if (controlPos > 0) { // control char found and we have normal text infront controlCharFound = true; submessage = message.Substring(0, controlPos); message = message.Substring(controlPos); } else if (controlPos != -1) { // control char found controlCharFound = true; char controlChar = message.Substring(controlPos, 1)[0]; IrcControlCode controlCode = (IrcControlCode)controlChar; string controlChars = controlChar.ToString(); switch (controlCode) { case IrcControlCode.Clear: #if LOG4NET _Logger.Debug("_IrcMessageToMessageModel(): found clear control character"); #endif bold = false; underline = false; italic = false; color = false; fg_color = IrcTextColor.Normal; bg_color = IrcTextColor.Normal; break; case IrcControlCode.Bold: #if LOG4NET _Logger.Debug("_IrcMessageToMessageModel(): found bold control character"); #endif bold = !bold; break; case IrcControlCode.Underline: #if LOG4NET _Logger.Debug("_IrcMessageToMessageModel(): found underline control character"); #endif underline = !underline; break; case IrcControlCode.Italic: #if LOG4NET _Logger.Debug("_IrcMessageToMessageModel(): found italic control character"); #endif italic = !italic; break; case IrcControlCode.Color: #if LOG4NET _Logger.Debug("_IrcMessageToMessageModel(): found color control character"); #endif color = !color; string colorMessage = message.Substring(controlPos); #if LOG4NET _Logger.Debug("_IrcMessageToMessageModel(): colorMessage: '" + colorMessage + "'"); #endif Match match = Regex.Match(colorMessage, (char)IrcControlCode.Color + "(?<fg>[0-9][0-9]?)(,(?<bg>[0-9][0-9]?))?"); if (match.Success) { controlChars = match.Value; int color_code; if (match.Groups["fg"] != null) { #if LOG4NET _Logger.Debug("_IrcMessageToMessageModel(): match.Groups[fg].Value: " + match.Groups["fg"].Value); #endif try { color_code = Int32.Parse(match.Groups["fg"].Value); fg_color = _IrcTextColorToTextColor(color_code); } catch (FormatException) { fg_color = IrcTextColor.Normal; } } if (match.Groups["bg"] != null) { #if LOG4NET _Logger.Debug("_IrcMessageToMessageModel(): match.Groups[bg].Value: " + match.Groups["bg"].Value); #endif try { color_code = Int32.Parse(match.Groups["bg"].Value); bg_color = _IrcTextColorToTextColor(color_code); } catch (FormatException) { bg_color = IrcTextColor.Normal; } } } else { controlChars = controlChar.ToString(); fg_color = IrcTextColor.Normal; bg_color = IrcTextColor.Normal; } #if LOG4NET _Logger.Debug("_IrcMessageToMessageModel(): fg_color.HexCode: " + String.Format("0x{0:X6}", fg_color.HexCode)); _Logger.Debug("_IrcMessageToMessageModel(): bg_color.HexCode: " + String.Format("0x{0:X6}", bg_color.HexCode)); #endif break; } #if LOG4NET _Logger.Debug("_IrcMessageToMessageModel(): controlChars.Length: " + controlChars.Length); #endif // check if there are more control chars in the rest of the message int nextControlPos = message.IndexOfAny(_IrcControlChars, controlPos + controlChars.Length); if (nextControlPos != -1) { // more control chars found submessage = message.Substring(controlChars.Length, nextControlPos - controlChars.Length); message = message.Substring(nextControlPos); } else { // no next control char // skip the control chars submessage = message.Substring(controlChars.Length); message = String.Empty; } } else { // no control char, nothing to do controlCharFound = false; submessage = message; } bool highlight = false; // BUG: don't highlight everything, like nicknames, maybe require whitespace? if (submessage.IndexOf(_IrcClient.Nickname, StringComparison.CurrentCultureIgnoreCase) != -1) { highlight = true; string highlightColor = (string) Session.UserConfig["Interface/Notebook/Tab/HighlightColor"]; fg_color = new TextColor(Int32.Parse(highlightColor.Substring(1), NumberStyles.HexNumber)); } TextMessagePartModel msgPart = new TextMessagePartModel(); msgPart.Text = submessage; msgPart.Bold = bold; msgPart.Underline = underline; msgPart.Italic = italic; msgPart.ForegroundColor = fg_color; msgPart.BackgroundColor = bg_color; msgPart.IsHighlight = highlight; msg.MessageParts.Add(msgPart); } while (controlCharFound); // parse URLs ParseUrls(msg); }