internal void SetColours(Stream stream = null, VoidDelegate callback = null) { GameBase.RunBackgroundThread(delegate { List <Color> newColours = new List <Color>(); if (stream != null) { try { using (System.Drawing.Bitmap b = (System.Drawing.Bitmap)System.Drawing.Image.FromStream(stream, false, false)) for (int i = 0; i < 50; i++) { newColours.Add(OsuMathHelper.CConvert(b.GetPixel(RNG.Next(b.Width), RNG.Next(b.Height)))); } return; } catch (ArgumentException) { } finally { stream.Dispose(); } } newColours.Add(new Color(5, 25, 81)); newColours.Add(new Color(16, 56, 135)); newColours.Add(new Color(3, 3, 5)); newColours.Add(new Color(91, 170, 207)); newColours.Add(new Color(140, 152, 150)); for (int i = 0; i < 2; i++) { byte c = (byte)RNG.Next(224, 256); newColours.Add(new Color(c, c, c)); } GameBase.Scheduler.Add(delegate { SetColours(newColours); if (callback != null) { callback(); } }); }); }
private void SongSetup_Load(object sender, EventArgs e) { combos = new[] { combo1, combo2, combo3, combo4, combo5, combo6, combo7, combo8 }; List <String> files = (BeatmapManager.Current.InOszContainer) ? new List <string>(BeatmapManager.Current.Package.MapFiles) : null; //Restrict anything that can alter the filename of the difficulty when we are in the editor with a overridden difficulty //unless we are using the save as dialog. bool fRestrict = files != null && !newDifficulty && files.Exists((f) => f.EndsWith(Path.GetFileName(BeatmapManager.Current.Filename))); version.Enabled = !fRestrict; title.Text = !string.IsNullOrEmpty(BeatmapManager.Current.TitleUnicode) ? BeatmapManager.Current.TitleUnicode : BeatmapManager.Current.Title; titleRomanised.Text = string.IsNullOrEmpty(BeatmapManager.Current.Title) ? GeneralHelper.AsciiOnly(BeatmapManager.Current.TitleUnicode) : BeatmapManager.Current.Title; artist.Text = !string.IsNullOrEmpty(BeatmapManager.Current.ArtistUnicode) ? BeatmapManager.Current.ArtistUnicode : BeatmapManager.Current.Artist; artistRomanised.Text = string.IsNullOrEmpty(BeatmapManager.Current.Artist) ? GeneralHelper.AsciiOnly(BeatmapManager.Current.ArtistUnicode) : BeatmapManager.Current.Artist; creator.Text = (BeatmapManager.Current.Creator.Length > 0 ? BeatmapManager.Current.Creator : ConfigManager.sUsername.Value); source.Text = BeatmapManager.Current.Source; if (creator.Text == ConfigManager.sUsername || fRestrict) { creator.Enabled = false; } version.Text = BeatmapManager.Current.Version; coopmode.Checked = BeatmapManager.Current.PlayMode == PlayModes.OsuMania && BeatmapManager.Current.DifficultyCircleSize >= 10; // extend the trackbar a little to avoid resetting .osuhaxed values setDifficulty(hpDrainRate, BeatmapManager.Current.DifficultyHpDrainRate, DRAIN_MIN, DRAIN_MAX, 10.0); if (allowedModes.SelectedIndex == 3) { setDifficulty(circleSize, BeatmapManager.Current.DifficultyCircleSize / (coopmode.Checked ? 2 : 1), CS_MIN_MANIA, CS_MAX_MANIA, 1.0); // Mania doesn't support any decimal circle size } else { setDifficulty(circleSize, BeatmapManager.Current.DifficultyCircleSize, CS_MIN, CS_MAX, 10.0); } setDifficulty(approachRate, BeatmapManager.Current.DifficultyApproachRate, AR_MIN, AR_MAX, 10.0); setDifficulty(overallDifficulty, BeatmapManager.Current.DifficultyOverall, OD_MIN, OD_MAX, 10.0); // in the case where there's only one sampleset, this works. // when there isn't, the control is hidden anyway. listSampleset.SelectedItem = AudioEngine.CurrentSampleSet.ToString(); tags.Text = BeatmapManager.Current.Tags; source.Text = BeatmapManager.Current.Source; sampleCustom.Checked = AudioEngine.CustomSamples == CustomSampleSet.Custom1; checkEpilepsy.Checked = BeatmapManager.Current.EpilepsyWarning; udCountdownOffset.Value = BeatmapManager.Current.CountdownOffset; stackLeniency.Value = (int)Math.Max(2, Math.Round(BeatmapManager.Current.StackLeniency * 10)); allowedModes.SelectedIndex = (int)BeatmapManager.Current.PlayMode; originMode = BeatmapManager.Current.PlayMode; volume1.Value = BeatmapManager.Current.SampleVolume; if (BeatmapManager.Current.AudioPresent) { checkSamplesMatchPlaybackRate.Checked = BeatmapManager.Current.SamplesMatchPlaybackRate; } else { checkSamplesMatchPlaybackRate.Checked = true; checkSamplesMatchPlaybackRate.Enabled = false; } checkCountdown.Checked = BeatmapManager.Current.Countdown != Countdown.Disabled; checkLetterbox.Checked = BeatmapManager.Current.LetterboxInBreaks; checkWidescreen.Checked = BeatmapManager.Current.WidescreenStoryboard || newDifficulty; checkStoryOverFire.Checked = !BeatmapManager.Current.StoryFireInFront; if (BeatmapManager.Current.Countdown == Countdown.Disabled) { countdownNormal.Checked = true; } else { countdownDouble.Checked = BeatmapManager.Current.Countdown == Countdown.DoubleSpeed; countdownHalf.Checked = BeatmapManager.Current.Countdown == Countdown.HalfSpeed; countdownNormal.Checked = BeatmapManager.Current.Countdown == Countdown.Normal; } SkinManager.InitializeSkinList(); foreach (string s in SkinManager.Skins) { skinPreference.Items.Add(s); } if (!string.IsNullOrEmpty(BeatmapManager.Current.SkinPreference)) { skinPreference.Text = BeatmapManager.Current.SkinPreference; } else { skinPreference.SelectedIndex = 0; } panelCountdownRate.Enabled = checkCountdown.Checked; if (AudioEngine.ControlPoints.Count > 0) { SampleSet def = AudioEngine.ControlPoints[0].SampleSet; CustomSampleSet cus = AudioEngine.ControlPoints[0].CustomSamples; int volume = AudioEngine.ControlPoints[0].Volume; foreach (ControlPoint p in AudioEngine.ControlPoints) { if (p.SampleSet != def || p.CustomSamples != cus || p.CustomSamples >= CustomSampleSet.Custom2) { hideSampleSettings.Visible = true; resetSampleSettings = false; } if (p.Volume != volume) { hideSampleVolume.Visible = true; resetVolumeSettings = false; } } volume1.Value = volume; } List <System.Drawing.Color> colours = new List <System.Drawing.Color>(4); for (int x = 0; x < SkinManager.MAX_COLOUR_COUNT; x++) { System.Drawing.Color c = OsuMathHelper.CConvert(SkinManager.LoadColour("Combo" + (x + 1).ToString())); if (x < 2 || c.A > 0) { colours.Add(c); } } while (colours.Count < 2) { colours.Add(System.Drawing.Color.FromArgb(240, 240, 240)); } colours.Add(colours[0]); colours.RemoveAt(0); int y; for (y = 0; y < colours.Count; y++) { combos[y].SwatchColor = colours[y]; combos[y].Visible = true; combos[y].Visible2 = true; } for (; y < 8; y++) { combos[y].Visible = false; combos[y].Visible2 = false; } backgroundColour.SwatchColor = OsuMathHelper.CConvert(EventManager.backgroundColour); updateCheckedColours(); customColour.Checked = BeatmapManager.Current.CustomColours; cb_maniaSpecial.Checked = BeatmapManager.Current.SpecialStyle; if (newDifficulty || fRestrict) { version.Text = string.Empty; version.Select(); artist.Enabled = false; title.Enabled = false; } else { artist.Select(); } changesMade = false; }
internal static pTexture CreateText(string text, float size, Vector2 restrictBounds, Color color, ShadowType shadow, bool bold, bool italic, bool underline, TextAlignment alignment, bool forceAa, out Vector2 measured, out RectangleF[] characterRegions, Color background, Color border, int borderWidth, bool measureOnly, bool getCharacterRegions, FontFace fontFace, Vector4 cornerBounds, Vector2 padding, pTexture lastTexture = null, int startIndex = 0, int length = -1) { characterRegions = null; if (text == null) { measured = Vector2.Zero; return(null); } if (ConfigManager.dDisableTextRendering) { measured = new Vector2(text.Length * size, size); return(null); } #if DEBUG if (!text.Contains(@"NativeText")) { int limit_per_second = osu.GameModes.Play.Player.Playing ? 5 : 58; bool newSecond = GameBase.Time / 1000 != currentSecond; drawCount++; if (drawCount == limit_per_second) { Debug.Print(@"NativeText: High number of text refreshes per second."); } if (newSecond) { currentSecond = GameBase.Time / 1000; drawCount = 0; } } #endif //This lock ensures we are only using the shared GDI+ object (FromHwnd) in one place at a time. lock (createTextLock) { try { using (System.Drawing.Graphics graphics = System.Drawing.Graphics.FromHwnd(IntPtr.Zero)) using (StringFormat sf = new StringFormat()) { if (dpiRatio == 0) { dpiRatio = 96 / graphics.DpiX; } size *= dpiRatio; GameBase.PerformanceMonitor.ReportCount(CounterType.NativeText); graphics.TextRenderingHint = TextRenderingHint.AntiAlias; SizeF measuredSize; string face = GetFontFace(fontFace); if (face.StartsWith(@"Aller")) { //if we are using the default osu! font, allow specific language overrides based on simple detection. string fontFaceOverride = getLanguageSpeicificFont(text); if (fontFaceOverride != null) { face = fontFaceOverride; } } if (startIndex != 0 || length > 0) { text = text.Substring(startIndex, length); } else if (length == -1) { length = text.Length; } if (size < 20 && face.EndsWith(@" Light")) { face = face.Replace(@" Light", string.Empty); } FontStyle fs = FontStyle.Regular; if (bold) { if (face.EndsWith(@" Light")) { face = face.Replace(@" Light", string.Empty); } fs |= FontStyle.Bold; } if (italic) { fs |= FontStyle.Italic; } if (underline) { fs |= FontStyle.Underline; } switch (alignment) { case TextAlignment.Left: case TextAlignment.LeftFixed: sf.Alignment = StringAlignment.Near; break; case TextAlignment.Centre: sf.Alignment = StringAlignment.Center; break; case TextAlignment.Right: sf.Alignment = StringAlignment.Far; break; } if (!OsuMain.IsWine && face.StartsWith(@"Aller")) { for (char c = '0'; c <= '9'; c++) { text = text.Replace(c, (char)(c + (0xf83c - '0'))); } } Font f = GetFont(face, size * ScaleModifier, fs); if (ScaleModifier != 1) { restrictBounds *= ScaleModifier; } try { if (text.Length == 0) { text = " "; } measuredSize = restrictBounds != Vector2.Zero ? graphics.MeasureString(text, f, new SizeF(restrictBounds.X, restrictBounds.Y), sf) : graphics.MeasureString(text, f); } catch (InvalidOperationException) { measured = Vector2.Zero; return(null); } int width = (int)(measuredSize.Width + 1); int height = (int)(measuredSize.Height + 1); if (restrictBounds.Y != 0) { height = (int)restrictBounds.Y; } if (restrictBounds.X != 0 && (alignment != TextAlignment.Left || background.A > 0)) { width = (int)restrictBounds.X; } if (padding != Vector2.Zero && restrictBounds == Vector2.Zero) { width += (int)(padding.X * 2); height += (int)(padding.Y * 2); } measured = new Vector2(width, height); float offset = Math.Max(0.5f, Math.Min(1f, (size * ScaleModifier) / 14)); if (getCharacterRegions) { characterRegions = new RectangleF[text.Length]; // SetMeasurableCharacterRanges only accepts a maximum of 32 intervals to be queried, so we as the library user are // forced to split the string into 32 character long chunks and perform MeasureCharacterRanges on each. int numIntervals = (text.Length / 32) + 1; for (int i = 0; i < numIntervals; ++i) { int offsetIndex = i * 32; int end = Math.Min(text.Length - offsetIndex, 32); CharacterRange[] characterRanges = new CharacterRange[end]; for (int j = 0; j < end; ++j) { characterRanges[j] = new CharacterRange(j + offsetIndex, 1); } sf.SetMeasurableCharacterRanges(characterRanges); Region[] regions = graphics.MeasureCharacterRanges( text, f, new RectangleF( padding.X, padding.Y, restrictBounds.X == 0 ? Single.PositiveInfinity : restrictBounds.X, restrictBounds.Y == 0 ? Single.PositiveInfinity : restrictBounds.Y), sf); for (int j = 0; j < end; ++j) { Region region = regions[j] as Region; characterRegions[j + offsetIndex] = region.GetBounds(graphics); } } } if (measureOnly) { int startSpace = 0; int endSpace = 0; int i = 0; while (i < text.Length && text[i++] == ' ') { startSpace++; } int j = text.Length - 1; while (j >= i && text[j--] == ' ') { endSpace++; } if (startSpace == text.Length) { endSpace += startSpace; } measured = new Vector2(width + (endSpace * 5.145f * size / 12), height); return(null); } using (Bitmap b = new Bitmap(width, height, PixelFormat.Format32bppArgb)) using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(b)) { //Quality settings g.TextRenderingHint = graphics.TextRenderingHint; g.SmoothingMode = SmoothingMode.HighQuality; g.InterpolationMode = InterpolationMode.HighQualityBicubic; if (background.A > 0) { if (cornerBounds != Vector4.Zero) { fillRoundedRectangle(g, new Rectangle(0, 0, width, height), new SolidBrush(OsuMathHelper.CConvert(background)), cornerBounds); if (borderWidth > 0) { drawRoundedRectangle(g, new Rectangle(0, 0, width - (int)Math.Ceiling(borderWidth / 2f), height - (int)Math.Ceiling(borderWidth / 2f)), new Pen(OsuMathHelper.CConvert(border), borderWidth), cornerBounds); } } else { g.Clear(OsuMathHelper.CConvert(background)); if (borderWidth > 0) { g.DrawRectangle(new Pen(OsuMathHelper.CConvert(border), borderWidth), new Rectangle(borderWidth / 2, borderWidth / 2, width - borderWidth, height - borderWidth)); } } } else { g.Clear(System.Drawing.Color.FromArgb(1, color.R, color.G, color.B)); } using (Brush brush = new SolidBrush(OsuMathHelper.CConvert(color))) { if (restrictBounds != Vector2.Zero) { restrictBounds.X -= padding.X * 2; restrictBounds.Y -= padding.Y * 2; switch (shadow) { case ShadowType.Normal: g.DrawString(text, f, shadowBrush, new RectangleF(padding.X - offset, offset + padding.Y, restrictBounds.X, restrictBounds.Y), sf); g.DrawString(text, f, shadowBrush, new RectangleF(padding.X + offset, offset + padding.Y, restrictBounds.X, restrictBounds.Y), sf); break; case ShadowType.Border: Brush borderBrush = greyBrush; if (background.A == 0 && borderWidth == 1 && border.A > 0) { borderBrush = new SolidBrush(OsuMathHelper.CConvert(border)); } g.DrawString(text, f, borderBrush, new RectangleF(padding.X + offset, padding.Y + offset, restrictBounds.X, restrictBounds.Y), sf); g.DrawString(text, f, borderBrush, new RectangleF(padding.X + offset, padding.Y - offset, restrictBounds.X, restrictBounds.Y), sf); g.DrawString(text, f, borderBrush, new RectangleF(padding.X - offset, padding.Y + offset, restrictBounds.X, restrictBounds.Y), sf); g.DrawString(text, f, borderBrush, new RectangleF(padding.X - offset, padding.Y - offset, restrictBounds.X, restrictBounds.Y), sf); break; } g.DrawString(text, f, brush, new RectangleF(padding.X, padding.Y, restrictBounds.X, restrictBounds.Y), sf); } else { switch (shadow) { case ShadowType.Normal: g.DrawString(text, f, shadowBrush, padding.X - offset, padding.Y + offset); g.DrawString(text, f, shadowBrush, padding.X + offset, padding.Y + offset); break; case ShadowType.Border: Brush borderBrush = greyBrush; if (background.A == 0 && borderWidth == 1 && border.A > 0) { borderBrush = new SolidBrush(OsuMathHelper.CConvert(border)); } g.DrawString(text, f, borderBrush, padding.X + offset, padding.Y + offset); g.DrawString(text, f, borderBrush, padding.X - offset, padding.Y + offset); g.DrawString(text, f, borderBrush, padding.X + offset, padding.Y - offset); g.DrawString(text, f, borderBrush, padding.X - offset, padding.Y - offset); break; } g.DrawString(text, f, brush, padding.X, padding.Y); } } //if (lastTexture == null || lastTexture.isDisposed) { lastTexture = pTexture.FromBitmap(b); lastTexture.Disposable = true; } /*else * { * lastTexture.Width = b.Width; * lastTexture.Height = b.Height; * lastTexture.SetData(b); * }*/ return(lastTexture); } } } catch (Exception e) { measured = Vector2.Zero; return(null); } } }