/// <summary>Renders the timetable data</summary> /// <param name="timetableTexture">The texture to create</param> internal void RenderData(ref Texture timetableTexture) { // prepare timetable int w = 384, h = 192; int offsetx = 0; int actualheight = h; float descriptionwidth = 256; float descriptionheight = 16; float stationnamewidth = 16; for (int k = 0; k < 2; k++) { Bitmap b = new Bitmap(w, h); Graphics g = Graphics.FromImage(b); g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; g.Clear(Color.Transparent); g.FillRectangle(Brushes.White, new RectangleF(offsetx, 0, w, actualheight)); Font f = new Font(FontFamily.GenericSansSerif, 13.0f, GraphicsUnit.Pixel); Font fs = new Font(FontFamily.GenericSansSerif, 11.0f, GraphicsUnit.Pixel); Font fss = new Font(FontFamily.GenericSansSerif, 9.0f, GraphicsUnit.Pixel); // draw timetable string t; // description float x0 = offsetx + 8; float y0 = 8; if (k == 1) { t = DefaultTimetableDescription; g.DrawString(t, f, Brushes.Black, new RectangleF(x0, 6, descriptionwidth, descriptionheight + 8)); y0 += descriptionheight + 2; } // highest speed t = Translations.GetInterfaceString("timetable_highestspeed"); SizeF s = g.MeasureString(t, fs); g.DrawString(t, fs, Brushes.Black, x0, y0); float y0a = y0 + s.Height + 2; float x1 = x0 + s.Width + 4; for (int i = 0; i < Tracks.Length; i++) { float y = y0a + 18 * i; t = Tracks[i].Speed; g.DrawString(t, f, Brushes.Black, x0, y); s = g.MeasureString(t, f); float x = x0 + s.Width + 4; if (x > x1) { x1 = x; } } g.DrawLine(Pens.LightGray, new PointF(x1 - 2, 4 + descriptionheight), new PointF(x1 - 2, y0a + 18 * Tracks.Length - 1)); // driving time t = Translations.GetInterfaceString("timetable_drivingtime"); s = g.MeasureString(t, fs); g.DrawString(t, fs, Brushes.Black, x1, y0); float x2 = x1 + s.Width + 4; for (int i = 0; i < Tracks.Length; i++) { float y = y0a + 18 * i; if (Tracks[i].Time.Hour.Length != 0) { t = Tracks[i].Time.Hour; g.DrawString(t, fss, Brushes.Black, x1, y + 2); } else { t = "0"; } s = g.MeasureString(t, fss, 9999, StringFormat.GenericTypographic); float x = x1 + s.Width - 1; if (Tracks[i].Time.Minute.Length != 0) { t = Tracks[i].Time.Minute; g.DrawString(t, fs, Brushes.Black, x, y + 2); } else { t = "00:"; } s = g.MeasureString(t, fs, 9999, StringFormat.GenericTypographic); x += s.Width + 1; t = Tracks[i].Time.Second; g.DrawString(t, fss, Brushes.Black, x, y + 2); s = g.MeasureString(t, fss, 9999, StringFormat.GenericTypographic); x += s.Width + 8; if (x > x2) { x2 = x; } } for (int i = 0; i < Tracks.Length; i++) { float y = y0a + 18 * i; g.DrawLine(Pens.LightGray, new PointF(offsetx + 4, y - 1), new PointF(x2 - 2, y - 1)); } g.DrawLine(Pens.LightGray, new PointF(x2 - 2, 4 + descriptionheight), new PointF(x2 - 2, y0a + 18 * Tracks.Length - 1)); // station name float y2 = y0; t = Translations.GetInterfaceString("timetable_stationname"); s = g.MeasureString(t, f); g.DrawString(t, f, Brushes.Black, x2, y2); float x3 = x2 + s.Width + 4; for (int i = 0; i < Stations.Length; i++) { float y = y0 + 18 * (i + 1) + 2; g.DrawLine(Pens.LightGray, new PointF(x2 - 2, y - 1), new PointF(w - 4, y - 1)); t = Stations[i].Name; if (Stations[i].NameJapanese & Stations[i].Name.Length > 1) { float[] sizes = new float[t.Length]; float totalsize = 0.0f; for (int j = 0; j < t.Length; j++) { sizes[j] = g.MeasureString(new string(t[j], 1), f, 9999, StringFormat.GenericTypographic).Width; totalsize += sizes[j]; } float space = (stationnamewidth - totalsize) / (float)(t.Length - 1); float x = 0.0f; for (int j = 0; j < t.Length; j++) { g.DrawString(new string(t[j], 1), f, Brushes.Black, x2 + x, y); x += sizes[j] + space; } } else { g.DrawString(t, f, Brushes.Black, x2, y); } s = g.MeasureString(t, f); { float x = x2 + s.Width + 4; if (x > x3) { x3 = x; } } } g.DrawLine(Pens.LightGray, new PointF(x3 - 2, 4 + descriptionheight), new PointF(x3 - 2, y0 + 18 * (Stations.Length + 1))); if (k == 0) { stationnamewidth = x3 - x2 - 6; } // arrival time t = Translations.GetInterfaceString("timetable_arrivaltime"); s = g.MeasureString(t, f); g.DrawString(t, f, Brushes.Black, x3, y2); float x4 = x3 + s.Width + 4; for (int i = 0; i < Stations.Length; i++) { float y = y0 + 18 * (i + 1) + 2; if (Stations[i].Pass) { t = "00"; s = g.MeasureString(t, fs); float x = x3 + s.Width; t = " ↓"; g.DrawString(t, f, Brushes.Black, x, y); s = g.MeasureString(t, f); x += +s.Width + 4; if (x > x4) { x4 = x; } } else { if (Stations[i].Arrival.Hour.Length != 0) { t = Stations[i].Arrival.Hour; g.DrawString(t, fs, Brushes.Black, x3, y); } else { t = "00"; } s = g.MeasureString(t, fs); float x = x3 + s.Width; if (Stations[i].Arrival.Minute.Length != 0 & Stations[i].Arrival.Second.Length != 0) { t = Stations[i].Arrival.Minute + ":" + Stations[i].Arrival.Second; } else { t = ""; } g.DrawString(t, f, Brushes.Black, x, y); s = g.MeasureString(t, f); x += s.Width + 4; if (x > x4) { x4 = x; } } } g.DrawLine(Pens.LightGray, new PointF(x4 - 2, 4 + descriptionheight), new PointF(x4 - 2, y0 + 18 * (Stations.Length + 1))); // departure time t = Translations.GetInterfaceString("timetable_departuretime"); s = g.MeasureString(t, f); g.DrawString(t, f, Brushes.Black, x4, y2); float x5 = x4 + s.Width + 4; for (int i = 0; i < Stations.Length; i++) { float y = y0 + 18 * (i + 1) + 2; if (Stations[i].Terminal) { t = "00"; s = g.MeasureString(t, fs); float x = x4 + s.Width; const float c0 = 4; const float c1 = 32; g.DrawLine(Pens.Black, new PointF(x + c0, y + 6), new PointF(x + c1, y + 6)); g.DrawLine(Pens.Black, new PointF(x + c0, y + 10), new PointF(x + c1, y + 10)); x += c1 + 4; if (x > x5) { x5 = x; } } else { if (Stations[i].Departure.Hour.Length != 0) { t = Stations[i].Departure.Hour; g.DrawString(t, fs, Brushes.Black, x4, y); } else { t = "00"; } s = g.MeasureString(t, fs); float x = x4 + s.Width; if (Stations[i].Departure.Minute.Length != 0 & Stations[i].Departure.Second.Length != 0) { t = Stations[i].Departure.Minute + ":" + Stations[i].Departure.Second; } else { t = ""; } g.DrawString(t, f, Brushes.Black, x, y); s = g.MeasureString(t, f); x += s.Width + 4; if (x > x5) { x5 = x; } } } for (int i = 0; i < Stations.Length; i++) { float y = y0 + 18 * (i + 1) + 2; g.DrawLine(Pens.LightGray, new PointF(x2 - 2, y - 1), new PointF(w - 4, y - 1)); } // border if (k == 1) { g.DrawLine(Pens.Black, new PointF(offsetx + 4, 4), new PointF(offsetx + 4, y0a + 18 * Tracks.Length - 1)); g.DrawLine(Pens.Black, new PointF(offsetx + 4, y0a + 18 * Tracks.Length - 1), new PointF(x2 - 2, y0a + 18 * Tracks.Length - 1)); g.DrawLine(Pens.Black, new PointF(offsetx + 4, 4), new PointF(w - 4, 4)); g.DrawLine(Pens.Black, new PointF(offsetx + 4, 4 + descriptionheight), new PointF(w - 4, 4 + descriptionheight)); g.DrawLine(Pens.Black, new PointF(x2 - 2, y0 + 18 * (Stations.Length + 1)), new PointF(w - 4, y0 + 18 * (Stations.Length + 1))); g.DrawLine(Pens.Black, new PointF(w - 4, 4), new PointF(w - 4, y0 + 18 * (Stations.Length + 1))); g.DrawLine(Pens.Black, new PointF(x2 - 2, y0a + 18 * Tracks.Length - 1), new PointF(x2 - 2, y0 + 18 * (Stations.Length + 1))); } // measure w = (int)Math.Ceiling((double)(x5 + 1)); h = (int)Math.Ceiling((double)(y0 + 18 * (Stations.Length + 1) + 4)); // description if (k == 0) { t = DefaultTimetableDescription; s = g.MeasureString(t, f, w - 16); descriptionwidth = s.Width; descriptionheight = s.Height + 2; h += (int)Math.Ceiling((double)s.Height) + 4; } // finish if (k == 0) { // measures int nw = TextureManager.RoundUpToPowerOfTwo(w); offsetx = nw - w; w = nw; actualheight = h; h = TextureManager.RoundUpToPowerOfTwo(h); } else { // create texture g.Dispose(); timetableTexture = TextureManager.RegisterTexture(b); } } }