Cosmos/source2/Users/Orvid/Orvid.Graphics/FontSupport/bdf/BDFTextRenderer.cs
blah38621_cp 92dcac4a51 Made a few improvements to the speed of the ILScanner, including caching the resolved plugs.
Added the possibility for an optimization step in the IL2CPU MSBuild task. Currently commented out, but should work fine with a few modifications to the optimizer.
Moved classes that are dependent on Cosmos from the Orvid.Graphics, into the Orvid.Graphics.Cosmos assembly. 
Re-factored the font mechanism, added partially working .fnt Font support. 
Added a Rectangle class, and a Vec2d class, which is the same as Vec2, except with doubles for the X and Y values.
Made a small aesthetic improvement to the output of the File2ByteArray Converter.
2011-09-03 21:05:46 +00:00

165 lines
6.1 KiB
C#

using System;
namespace Orvid.Graphics.FontSupport.bdf
{
public class BDFTextRenderer : ITextRenderer
{
private BDFFontContainer bdfFont;
public BDFTextRenderer(BDFFontContainer BdfFont)
{
this.bdfFont = BdfFont;
}
public override void Render(Image im, BoundingBox clip, AffineTransform tx, string text, Vec2 loc, Pixel color)
{
if (text == null || text.Length == 0)
return;
int offset = 0,
x = 0, y = 0,
bdfFontDepth = bdfFont.getDepth(),
x_min = int.MaxValue,
y_min = int.MaxValue,
x_max = int.MinValue,
y_max = int.MinValue,
charsCount = text.Length,
fHeight, scan, fg_r, fg_g,
fg_b, bx, by, offsetLine,
fPixel, px, py, bg_r,
bg_g, bg_b, r, g, b
;
int[] fData;
Vec2 src, dst;
BDFParser.Rectangle glyph_box = new BDFParser.Rectangle();
BDFGlyph glyph;
Image img;
if ((bdfFont != null) && (charsCount > 0))
{
char[] chrs = text.ToCharArray();
int mH = 0;
int mY = 0;
int mxY = 0;
int tW = 0;
int tH = 0;
for (uint m = 0; m < text.Length; m++)
{
glyph = bdfFont.getGlyph(chrs[m]);
glyph_box = glyph.getBbx(glyph_box);
if (glyph_box.height > mH)
{
mH = glyph_box.height + 2;
}
if (glyph_box.y < mY)
{
mY = glyph_box.y;
}
if (glyph_box.y > mxY)
{
mxY = glyph_box.y;
}
tW += glyph_box.width + glyph_box.x + 2;
}
tH = mH + (mxY - mY);
y = mH + -mY;
img = new Image(tW, tH);
float f_max = (1 << bdfFontDepth) - 1;
if (f_max == 0)
f_max = 1;
glyph_box = new BDFParser.Rectangle();
src = new Vec2();
dst = new Vec2();
for (int i = 0; i < charsCount; i++)
{
glyph = bdfFont.getGlyph(chrs[i]);
if (glyph == null)
{
continue;
}
glyph_box = glyph.getBbx(glyph_box);
fHeight = glyph_box.height;
fData = glyph.getData();
scan = fData.Length / fHeight;
fg_r = color.R;
fg_g = color.G;
fg_b = color.B;
//box location
bx = x + offset + glyph_box.x;
by = y - fHeight - glyph_box.y;
for (int k = 0; k < fHeight; k++)
{
offsetLine = k * scan;
for (int j = 0; j < scan; j++)
{
fPixel = fData[offsetLine + j];
if (fPixel != 0)
{
//pixel location
px = bx + j;
py = by + k;
if (tx != null)
{
//src.setLocation(px, py);
//tx.transform(src, dst);
#warning TODO: Add support for this.
//px = dst.X;
//py = dst.Y;
}
//clip
if (clip == null || clip.Contains(px, py))
{
//compute color
Pixel bg_color = img.GetPixel((uint)px, (uint)py);
bg_r = bg_color.R;
bg_g = bg_color.G;
bg_b = bg_color.B;
//todo improve this pixel composition
float alpha = fPixel / f_max;
r = bg_r + ((int)((fg_r - bg_r) * alpha)) & 0xFF;
g = bg_g + ((int)((fg_g - bg_g) * alpha)) & 0xFF;
b = bg_b + ((int)((fg_b - bg_b) * alpha)) & 0xFF;
Pixel nw = new Pixel((byte)r, (byte)g, (byte)b, 255);
img.SetPixel((uint)px, (uint)py, nw);
if (x_min > px)
x_min = px;
if (y_min > py)
y_min = py;
if (x_max < px)
x_max = px;
if (y_max < py)
y_max = py;
}
}
}
}
offset += glyph.getDWidth().width;
}
//img = ImageManipulator.Resize(img, new Vec2(img.Width * 8, img.Height * 8), ImageManipulator.ScalingAlgorithm.Bicubic);
//img = ImageManipulator.Resize(img, Vec2.Zero, ImageManipulator.ScalingAlgorithm.Hq2x);
//img = ImageManipulator.Resize(img, Vec2.Zero, ImageManipulator.ScalingAlgorithm.Hq4x);
im.DrawImage(loc, img);
}
}
}
}