public void RenderCharacter(byte *ptr, char c, FontPack font, FontColor foreground, FontColor background) { //Make sure we have this if (!font.font.ContainsKey(c)) { return; } //Get lines float[] data = font.font[c]; //Copy for (int y = 0; y < font.height; y++) { //Get pointer and offset byte *line = ptr + (y * format.BytesPerPixel * imageWidth); int offset = font.width * y; //Mix for (int x = 0; x < font.width; x++) { SetMixColor(line, data[offset + x], foreground, background); line += format.BytesPerPixel; } } }
public static FontPack FromStream(Stream s) { //Load header byte[] header = new byte[Math.Max(HEADER_SIZE, CHAR_HEADER_SIZE)]; s.Read(header, 0, HEADER_SIZE); //Check magic if (header[0] != 'S' || header[1] != 'D' || header[2] != 'R' || header[3] != 'F') { throw new Exception("Invalid font file"); } //Read header parts byte version = header[4]; byte count = header[5]; byte width = header[6]; byte height = header[7]; //Create FontPack pack = new FontPack(width, height); //Load all fonts for (int i = 0; i < count; i++) { //Load font header s.Read(header, 0, CHAR_HEADER_SIZE); byte charCode = header[0]; byte charFlags = header[1]; //Read font data byte[] buffer = new byte[width * height]; s.Read(buffer, 0, buffer.Length); //Convert font data float[] converted = new float[width * height]; for (int p = 0; p < width * height; p++) { converted[p] = (float)buffer[p] / byte.MaxValue; } pack.font.Add((char)charCode, converted); } return(pack); }
public FontPack MakeScaledPack(float hScale, float vScale) { //Make pack FontPack pack = new FontPack((byte)(width * hScale), (byte)(height * vScale)); //Convert characters foreach (var c in font) { float[] data = new float[pack.height * pack.width]; for (int y = 0; y < pack.height; y++) { for (int x = 0; x < pack.width; x++) { //First, get data points to use on both axis float yRatio = GetInterpScale(y, vScale, out int srcYa, out int srcYb); float xRatio = GetInterpScale(x, hScale, out int srcXa, out int srcXb); float yRatioInvert = 1 - yRatio; float xRatioInvert = 1 - xRatio; //Constrain if (srcYa >= height) { srcYa = height - 1; } if (srcYb >= height) { srcYb = height - 1; } //Apply on the X axis float p1 = (c.Value[srcXa + (srcYa * width)] * xRatioInvert) + (c.Value[srcXb + (srcYa * width)] * xRatio); float p2 = (c.Value[srcXa + (srcYb * width)] * xRatioInvert) + (c.Value[srcXb + (srcYb * width)] * xRatio); //Now, apply on the X axis between those two points data[x + (y * pack.width)] = (p1 * yRatioInvert) + (p2 * yRatio); } } pack.font.Add(c.Key, data); } return(pack); }
public bool RenderRawBox(byte *ptr, char[][] lines, FontPack font, FontAlignHorizontal horizTextAlign, FontAlignVertical vertTextAlign, int boundsWidth, int boundsHeight, FontColor foreground, FontColor background) { //Fill box with background for (int y = 0; y < boundsHeight; y++) { byte *fillLine = ptr + (format.BytesPerPixel * y * imageWidth); for (int x = 0; x < boundsWidth; x++) { format.WritePixel(fillLine, background.r, background.g, background.b); fillLine += format.BytesPerPixel; } } //Determine Y offset int offsetY; switch (vertTextAlign) { case FontAlignVertical.Top: offsetY = 0; break; case FontAlignVertical.Bottom: offsetY = boundsHeight - (lines.Length * font.height); break; case FontAlignVertical.Center: offsetY = (boundsHeight - (lines.Length * font.height)) / 2; break; default: throw new Exception("Unknown alignment."); } //Draw bool fitAll = true; byte *line = ptr + (format.BytesPerPixel * offsetY * imageWidth); for (int ln = 0; ln < lines.Length; ln++) { //Calculate X offset int offsetX; switch (horizTextAlign) { case FontAlignHorizontal.Left: offsetX = 0; break; case FontAlignHorizontal.Right: offsetX = boundsWidth - (lines[ln].Length * font.width); break; case FontAlignHorizontal.Center: offsetX = (boundsWidth - (lines[ln].Length * font.width)) / 2; break; default: throw new Exception("Unknown alignment."); } //Write byte *lineDraw = line + (offsetX * format.BytesPerPixel); byte *maxDraw = line + ((boundsWidth - font.width) * format.BytesPerPixel); for (int i = 0; i < lines[ln].Length && lineDraw <= maxDraw; i++) { RenderCharacter(lineDraw, lines[ln][i], font, foreground, background); lineDraw += format.BytesPerPixel * font.width; } //Update flag if we have too much fitAll = fitAll && (lineDraw <= maxDraw); //Offset line += format.BytesPerPixel * imageWidth * font.height; } return(fitAll); }