Rank: Advanced Member
Groups: Guest
Joined: 1/31/2005(UTC) Posts: 458
Was thanked: 5 time(s) in 5 post(s)
|
Hello Eric, Here is code sample, adapted for ARGB output. It is based on the same idea, but implemented in another way - with use of System.Drawing classes. As I can see, Adobe Photoshop and Windows Picture&Fax viewer display this .png correctly, but another my picture viewer (XnView) displays multiple black squares instead of characters. I think that this is the issue of the XnView and hope that these pictures will be acceptable for you. Code:private void DrawCurvedViaGdiPlus()
{
const int centerX = 150;
const int centerY = 150;
const int radius = 110;
//Create mask bitmap object
Aurigma.GraphicsMill.Bitmap result =
new Aurigma.GraphicsMill.Bitmap(Aurigma.GraphicsMill.Color.FromArgb(0x00, 0xff, 0xff, 0xff)
, 300
, 150
, Aurigma.GraphicsMill.PixelFormat.Format32bppArgb);
using (System.Drawing.Graphics g = result.GetGdiplusGraphics())
{
string text = "Audio Video Labs, INC.";
System.Drawing.Brush brush = new System.Drawing.SolidBrush(System.Drawing.Color.Black);
System.Drawing.Font font = new System.Drawing.Font("Times New Roman", 37);
System.Drawing.StringFormat sf =
new System.Drawing.StringFormat(System.Drawing.StringFormat.GenericTypographic);
sf.LineAlignment = StringAlignment.Far;
float[] positions = GetCharacterPositions(text, font, sf, g);
//Draw character by character
for (int i = 0; i < text.Length; i++)
{
//Compute angle in radians
float angle = (float)(positions[i] / radius + Math.PI);
float x = (float)(centerX + radius * Math.Cos(angle));
float y = (float)(centerY + radius * Math.Sin(angle));
System.Drawing.Drawing2D.Matrix rotateMatrix =
new System.Drawing.Drawing2D.Matrix();
rotateMatrix.RotateAt((float)(angle / Math.PI * 180 + 90),
new System.Drawing.PointF(x, y));
g.Transform = rotateMatrix;
g.DrawString(text[i].ToString(), font, brush, x, y, sf);
}
}
result.Save("curved.png");
result.Dispose();
}
//StringFormat.SetMeasurableCharacterRanges() method has limitation - length of the
//ranges array to measure should be less than 32. So we had to split out measurement
//into chunks to workaround this issue.
float[] GetCharacterPositions(string text
, System.Drawing.Font font
, System.Drawing.StringFormat sf
, System.Drawing.Graphics g)
{
float[] result = new float[text.Length];
int callCount = (text.Length + 31) / 32;
for (int i = 0; i < callCount; i++)
{
int baseIndex = i * 32;
int charCount = System.Math.Min(text.Length - baseIndex, 32);
System.Drawing.CharacterRange[] ranges = new System.Drawing.CharacterRange[charCount];
for (int j = 0; j < charCount; j++)
ranges[j] = new System.Drawing.CharacterRange(baseIndex + j, 1);
sf.SetMeasurableCharacterRanges(ranges);
System.Drawing.Region[] regions = g.MeasureCharacterRanges(text
, font
, new System.Drawing.RectangleF(0, 0, float.MaxValue, float.MaxValue)
, sf);
for (int j = 0; j < charCount; j++)
{
result[baseIndex + j] = regions[j].GetBounds(g).X;
regions[j].Dispose();
}
}
return result;
}
Edited by user Tuesday, December 18, 2007 3:42:05 AM(UTC)
| Reason: Not specified |