Added EPD business card project to archives.

This commit is contained in:
2018-06-04 14:24:02 -07:00
parent e6715f3686
commit 43b3555da8
556 changed files with 214719 additions and 0 deletions

View File

@@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "bm2rgbi", "bm2rgbi\bm2rgbi.csproj", "{96885E95-63A1-4321-9708-69BF7F6FB34F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{96885E95-63A1-4321-9708-69BF7F6FB34F}.Debug|x86.ActiveCfg = Debug|x86
{96885E95-63A1-4321-9708-69BF7F6FB34F}.Debug|x86.Build.0 = Debug|x86
{96885E95-63A1-4321-9708-69BF7F6FB34F}.Release|x86.ActiveCfg = Release|x86
{96885E95-63A1-4321-9708-69BF7F6FB34F}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,78 @@
using System.Drawing;
using System.IO;
using System;
namespace bm2rgbi {
/// <summary>
/// generic converter for 565 format 64K colours
/// Format: RRRRRGGGGGGBBBBB (RGB)
/// Format: BBBBBGGGGGGRRRRR (BGR)
/// </summary>
public class Generic565Converter {
/// <summary>
/// Convert to 565 format RGB
/// </summary>
public void convertRGB(Bitmap bm,FileStream fs) {
int x,y,value,r,g,b;
Color c;
for(y=0;y<bm.Height;y++) {
for(x=0;x<bm.Width;x++) {
c=bm.GetPixel(x,y);
// convert to 565
r=c.R>>3;
g=c.G>>2;
b=c.B>>3;
value=r<<11 | g<<5 | b;
// little-endian output
fs.WriteByte(Convert.ToByte(value & 0xFF));
fs.WriteByte(Convert.ToByte(value >> 8));
}
}
}
/// <summary>
/// Convert to 565 format BGR
/// </summary>
public void convertBGR(Bitmap bm,FileStream fs) {
int x,y,value,r,g,b;
Color c;
for(y=0;y<bm.Height;y++) {
for(x=0;x<bm.Width;x++) {
c=bm.GetPixel(x,y);
// convert to 565
r=c.R>>3;
g=c.G>>2;
b=c.B>>3;
value=b<<11 | g<<5 | r;
// little-endian output
fs.WriteByte(Convert.ToByte(value & 0xFF));
fs.WriteByte(Convert.ToByte(value >> 8));
}
}
}
}
}

View File

@@ -0,0 +1,44 @@
using System;
using System.Drawing;
using System.IO;
namespace bm2rgbi {
/// <summary>
/// Format is: 00000000RRRRRR00 GGGGGG00BBBBBB00
/// </summary>
class Generic666RGBConverter {
/// <summary>
/// Convert to 666 format
/// </summary>
public void convert(Bitmap bm,FileStream fs) {
int x,y,r,g,b;
Color c;
for(y=0;y<bm.Height;y++) {
for(x=0;x<bm.Width;x++) {
c=bm.GetPixel(x,y);
// convert to 666
r=c.R & 0xFC;
g=c.G & 0xFC;
b=c.B & 0xFC;
// the conversion is a tidy stream of bytes
fs.WriteByte(Convert.ToByte(r));
fs.WriteByte(0);
fs.WriteByte(Convert.ToByte(b));
fs.WriteByte(Convert.ToByte(g));
}
}
}
}
}

View File

@@ -0,0 +1,26 @@
using System;
namespace bm2rgbi {
/// <summary>
/// Convert to HX8347A internal format
/// </summary>
abstract public class HX8347AConverter {
/// <summary>
/// Get an instance of the converter
/// </summary>
static public IBitmapConverter createInstance(int depth) {
switch(depth) {
case 64:
return new HX8347AConverter64();
default:
throw new Exception(depth+" is not a recognised colour depth for the HX8347A");
}
}
}
}

View File

@@ -0,0 +1,26 @@
using System.Drawing;
using System.IO;
namespace bm2rgbi {
/// <summary>
/// Converter for 64K colours
/// </summary>
public class HX8347AConverter64 : HX8347AConverter, IBitmapConverter {
/// <summary>
/// Use the generic converter
/// </summary>
private Generic565Converter _converter=new Generic565Converter();
/// <summary>
/// Do the conversion
/// </summary>
public void convert(Bitmap bm,FileStream fs) {
_converter.convertRGB(bm,fs);
}
}
}

View File

@@ -0,0 +1,29 @@
using System;
namespace bm2rgbi {
/// <summary>
/// Convert to HX8352A internal format
/// </summary>
abstract public class HX8352AConverter {
/// <summary>
/// Get an instance of the converter
/// </summary>
static public IBitmapConverter createInstance(int depth) {
switch(depth) {
case 64:
return new HX8352AConverter64();
case 262:
return new HX8352AConverter262();
default:
throw new Exception(depth+" is not a recognised colour depth for the HX8352A");
}
}
}
}

View File

@@ -0,0 +1,47 @@
using System.Drawing;
using System.IO;
namespace bm2rgbi {
/// <summary>
/// 262K colour converter for HX8352A. This is a packed format:
/// 00000000000000RR RRRRGGGGGGBBBBBB
/// </summary>
class HX8352AConverter262 : HX8352AConverter, IBitmapConverter {
/// <summary>
/// Do the conversion.
/// </summary>
public void convert(Bitmap bm,FileStream fs) {
int x,y,r,g,b,value;
Color c;
for(y=0;y<bm.Height;y++) {
for(x=0;x<bm.Width;x++) {
c=bm.GetPixel(x,y);
// convert to 666
r=c.R & 0xFC;
g=c.G & 0xFC;
b=c.B & 0xFC;
value = r<<10;
value |= g << 4; // G into bits 6-11
value |= b >> 2; // B into bits 0-5
fs.WriteByte((byte) (value >>16));
fs.WriteByte(0);
fs.WriteByte((byte) (value & 0xff));
fs.WriteByte((byte) ((value >> 8) & 0xff));
}
}
}
}
}

View File

@@ -0,0 +1,26 @@
using System.Drawing;
using System.IO;
namespace bm2rgbi {
/// <summary>
/// Converter for 64K colours
/// </summary>
public class HX8352AConverter64 : HX8352AConverter, IBitmapConverter {
/// <summary>
/// Use the generic converter
/// </summary>
private Generic565Converter _converter=new Generic565Converter();
/// <summary>
/// Do the conversion
/// </summary>
public void convert(Bitmap bm,FileStream fs) {
_converter.convertRGB(bm,fs);
}
}
}

View File

@@ -0,0 +1,11 @@
using System.Drawing;
using System.IO;
namespace bm2rgbi {
public interface IBitmapConverter {
void convert(Bitmap bm,FileStream fs);
}
}

View File

@@ -0,0 +1,29 @@
using System;
namespace bm2rgbi {
/// <summary>
/// Convert to ILI9325 internal format specific to the Adafruit Arduino shield
/// </summary>
abstract public class ILI9325AConverter {
/// <summary>
/// Get an instance of the converter
/// </summary>
static public IBitmapConverter createInstance(int depth) {
switch(depth) {
case 64:
return new ILI9325AConverter64();
case 262:
return new ILI9325AConverter262();
default:
throw new Exception(depth+" is not a recognised colour depth for the ILI9325 (adafruit shield)");
}
}
}
}

View File

@@ -0,0 +1,47 @@
using System;
using System.Drawing;
using System.IO;
namespace bm2rgbi {
/// <summary>
/// 262K colour converter for ILI9325 (Adafruit Arduino shield). This is a packed format:
/// 00000000000000RR RRRRGGGGGGBBBBBB
/// </summary>
class ILI9325AConverter262 : ILI9325AConverter, IBitmapConverter {
/// <summary>
/// Convert to 666 format
/// </summary>
public void convert(Bitmap bm, FileStream fs)
{
int x, y, r, g, b;
Color c;
for (y = 0; y < bm.Height; y++)
{
for (x = 0; x < bm.Width; x++)
{
c = bm.GetPixel(x, y);
// convert to 666
r = c.R & 0xFC;
g = c.G & 0xFC;
b = c.B & 0xFC;
// the conversion is a tidy stream of bytes
fs.WriteByte(Convert.ToByte(r));
fs.WriteByte(Convert.ToByte(g));
fs.WriteByte(Convert.ToByte(b));
}
}
}
}
}

View File

@@ -0,0 +1,47 @@
using System;
using System.Drawing;
using System.IO;
namespace bm2rgbi {
/// <summary>
/// Converter for 64K colours
/// </summary>
public class ILI9325AConverter64 : ILI9325AConverter, IBitmapConverter {
/// <summary>
/// Convert to 565 format
/// </summary>
public void convert(Bitmap bm, FileStream fs)
{
int x, y, value, r, g, b;
Color c;
for (y = 0; y < bm.Height; y++)
{
for (x = 0; x < bm.Width; x++)
{
c = bm.GetPixel(x, y);
// convert to 565
r = c.R >> 3;
g = c.G >> 2;
b = c.B >> 3;
value = r << 11 | g << 5 | b;
// little-endian output
fs.WriteByte(Convert.ToByte(value >> 8));
fs.WriteByte(Convert.ToByte(value & 0xFF));
}
}
}
}
}

View File

@@ -0,0 +1,29 @@
using System;
namespace bm2rgbi {
/// <summary>
/// Convert to ILI9325 internal format
/// </summary>
abstract public class ILI9325Converter {
/// <summary>
/// Get an instance of the converter
/// </summary>
static public IBitmapConverter createInstance(int depth) {
switch(depth) {
case 64:
return new ILI9325Converter64();
case 262:
return new ILI9325Converter262();
default:
throw new Exception(depth+" is not a recognised colour depth for the ILI9325");
}
}
}
}

View File

@@ -0,0 +1,47 @@
using System.Drawing;
using System.IO;
namespace bm2rgbi {
/// <summary>
/// 262K colour converter for ILI9325. This is a packed format:
/// 00000000000000RR RRRRGGGGGGBBBBBB
/// </summary>
class ILI9325Converter262 : ILI9325Converter, IBitmapConverter {
/// <summary>
/// Do the conversion.
/// </summary>
public void convert(Bitmap bm,FileStream fs) {
int x,y,r,g,b,value;
Color c;
for(y=0;y<bm.Height;y++) {
for(x=0;x<bm.Width;x++) {
c=bm.GetPixel(x,y);
// convert to 666
r=c.R & 0xFC;
g=c.G & 0xFC;
b=c.B & 0xFC;
value = r<<10;
value |= g << 4; // G into bits 6-11
value |= b >> 2; // B into bits 0-5
fs.WriteByte((byte) (value >>16));
fs.WriteByte(0);
fs.WriteByte((byte) (value & 0xff));
fs.WriteByte((byte) ((value >> 8) & 0xff));
}
}
}
}
}

View File

@@ -0,0 +1,26 @@
using System.Drawing;
using System.IO;
namespace bm2rgbi {
/// <summary>
/// Converter for 64K colours
/// </summary>
public class ILI9325Converter64 : ILI9325Converter, IBitmapConverter {
/// <summary>
/// Use the generic converter
/// </summary>
private Generic565Converter _converter=new Generic565Converter();
/// <summary>
/// Do the conversion
/// </summary>
public void convert(Bitmap bm,FileStream fs) {
_converter.convertRGB(bm,fs);
}
}
}

View File

@@ -0,0 +1,29 @@
using System;
namespace bm2rgbi {
/// <summary>
/// Convert to ILI9327 internal format
/// </summary>
abstract public class ILI9327Converter {
/// <summary>
/// Get an instance of the converter
/// </summary>
static public IBitmapConverter createInstance(int depth) {
switch(depth) {
case 64:
return new ILI9327Converter64();
case 262:
return new ILI9327Converter262();
default:
throw new Exception(depth+" is not a recognised colour depth for the ILI9327");
}
}
}
}

View File

@@ -0,0 +1,22 @@
using System.Drawing;
using System.IO;
namespace bm2rgbi {
/// <summary>
/// 262K colour converter
/// </summary>
class ILI9327Converter262 : ILI9327Converter, IBitmapConverter {
private Generic666RGBConverter _converter=new Generic666RGBConverter();
/// <summary>
/// Do the conversion
/// </summary>
public void convert(Bitmap bm,FileStream fs) {
_converter.convert(bm,fs);
}
}
}

View File

@@ -0,0 +1,26 @@
using System.Drawing;
using System.IO;
namespace bm2rgbi {
/// <summary>
/// Converter for 64K colours
/// </summary>
public class ILI9327Converter64 : ILI9327Converter, IBitmapConverter {
/// <summary>
/// Use the generic converter
/// </summary>
private Generic565Converter _converter=new Generic565Converter();
/// <summary>
/// Do the conversion
/// </summary>
public void convert(Bitmap bm,FileStream fs) {
_converter.convertRGB(bm,fs);
}
}
}

View File

@@ -0,0 +1,29 @@
using System;
namespace bm2rgbi {
/// <summary>
/// Convert to ILI9481 internal format
/// </summary>
abstract public class ILI9481Converter {
/// <summary>
/// Get an instance of the converter
/// </summary>
static public IBitmapConverter createInstance(int depth) {
switch(depth) {
case 64:
return new ILI9481Converter64();
case 262:
return new ILI9481Converter262();
default:
throw new Exception(depth+" is not a recognised colour depth for the ILI9481");
}
}
}
}

View File

@@ -0,0 +1,22 @@
using System.Drawing;
using System.IO;
namespace bm2rgbi {
/// <summary>
/// 262K colour converter
/// </summary>
class ILI9481Converter262 : ILI9481Converter, IBitmapConverter {
private Generic666RGBConverter _converter=new Generic666RGBConverter();
/// <summary>
/// Do the conversion
/// </summary>
public void convert(Bitmap bm,FileStream fs) {
_converter.convert(bm,fs);
}
}
}

View File

@@ -0,0 +1,26 @@
using System.Drawing;
using System.IO;
namespace bm2rgbi {
/// <summary>
/// Converter for 64K colours
/// </summary>
public class ILI9481Converter64 : ILI9481Converter, IBitmapConverter {
/// <summary>
/// Use the generic converter
/// </summary>
private Generic565Converter _converter=new Generic565Converter();
/// <summary>
/// Do the conversion
/// </summary>
public void convert(Bitmap bm,FileStream fs) {
_converter.convertRGB(bm,fs);
}
}
}

View File

@@ -0,0 +1,32 @@
using System;
namespace bm2rgbi {
/// <summary>
/// Convert to LDS285 internal format
/// </summary>
abstract public class LDS285Converter {
/// <summary>
/// Get an instance of the converter
/// </summary>
static public IBitmapConverter createInstance(int depth) {
switch(depth) {
case 16:
return new LDS285Converter16();
case 262:
return new LDS285Converter262();
case 64:
return new LDS285Converter64();
default:
throw new Exception(depth+" is not a recognised colour depth for the LDS285");
}
}
}
}

View File

@@ -0,0 +1,42 @@
using System.Drawing;
using System.IO;
namespace bm2rgbi {
/// <summary>
/// 16M colour converter for LDS285. This is an unpacked format:
/// BBBBBBBB GGGGGGGG RRRRRRRR
/// </summary>
class LDS285Converter16 : LDS285Converter, IBitmapConverter {
/// <summary>
/// Do the conversion.
/// </summary>
public void convert(Bitmap bm,FileStream fs) {
int x,y;
byte r,g,b;
Color c;
for(y=0;y<bm.Height;y++) {
for(x=0;x<bm.Width;x++) {
c=bm.GetPixel(x,y);
// convert to 888
r=(byte)c.R;
g=(byte)c.G;
b=(byte)c.B;
fs.WriteByte(r);
fs.WriteByte(g);
fs.WriteByte(b);
}
}
}
}
}

View File

@@ -0,0 +1,42 @@
using System.Drawing;
using System.IO;
namespace bm2rgbi {
/// <summary>
/// 262K colour converter for LDS285. This is an unpacked format:
/// BBBBBB00 GGGGGG00 RRRRRR00
/// </summary>
class LDS285Converter262 : LDS285Converter, IBitmapConverter {
/// <summary>
/// Do the conversion.
/// </summary>
public void convert(Bitmap bm,FileStream fs) {
int x,y;
byte r,g,b;
Color c;
for(y=0;y<bm.Height;y++) {
for(x=0;x<bm.Width;x++) {
c=bm.GetPixel(x,y);
// convert to 666
r=(byte)(c.R & 0xFC);
g=(byte)(c.G & 0xFC);
b=(byte)(c.B & 0xFC);
fs.WriteByte(r);
fs.WriteByte(g);
fs.WriteByte(b);
}
}
}
}
}

View File

@@ -0,0 +1,44 @@
using System.Drawing;
using System.IO;
namespace bm2rgbi {
/// <summary>
/// 64K colour converter for LDS285. This is a packed format:
/// BBBBBGGG GGGRRRRR
/// </summary>
class LDS285Converter64 : LDS285Converter, IBitmapConverter {
/// <summary>
/// Do the conversion.
/// </summary>
public void convert(Bitmap bm,FileStream fs) {
int x,y;
byte r,g,b,b1,b2;
Color c;
for(y=0;y<bm.Height;y++) {
for(x=0;x<bm.Width;x++) {
c=bm.GetPixel(x,y);
// convert to 888
r=(byte)(c.R & 0xf8);
g=(byte)(c.G & 0xfc);
b=(byte)(c.B & 0xf8);
b1=(byte)(r | (g >> 5));
b2=(byte)((g << 3) | (b >> 3));
fs.WriteByte(b1);
fs.WriteByte(b2);
}
}
}
}
}

View File

@@ -0,0 +1,32 @@
using System;
namespace bm2rgbi {
/// <summary>
/// Convert to MC2PA8201 internal format
/// </summary>
abstract public class MC2PA8201Converter {
/// <summary>
/// Get an instance of the converter
/// </summary>
static public IBitmapConverter createInstance(int depth) {
switch(depth) {
case 16:
return new MC2PA8201Converter16();
case 262:
return new MC2PA8201Converter262();
case 64:
return new MC2PA8201Converter64();
default:
throw new Exception(depth+" is not a recognised colour depth for the MC2PA8201");
}
}
}
}

View File

@@ -0,0 +1,42 @@
using System.Drawing;
using System.IO;
namespace bm2rgbi {
/// <summary>
/// 16M colour converter for MC2PA8201. This is a packed format:
/// RRRRRRRR GGGGGGGG BBBBBBBB
/// </summary>
class MC2PA8201Converter16 : MC2PA8201Converter, IBitmapConverter {
/// <summary>
/// Do the conversion.
/// </summary>
public void convert(Bitmap bm,FileStream fs) {
int x,y;
byte r,g,b;
Color c;
for(y=0;y<bm.Height;y++) {
for(x=0;x<bm.Width;x++) {
c=bm.GetPixel(x,y);
// convert to 888
r=(byte)c.R;
g=(byte)c.G;
b=(byte)c.B;
fs.WriteByte(r);
fs.WriteByte(g);
fs.WriteByte(b);
}
}
}
}
}

View File

@@ -0,0 +1,42 @@
using System.Drawing;
using System.IO;
namespace bm2rgbi {
/// <summary>
/// 262K colour converter for MC2PA8201. This is a packed format:
/// RRRRRR00 BBBBBB00 GGGGGG00
/// </summary>
class MC2PA8201Converter262 : MC2PA8201Converter, IBitmapConverter {
/// <summary>
/// Do the conversion.
/// </summary>
public void convert(Bitmap bm,FileStream fs) {
int x,y;
byte r,g,b;
Color c;
for(y=0;y<bm.Height;y++) {
for(x=0;x<bm.Width;x++) {
c=bm.GetPixel(x,y);
// convert to 666
r=(byte)(c.R & 0xFC);
g=(byte)(c.G & 0xFC);
b=(byte)(c.B & 0xFC);
fs.WriteByte(r);
fs.WriteByte(g);
fs.WriteByte(b);
}
}
}
}
}

View File

@@ -0,0 +1,44 @@
using System.Drawing;
using System.IO;
namespace bm2rgbi {
/// <summary>
/// 64K colour converter for MC2PA8201. This is a packed format:
/// BBBBBGGG GGGRRRRR
/// </summary>
class MC2PA8201Converter64 : MC2PA8201Converter, IBitmapConverter {
/// <summary>
/// Do the conversion.
/// </summary>
public void convert(Bitmap bm,FileStream fs) {
int x,y;
byte r,g,b,b1,b2;
Color c;
for(y=0;y<bm.Height;y++) {
for(x=0;x<bm.Width;x++) {
c=bm.GetPixel(x,y);
// convert to 888
r=(byte)(c.R & 0xf8);
g=(byte)(c.G & 0xfc);
b=(byte)(c.B & 0xf8);
b1=(byte)(r | (g >> 5));
b2=(byte)((g << 3) | (b >> 3));
fs.WriteByte(b1);
fs.WriteByte(b2);
}
}
}
}
}

View File

@@ -0,0 +1,116 @@
using System;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Reflection;
using System.Diagnostics;
namespace bm2rgbi {
class Program {
/// <summary>
/// Main entry point
/// </summary>
static void Main(string[] args_) {
new Program().run(args_);
}
/// <summary>
/// Run the program
/// </summary>
public void run(string[] args_) {
ProgramArgs args;
Bitmap bm;
try {
args=new ProgramArgs(args_);
bm=new Bitmap(new FileStream(args.InputBitmapFilename,FileMode.Open,FileAccess.Read,FileShare.Read));
printBitmapInfo(bm);
Console.WriteLine("Writing converted bitmap");
using(FileStream fs=new FileStream(args.OutputBitmapFilename,FileMode.Create,FileAccess.Write,FileShare.None))
args.TargetDevice.convert(bm,fs);
if(args.Compress) {
Console.WriteLine("Compressing converted bitmap");
compress(args.OutputBitmapFilename);
}
Console.WriteLine("Completed OK");
}
catch(Exception ex) {
Console.WriteLine(ex.Message);
}
}
/// <summary>
/// Compress the target
/// </summary>
private void compress(string filename) {
string procpath,tempfile;
ProcessStartInfo psi;
Process p;
FileInfo fi;
long oldlength,percent;
// get our executable location
procpath=Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
// get the temp file path
tempfile=filename+".lzg";
// get the old length
fi=new FileInfo(filename);
oldlength=fi.Length;
// run the compressor
psi=new ProcessStartInfo(Path.Combine(procpath,"lzg.exe"),"-1 "+filename+" "+tempfile);
psi.CreateNoWindow=true;
psi.WindowStyle=ProcessWindowStyle.Hidden;
if((p=Process.Start(psi))==null)
throw new Exception("Failed to start compression process (lzg.exe)");
// wait for it to finish
p.WaitForExit();
// if the temp file is >0 bytes we assume it worked :-;
fi=new FileInfo(tempfile);
if(fi.Length==0)
throw new Exception("The compression process (lzg.exe) failed");
File.Delete(filename);
File.Move(tempfile,filename);
percent=(oldlength-fi.Length)*100/oldlength;
Console.WriteLine("Compression completed: "+oldlength+" down to "+fi.Length+" ("+percent+"%) bytes");
}
/// <summary>
/// show some bm info
/// </summary>
private void printBitmapInfo(Bitmap bm_) {
Console.WriteLine("Width: "+bm_.Width);
Console.WriteLine("Height: "+bm_.Height);
Console.WriteLine("Format: "+bm_.PixelFormat.ToString());
}
}
}

View File

@@ -0,0 +1,136 @@
using System;
namespace bm2rgbi {
/// <summary>
/// program args class
/// </summary>
class ProgramArgs {
/// <summary>
/// properties
/// </summary>
public string InputBitmapFilename { get; private set; }
public string OutputBitmapFilename { get; private set; }
public IBitmapConverter TargetDevice { get; private set; }
public bool Compress { get; private set; }
/// <summary>
/// constructor
/// </summary>
public ProgramArgs(string[] args) {
int depth;
string device;
if(args.Length!=4 && args.Length!=5)
usage();
InputBitmapFilename=args[0];
OutputBitmapFilename=args[1];
device=args[2];
depth=int.Parse(args[3]);
if(args.Length==5) {
if(args[4].Equals("-c"))
this.Compress=true;
else
usage();
}
else
this.Compress=false;
switch(device.ToLower()) {
case "hx8347a":
this.TargetDevice=HX8347AConverter.createInstance(depth);
break;
case "hx8352a":
this.TargetDevice=HX8352AConverter.createInstance(depth);
break;
case "ili9325":
this.TargetDevice=ILI9325Converter.createInstance(depth);
break;
case "ili9325a":
this.TargetDevice=ILI9325AConverter.createInstance(depth);
break;
case "ili9327":
this.TargetDevice=ILI9327Converter.createInstance(depth);
break;
case "ili9481":
this.TargetDevice=ILI9481Converter.createInstance(depth);
break;
case "mc2pa8201":
this.TargetDevice=MC2PA8201Converter.createInstance(depth);
break;
case "lds285":
this.TargetDevice=LDS285Converter.createInstance(depth);
break;
case "ssd1963":
this.TargetDevice=SSD1963Converter.createInstance(depth);
break;
case "st7783":
this.TargetDevice=ST7783Converter.createInstance(depth);
break;
case "r61523":
this.TargetDevice=R61523Converter.createInstance(depth);
break;
default:
throw new Exception(device+" is an unrecognised device");
}
}
/// <summary>
/// show usage message and exit abruptly
/// </summary>
private void usage() {
Console.WriteLine("Usage: bm2rgbi input-image-file output-image-file target-device target-colour-depth [-c]\n");
Console.WriteLine("-c : compress the output in LZG format");
Console.WriteLine("Supported devices and colours:");
Console.WriteLine(" ili9325 64");
Console.WriteLine(" ili9325 262");
Console.WriteLine(" ili9325a 64 (Arduino Adafruit shield)");
Console.WriteLine(" ili9325a 262 (Arduino Adafruit shield)");
Console.WriteLine(" ili9327 64");
Console.WriteLine(" ili9327 262");
Console.WriteLine(" ili9481 64");
Console.WriteLine(" ili9481 262");
Console.WriteLine(" hx8347a 64");
Console.WriteLine(" hx8352a 64");
Console.WriteLine(" hx8352a 262");
Console.WriteLine(" mc2pa8201 64");
Console.WriteLine(" mc2pa8201 262");
Console.WriteLine(" mc2pa8201 16");
Console.WriteLine(" lds285 64");
Console.WriteLine(" lds285 262");
Console.WriteLine(" lds285 16");
Console.WriteLine(" ssd1963 16");
Console.WriteLine(" ssd1963 262");
Console.WriteLine(" st7783 64");
Console.WriteLine(" st7783 262");
Console.WriteLine(" r61523 64");
Console.WriteLine(" r61523 262");
Console.WriteLine(" r61523 16");
Environment.Exit(0);
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("bm2rgbi")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("bm2rgbi")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("89102cae-0e94-42ec-abe3-f4e4ca755bdb")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,43 @@
using System.Drawing;
using System.IO;
namespace bm2rgbi {
/// <summary>
/// 16M colour converter for R61523. This is a packed format:
/// BBBBBBBB GGGGGGGG RRRRRRRR
/// </summary>
class R61523Converter16 : R61523Converter, IBitmapConverter {
/// <summary>
/// Do the conversion.
/// </summary>
public void convert(Bitmap bm,FileStream fs) {
int x,y;
byte r,g,b;
Color c;
for(y=0;y<bm.Height;y++) {
for(x=0;x<bm.Width;x++) {
c=bm.GetPixel(x,y);
// convert to 888
r=(byte)c.R;
g=(byte)c.G;
b=(byte)c.B;
fs.WriteByte(b);
fs.WriteByte(0);
fs.WriteByte(r);
fs.WriteByte(g);
}
}
}
}
}

View File

@@ -0,0 +1,33 @@
using System;
namespace bm2rgbi {
/// <summary>
/// Convert to R61523 internal format
/// </summary>
abstract public class R61523Converter {
/// <summary>
/// Get an instance of the converter
/// </summary>
static public IBitmapConverter createInstance(int depth) {
switch(depth) {
case 64:
return new R61523Converter64();
case 262:
return new R61523Converter262();
case 16:
return new R61523Converter16();
default:
throw new Exception(depth+" is not a recognised colour depth for the R61523");
}
}
}
}

View File

@@ -0,0 +1,43 @@
using System.Drawing;
using System.IO;
namespace bm2rgbi {
/// <summary>
/// 262K colour converter for R61523. This is a packed format:
/// BBBBBB00 GGGGGG00 RRRRRR00
/// </summary>
class R61523Converter262 : R61523Converter, IBitmapConverter {
/// <summary>
/// Do the conversion.
/// </summary>
public void convert(Bitmap bm,FileStream fs) {
int x,y;
byte r,g,b;
Color c;
for(y=0;y<bm.Height;y++) {
for(x=0;x<bm.Width;x++) {
c=bm.GetPixel(x,y);
// convert to 666
r=(byte)(c.R & 0xFC);
g=(byte)(c.G & 0xFC);
b=(byte)(c.B & 0xFC);
fs.WriteByte(b);
fs.WriteByte(0);
fs.WriteByte(r);
fs.WriteByte(g);
}
}
}
}
}

View File

@@ -0,0 +1,26 @@
using System.Drawing;
using System.IO;
namespace bm2rgbi {
/// <summary>
/// Converter for 64K colours
/// </summary>
public class R61523Converter64 : R61523Converter, IBitmapConverter {
/// <summary>
/// Use the generic converter
/// </summary>
private Generic565Converter _converter=new Generic565Converter();
/// <summary>
/// Do the conversion
/// </summary>
public void convert(Bitmap bm,FileStream fs) {
_converter.convertBGR(bm,fs);
}
}
}

View File

@@ -0,0 +1,29 @@
using System;
namespace bm2rgbi {
/// <summary>
/// Convert to SSD1963 internal format
/// </summary>
abstract public class SSD1963Converter {
/// <summary>
/// Get an instance of the converter
/// </summary>
static public IBitmapConverter createInstance(int depth) {
switch(depth) {
case 16:
return new SSD1963Converter16();
case 262:
return new SSD1963Converter262();
default:
throw new Exception(depth+" is not a recognised colour depth for the SSD1963");
}
}
}
}

View File

@@ -0,0 +1,49 @@
using System.Drawing;
using System.IO;
namespace bm2rgbi {
/// <summary>
/// 16M colour converter for SSD1963. This is a packed format:
/// 0000RRRRRRRRGGGG 0000GGGGBBBBBBBB
/// </summary>
class SSD1963Converter16 : SSD1963Converter, IBitmapConverter {
/// <summary>
/// Do the conversion.
/// </summary>
public void convert(Bitmap bm,FileStream fs) {
int x,y;
byte red,green,blue;
Color c;
ushort first,second;
for(y=0;y<bm.Height;y++) {
for(x=0;x<bm.Width;x++) {
c=bm.GetPixel(x,y);
// convert to new format
red=(byte)c.R;
green=(byte)c.G;
blue=(byte)c.B;
first=(ushort)(((ushort)red << 4) | (green >> 4));
second=(ushort)((((ushort)green & 0xf) << 8) | blue);
fs.WriteByte((byte)(first & 0xff));
fs.WriteByte((byte)(first >> 8));
fs.WriteByte((byte)(second & 0xff));
fs.WriteByte((byte)(second >> 8));
}
}
}
}
}

View File

@@ -0,0 +1,49 @@
using System.Drawing;
using System.IO;
namespace bm2rgbi {
/// <summary>
/// 262K colour converter for SSD1963. This is a packed format:
/// 0000RRRRRRRRGGGG 0000GGGGBBBBBBBB
/// </summary>
class SSD1963Converter262 : SSD1963Converter, IBitmapConverter {
/// <summary>
/// Do the conversion.
/// </summary>
public void convert(Bitmap bm,FileStream fs) {
int x,y;
byte red,green,blue;
Color c;
ushort first,second;
for(y=0;y<bm.Height;y++) {
for(x=0;x<bm.Width;x++) {
c=bm.GetPixel(x,y);
// convert to new format
red=(byte)c.R;
green=(byte)c.G;
blue=(byte)c.B;
first=(ushort)(((ushort)red << 4) | (green >> 4));
second=(ushort)((((ushort)green & 0xf) << 8) | blue);
fs.WriteByte((byte)(first & 0xff));
fs.WriteByte((byte)(first >> 8));
fs.WriteByte((byte)(second & 0xff));
fs.WriteByte((byte)(second >> 8));
}
}
}
}
}

View File

@@ -0,0 +1,29 @@
using System;
namespace bm2rgbi {
/// <summary>
/// Convert to ST7783 internal format
/// </summary>
abstract public class ST7783Converter {
/// <summary>
/// Get an instance of the converter
/// </summary>
static public IBitmapConverter createInstance(int depth) {
switch(depth) {
case 64:
return new ST7783Converter64();
case 262:
return new ST7783Converter262();
default:
throw new Exception(depth+" is not a recognised colour depth for the ST7783");
}
}
}
}

View File

@@ -0,0 +1,47 @@
using System.Drawing;
using System.IO;
namespace bm2rgbi {
/// <summary>
/// 262K colour converter for ST7783. This is a packed format:
/// 00000000000000RR RRRRGGGGGGBBBBBB
/// </summary>
class ST7783Converter262 : ST7783Converter, IBitmapConverter {
/// <summary>
/// Do the conversion.
/// </summary>
public void convert(Bitmap bm,FileStream fs) {
int x,y,r,g,b,value;
Color c;
for(y=0;y<bm.Height;y++) {
for(x=0;x<bm.Width;x++) {
c=bm.GetPixel(x,y);
// convert to 666
r=c.R & 0xFC;
g=c.G & 0xFC;
b=c.B & 0xFC;
value = r<<10;
value |= g << 4; // G into bits 6-11
value |= b >> 2; // B into bits 0-5
fs.WriteByte((byte) (value >>16));
fs.WriteByte(0);
fs.WriteByte((byte) (value & 0xff));
fs.WriteByte((byte) ((value >> 8) & 0xff));
}
}
}
}
}

View File

@@ -0,0 +1,26 @@
using System.Drawing;
using System.IO;
namespace bm2rgbi {
/// <summary>
/// Converter for 64K colours
/// </summary>
public class ST7783Converter64 : ST7783Converter, IBitmapConverter {
/// <summary>
/// Use the generic converter
/// </summary>
private Generic565Converter _converter=new Generic565Converter();
/// <summary>
/// Do the conversion
/// </summary>
public void convert(Bitmap bm,FileStream fs) {
_converter.convertRGB(bm,fs);
}
}
}

View File

@@ -0,0 +1,97 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{96885E95-63A1-4321-9708-69BF7F6FB34F}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>bm2rgbi</RootNamespace>
<AssemblyName>bm2rgbi</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<PlatformTarget>x86</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<PlatformTarget>x86</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="R61523Converter262.cs" />
<Compile Include="R615231Converter16.cs" />
<Compile Include="R61523Converter.cs" />
<Compile Include="R61523Converter64.cs" />
<Compile Include="HX8352AConverter.cs" />
<Compile Include="HX8352AConverter262.cs" />
<Compile Include="HX8352AConverter64.cs" />
<Compile Include="ILI9325AConverter.cs" />
<Compile Include="ILI9325AConverter262.cs" />
<Compile Include="ILI9325AConverter64.cs" />
<Compile Include="ST7783Converter64.cs" />
<Compile Include="ST7783Converter262.cs" />
<Compile Include="ST7783Converter.cs" />
<Compile Include="LDS285Converter64.cs" />
<Compile Include="LDS285Converter262.cs" />
<Compile Include="LDS285Converter16.cs" />
<Compile Include="LDS285Converter.cs" />
<Compile Include="MC2PA8201Converter64.cs" />
<Compile Include="MC2PA8201Converter16.cs" />
<Compile Include="Generic666RGBConverter.cs" />
<Compile Include="Generic565Converter.cs" />
<Compile Include="HX8347AConverter.cs" />
<Compile Include="HX8347AConverter64.cs" />
<Compile Include="ILI9325Converter.cs" />
<Compile Include="ILI9325Converter262.cs" />
<Compile Include="ILI9325Converter64.cs" />
<Compile Include="ILI9327Converter262.cs" />
<Compile Include="ILI9327Converter64.cs" />
<Compile Include="IBitmapConverter.cs" />
<Compile Include="ILI9327Converter.cs" />
<Compile Include="ILI9481Converter.cs" />
<Compile Include="ILI9481Converter262.cs" />
<Compile Include="ILI9481Converter64.cs" />
<Compile Include="MC2PA8201Converter.cs" />
<Compile Include="MC2PA8201Converter262.cs" />
<Compile Include="Program.cs" />
<Compile Include="ProgramArgs.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SSD1963Converter.cs" />
<Compile Include="SSD1963Converter16.cs" />
<Compile Include="SSD1963Converter262.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@@ -0,0 +1,132 @@
using System;
using System.IO;
using System.Windows.Forms;
using System.Xml;
namespace FontConv {
/*
* Class for writing out fonts suitable for the Arduino
*/
public class ArduinoFontWriter : FontWriter {
/*
* Constructor
*/
public ArduinoFontWriter(SizedFont sf,StreamWriter headerWriter,StreamWriter sourceWriter,XmlElement parent,Control refControl)
: base(sf,headerWriter,sourceWriter,parent,refControl) {
}
/*
* write trailer
*/
override protected void WriteTrailer() {
_headerWriter.Write("}\n");
}
/*
* write source trailer
*/
override protected void WriteSourceTrailer() {
_sourceWriter.Write("}\n");
}
/*
* write header
*/
override protected void WriteHeader() {
_headerWriter.Write("#pragma once\n\n");
_headerWriter.Write("#include \"Font.h\"\n\n");
_headerWriter.Write("namespace lcd {\n\n");
}
/*
* Write the source header
*/
protected override void WriteSourceHeader() {
_sourceWriter.Write("#include <avr/pgmspace.h>\n");
_sourceWriter.Write("#include \"Font.h\"\n\n");
_sourceWriter.Write("namespace lcd {\n\n");
}
/*
* write font byte declarations
*/
override protected void WriteFontBytes() {
string str;
bool[,] values;
byte b,bitpos;
int x,y;
_sourceWriter.Write(" // byte definitions for "+_font.Identifier+"\n\n");
foreach(char c in _font.Characters()) {
str=GetBytesName(c);
_sourceWriter.Write(" const uint8_t __attribute__((progmem)) "+str+"[] PROGMEM={ ");
values=FontUtil.GetCharacterBitmap(_refControl,_font.GdiFont,c,_font.XOffset,_font.YOffset,_font.ExtraLines);
b=0;
bitpos=0;
for(y=0;y<values.GetLength(1);y++)
{
for(x=0;x<values.GetLength(0);x++)
{
if(values[x,y])
b|=(byte)(1 << bitpos);
if(bitpos++==7)
{
_sourceWriter.Write(b.ToString()+",");
bitpos=0;
b=0;
}
}
}
if(bitpos>0)
_sourceWriter.Write(b.ToString()+",");
_sourceWriter.Write("};\n");
}
_sourceWriter.Write("\n");
}
/*
* write font char declarations
*/
override protected void WriteFontChars() {
_sourceWriter.Write(" // character definitions for "+_font.Identifier+"\n\n");
_sourceWriter.Write(" extern const struct FontChar __attribute__((progmem)) "+GetCharName()+"[] PROGMEM={\n");
foreach(char c in _font.Characters()) {
_sourceWriter.Write(" { ");
_sourceWriter.Write(Convert.ToUInt16(c).ToString()+",");
_sourceWriter.Write(GetCharWidth(c)+",");
_sourceWriter.Write(GetBytesName(c)+" },\n");
}
_sourceWriter.Write(" };\n\n");
}
}
}

View File

@@ -0,0 +1,37 @@
namespace FontConv
{
partial class CharPreview
{
/*
* Required designer variable.
*/
private System.ComponentModel.IContainer components=null;
/*
* Clean up any resources being used.
*/
protected override void Dispose(bool disposing)
{
if(disposing&&(components!=null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/*
* Required method for Designer support - do not modify
* the contents of this method with the code editor.
*/
private void InitializeComponent()
{
components=new System.ComponentModel.Container();
this.AutoScaleMode=System.Windows.Forms.AutoScaleMode.Font;
}
#endregion
}
}

View File

@@ -0,0 +1,122 @@
using System.Drawing;
using System.Windows.Forms;
namespace FontConv
{
/*
* character preview
*/
public partial class CharPreview : UserControl
{
/*
* bitmap
*/
private Bitmap _bitmap;
/*
* constants
*/
public const int PixelSize=8;
/*
* constructor
*/
public CharPreview()
{
InitializeComponent();
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer,true);
}
/*
* create from the given character
*/
public void Create(char c_,int xoffset_,int yoffset_,int extraLines_)
{
bool[,] values;
int x,y;
Point pos;
Point[] line;
values=FontUtil.GetCharacterBitmap(this,this.Font,c_,xoffset_,yoffset_,extraLines_);
_bitmap=new Bitmap(values.GetLength(0)*PixelSize,values.GetLength(1)*PixelSize);
pos=Point.Empty;
using(Graphics g=Graphics.FromImage(_bitmap))
{
g.FillRectangle(Brushes.White,0,0,_bitmap.Width,_bitmap.Height);
for(y=0;y<values.GetLength(1);y++)
{
for(x=0;x<values.GetLength(0);x++)
{
if(values[x,y])
g.FillRectangle(Brushes.Black,pos.X,pos.Y,PixelSize,PixelSize);
pos.X+=PixelSize;
}
pos.X=0;
pos.Y+=PixelSize;
}
// grid
line=new Point[2];
line[0].X=line[1].X=0;
line[0].Y=0;
line[1].Y=_bitmap.Height;
for(x=0;x<=values.GetLength(0);x++)
{
g.DrawLine(Pens.LightGray,line[0],line[1]);
line[0].X+=PixelSize;
line[1].X+=PixelSize;
}
line[0].X=0;
line[1].X=_bitmap.Width;
line[0].Y=line[1].Y=0;
for(y=0;y<=values.GetLength(1);y++)
{
g.DrawLine(Pens.LightGray,line[0],line[1]);
line[0].Y+=PixelSize;
line[1].Y+=PixelSize;
}
}
// set the control size
this.Size=_bitmap.Size;
}
/*
* paint the background
*/
protected override void OnPaintBackground(PaintEventArgs e)
{
}
/*
* paint the control
*/
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.DrawImageUnscaled(_bitmap,0,0);
}
}
}

View File

@@ -0,0 +1,47 @@
namespace FontConv
{
partial class FontChar
{
/*
* Required designer variable.
*/
private System.ComponentModel.IContainer components=null;
/*
* Clean up any resources being used.
*/
protected override void Dispose(bool disposing)
{
if(disposing&&(components!=null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/*
* Required method for Designer support - do not modify
* the contents of this method with the code editor.
*/
private void InitializeComponent()
{
this.SuspendLayout();
//
// FontChar
//
this.AutoScaleDimensions=new System.Drawing.SizeF(6F,13F);
this.AutoScaleMode=System.Windows.Forms.AutoScaleMode.Font;
this.Name="FontChar";
this.MouseLeave+=new System.EventHandler(this.FontChar_MouseLeave);
this.MouseEnter+=new System.EventHandler(this.FontChar_MouseEnter);
this.ResumeLayout(false);
}
#endregion
}
}

View File

@@ -0,0 +1,101 @@
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System;
namespace FontConv
{
/*
* Font character
*/
public partial class FontChar : UserControl
{
/*
* members
*/
private bool _hover=false;
private ToolTip _tooltip;
/*
* properties
*/
public bool Selected { get; set; }
/*
* constructor
*/
public FontChar(ToolTip tooltip)
{
InitializeComponent();
_tooltip=tooltip;
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer,true);
}
/*
* background paint
*/
protected override void OnPaintBackground(PaintEventArgs e)
{
Brush b;
if(!this.Selected && _hover)
b=Brushes.Tan;
else
b=this.Selected ? SystemBrushes.Highlight : SystemBrushes.Control;
e.Graphics.FillRectangle(b,e.ClipRectangle);
}
/*
* paint the character
*/
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.TextRenderingHint=TextRenderingHint.SingleBitPerPixel;
e.Graphics.DrawString(
this.Text,
this.Font,
this.Selected ? SystemBrushes.HighlightText : SystemBrushes.WindowText,
0,0,
StringFormat.GenericTypographic);
}
/*
* mouse enter
*/
private void FontChar_MouseEnter(object sender,System.EventArgs e)
{
_hover=true;
_tooltip.SetToolTip(this,Convert.ToInt32(this.Text[0]).ToString());
Invalidate();
}
/*
* mouse leave
*/
private void FontChar_MouseLeave(object sender,System.EventArgs e)
{
_hover=false;
Invalidate();
}
}
}

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,127 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{34591688-EAE4-41D5-957C-AB5FA906BA80}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>FontConv</RootNamespace>
<AssemblyName>FontConv</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>3.5</OldToolsVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ArduinoFontWriter.cs" />
<Compile Include="CharPreview.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="CharPreview.Designer.cs">
<DependentUpon>CharPreview.cs</DependentUpon>
</Compile>
<Compile Include="FontChar.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="FontChar.Designer.cs">
<DependentUpon>FontChar.cs</DependentUpon>
</Compile>
<Compile Include="FontReader.cs" />
<Compile Include="FontUtil.cs" />
<Compile Include="FontWriter.cs" />
<Compile Include="FormMain.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="FormMain.Designer.cs">
<DependentUpon>FormMain.cs</DependentUpon>
</Compile>
<Compile Include="PreviewText.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="PreviewText.Designer.cs">
<DependentUpon>PreviewText.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="FontChar.resx">
<DependentUpon>FontChar.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="FormMain.resx">
<DependentUpon>FormMain.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<Compile Include="SizedFont.cs" />
<Compile Include="Stm32plusFontWriter.cs" />
<Compile Include="TargetDevice.cs" />
<Compile Include="Util.cs" />
<Compile Include="XmlUtil.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FontConv", "FontConv.csproj", "{34591688-EAE4-41D5-957C-AB5FA906BA80}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{34591688-EAE4-41D5-957C-AB5FA906BA80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{34591688-EAE4-41D5-957C-AB5FA906BA80}.Debug|Any CPU.Build.0 = Debug|Any CPU
{34591688-EAE4-41D5-957C-AB5FA906BA80}.Release|Any CPU.ActiveCfg = Release|Any CPU
{34591688-EAE4-41D5-957C-AB5FA906BA80}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Xml;
using System.IO;
using System.Windows.Forms;
namespace FontConv {
abstract public class FontReader {
/*
* load from XML
*/
static public SizedFont Load(String filename) {
XmlDocument doc;
XmlNodeList charsNodes;
char c;
String fontfile;
int fontsize;
SizedFont sf;
// read the XML
doc=new XmlDocument();
doc.Load(filename);
// get file and size to create the SizedFont
fontfile=XmlUtil.GetString(doc.DocumentElement,"Filename",null,true);
fontsize=XmlUtil.GetInt(doc.DocumentElement,"Size",0,true);
// give the user the chance to find missing fonts
if(!File.Exists(fontfile)) {
OpenFileDialog ofn;
if(MessageBox.Show(fontfile+" does not exist. Click OK to browse for the font file or Cancel to abort","Font not found",MessageBoxButtons.OKCancel,MessageBoxIcon.Stop)==DialogResult.Cancel)
throw new Exception("Font not found");
ofn=new OpenFileDialog();
ofn.FileName=fontfile;
ofn.Filter="Font Files (*.ttf)|*.ttf|All Files (*.*)|*.*||";
if(ofn.ShowDialog()==DialogResult.Cancel)
throw new Exception("Font not found");
fontfile=ofn.FileName;
}
sf=new SizedFont(fontfile,fontsize);
// fill in the adjustments
sf.XOffset=XmlUtil.GetInt(doc.DocumentElement,"XOffset",0,true);
sf.YOffset=XmlUtil.GetInt(doc.DocumentElement,"YOffset",0,true);
sf.ExtraLines=XmlUtil.GetInt(doc.DocumentElement,"ExtraLines",0,true);
sf.CharSpace=XmlUtil.GetInt(doc.DocumentElement,"CharSpace",0,true);
if((charsNodes=doc.DocumentElement.SelectNodes("Chars/Char"))!=null) {
foreach(XmlNode charNode in charsNodes) {
c=Convert.ToChar(UInt16.Parse(charNode.InnerText));
sf.Add(c);
}
}
return sf;
}
}
}

View File

@@ -0,0 +1,107 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Drawing.Text;
namespace FontConv
{
/*
* font utils
*/
public class FontUtil
{
[DllImport("gdi32.dll")]
public static extern uint GetFontUnicodeRanges(IntPtr hdc, IntPtr lpgs);
[DllImport("gdi32.dll")]
public extern static IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
public struct FontRange
{
public UInt16 Low;
public UInt16 High;
}
/*
* get unicode font ranges
*/
static public List<FontRange> GetFontUnicodeRanges(Font font)
{
Graphics g = Graphics.FromHwnd(IntPtr.Zero);
IntPtr hdc = g.GetHdc();
IntPtr hFont = font.ToHfont();
IntPtr old = SelectObject(hdc, hFont);
uint size = GetFontUnicodeRanges(hdc, IntPtr.Zero);
IntPtr glyphSet = Marshal.AllocHGlobal((int)size);
GetFontUnicodeRanges(hdc, glyphSet);
List<FontRange> fontRanges = new List<FontRange>();
int count = Marshal.ReadInt32(glyphSet, 12);
for (int i = 0; i < count; i++)
{
FontRange range = new FontRange();
range.Low = (UInt16)Marshal.ReadInt16(glyphSet, 16 + i * 4);
range.High = (UInt16)(range.Low + Marshal.ReadInt16(glyphSet, 18 + i * 4) - 1);
fontRanges.Add(range);
}
SelectObject(hdc, old);
Marshal.FreeHGlobal(glyphSet);
g.ReleaseHdc(hdc);
g.Dispose();
return fontRanges;
}
/*
* get the character bitmap
*/
static public bool[,] GetCharacterBitmap(Control refControl_,Font f_,char c_,int xoffset_,int yoffset_,int extraLines_)
{
bool[,] values;
int x,y,width;
Bitmap bm;
Color cr;
using(Graphics g=refControl_.CreateGraphics())
{
g.TextRenderingHint=TextRenderingHint.SingleBitPerPixel;
if(c_==' ')
width=(int)g.MeasureString("-",f_,PointF.Empty,StringFormat.GenericTypographic).Width;
else
width=(int)g.MeasureString(c_.ToString(),f_,PointF.Empty,StringFormat.GenericTypographic).Width;
bm=new Bitmap(width,(int)f_.Size+extraLines_,g);
using(Graphics g2=Graphics.FromImage(bm))
{
g2.FillRectangle(Brushes.White,0,0,bm.Width,bm.Height);
g2.TextRenderingHint=TextRenderingHint.SingleBitPerPixel;
g2.DrawString(c_.ToString(),f_,Brushes.Black,xoffset_,yoffset_,StringFormat.GenericTypographic);
values=new bool[bm.Width,bm.Height];
for(y=0;y<bm.Height;y++)
{
for(x=0;x<bm.Width;x++)
{
cr=bm.GetPixel(x,y);
values[x,y]=cr.B==0 && cr.G==0 && cr.R==0;
}
}
}
}
return values;
}
}
}

View File

@@ -0,0 +1,208 @@
using System;
using System.Drawing;
using System.Drawing.Text;
using System.IO;
using System.Windows.Forms;
using System.Xml;
namespace FontConv {
/*
* Helper for writing fonts
*/
abstract public class FontWriter {
/*
* Members
*/
protected SizedFont _font;
protected StreamWriter _headerWriter;
protected StreamWriter _sourceWriter;
protected XmlElement _parent;
protected Control _refControl;
/*
* For the derivations
*/
abstract protected void WriteSourceHeader();
abstract protected void WriteHeader();
abstract protected void WriteTrailer();
abstract protected void WriteSourceTrailer();
abstract protected void WriteFontBytes();
abstract protected void WriteFontChars();
/*
* Constructor
*/
protected FontWriter(SizedFont sf,StreamWriter headerWriter,StreamWriter sourceWriter,XmlElement parent,Control refControl) {
_font=sf;
_headerWriter=headerWriter;
_sourceWriter=sourceWriter;
_parent=parent;
_refControl=refControl;
}
/*
* Save font
*/
static public void Save(SizedFont sf,String xmlFilename,Control refControl,TargetDevice targetDevice) {
String headerFilename,sourceFilename;
XmlDocument doc;
XmlElement root;
FontWriter fw;
// filename has .xml extension. calculate same name with .h and .cpp
headerFilename=Path.GetFileNameWithoutExtension(xmlFilename)+".h";
headerFilename=Path.Combine(Path.GetDirectoryName(xmlFilename),headerFilename);
sourceFilename=Path.GetFileNameWithoutExtension(xmlFilename)+".cpp";
sourceFilename=Path.Combine(Path.GetDirectoryName(xmlFilename),sourceFilename);
// create header stream
using(StreamWriter headerWriter=new StreamWriter(headerFilename)) {
using(StreamWriter sourceWriter=new StreamWriter(sourceFilename)) {
// create XML parent
doc=new XmlDocument();
root=doc.CreateElement("FontConv");
doc.AppendChild(root);
switch(targetDevice) {
case TargetDevice.ARDUINO:
fw=new ArduinoFontWriter(sf,headerWriter,sourceWriter,root,refControl);
break;
case TargetDevice.STM32PLUS:
fw=new Stm32plusFontWriter(sf,headerWriter,sourceWriter,root,refControl);
break;
default:
throw new Exception("Unknown device");
}
fw.Save();
doc.Save(xmlFilename);
}
}
}
/*
* Save header and XML
*/
public void Save() {
SaveXml();
// header
WriteHeader();
WriteFont();
WriteTrailer();
// source
WriteSourceHeader();
WriteFontBytes();
WriteFontChars();
WriteSourceTrailer();
}
/*
* Write XML
*/
private void SaveXml() {
XmlElement chars;
XmlUtil.AppendString(_parent,"Filename",_font.Filename);
XmlUtil.AppendInt(_parent,"Size",_font.Size);
XmlUtil.AppendInt(_parent,"XOffset",_font.XOffset);
XmlUtil.AppendInt(_parent,"YOffset",_font.YOffset);
XmlUtil.AppendInt(_parent,"ExtraLines",_font.ExtraLines);
XmlUtil.AppendInt(_parent,"CharSpace",_font.CharSpace);
chars=_parent.OwnerDocument.CreateElement("Chars");
foreach(char c in _font.Characters())
XmlUtil.AppendInt(chars,"Char",Convert.ToUInt16(c));
_parent.AppendChild(chars);
}
/*
* get bytes name
*/
protected string GetBytesName(char c) {
return _font.Identifier+Convert.ToUInt16(c).ToString()+"_BYTES";
}
/*
* get char name
*/
protected string GetCharName() {
return _font.Identifier+"_CHAR";
}
/*
* get the width of this character
*/
protected int GetCharWidth(char c) {
using(Graphics g=_refControl.CreateGraphics()) {
g.TextRenderingHint=TextRenderingHint.SingleBitPerPixel;
return (int)g.MeasureString(c==' ' ? "-" : c.ToString(),_font.GdiFont,0,StringFormat.GenericTypographic).Width;
}
}
/*
* Write the font declaration
*/
protected void WriteFont() {
int firstChar,charCount,height,spacing;
firstChar=_font.GetFirstCharacter();
charCount=_font.Characters().Count;
height=_font.Size+_font.ExtraLines;
spacing=_font.CharSpace;
_headerWriter.Write(" // helper so the user can just do 'new fontname' without having to know the parameters\n\n");
_headerWriter.Write(" extern const struct FontChar "+GetCharName()+"[];\n\n");
_headerWriter.Write(" class Font_"+_font.Name+_font.Size+" : public Font {\n");
_headerWriter.Write(" public:\n");
_headerWriter.Write(" Font_"+_font.Name+_font.Size+"()\n");
_headerWriter.Write(" : Font("+firstChar+","+charCount+","+height+","+spacing+","+GetCharName()+") {\n");
_headerWriter.Write(" }\n");
_headerWriter.Write(" };\n");
}
}
}

View File

@@ -0,0 +1,535 @@
namespace FontConv
{
partial class FormMain
{
/*
* Required designer variable.
*/
private System.ComponentModel.IContainer components=null;
/*
* Clean up any resources being used.
*/
protected override void Dispose(bool disposing)
{
if(disposing&&(components!=null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/*
* Required method for Designer support - do not modify
* the contents of this method with the code editor.
*/
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormMain));
this._charsPanel = new System.Windows.Forms.FlowLayoutPanel();
this._previewPanel = new System.Windows.Forms.FlowLayoutPanel();
this.label3 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this._charSpace = new System.Windows.Forms.NumericUpDown();
this._extraLines = new System.Windows.Forms.NumericUpDown();
this._xoffset = new System.Windows.Forms.NumericUpDown();
this._yoffset = new System.Windows.Forms.NumericUpDown();
this.BottomToolStripPanel = new System.Windows.Forms.ToolStripPanel();
this.TopToolStripPanel = new System.Windows.Forms.ToolStripPanel();
this.RightToolStripPanel = new System.Windows.Forms.ToolStripPanel();
this.LeftToolStripPanel = new System.Windows.Forms.ToolStripPanel();
this.ContentPanel = new System.Windows.Forms.ToolStripContentPanel();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this._fontSize = new System.Windows.Forms.NumericUpDown();
this._btnBrowseFontFile = new System.Windows.Forms.Button();
this._editFontFile = new System.Windows.Forms.TextBox();
this.label5 = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this._btnSelect7Bit = new System.Windows.Forms.Button();
this._btnSelectAlpha = new System.Windows.Forms.Button();
this.groupBox3 = new System.Windows.Forms.GroupBox();
this._preview = new FontConv.PreviewText();
this._btnSave = new System.Windows.Forms.Button();
this._btnLoad = new System.Windows.Forms.Button();
this._fontDialog = new System.Windows.Forms.FontDialog();
this._openFileDialog = new System.Windows.Forms.OpenFileDialog();
this._saveFileDialog = new System.Windows.Forms.SaveFileDialog();
this._btnStm32plus = new System.Windows.Forms.RadioButton();
this._btnArduino = new System.Windows.Forms.RadioButton();
this.groupBox4 = new System.Windows.Forms.GroupBox();
this._openFontFileDialog = new System.Windows.Forms.OpenFileDialog();
this._logo = new System.Windows.Forms.PictureBox();
this._tooltip = new System.Windows.Forms.ToolTip(this.components);
((System.ComponentModel.ISupportInitialize)(this._charSpace)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this._extraLines)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this._xoffset)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this._yoffset)).BeginInit();
this.groupBox1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this._fontSize)).BeginInit();
this.groupBox2.SuspendLayout();
this.groupBox3.SuspendLayout();
this.groupBox4.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this._logo)).BeginInit();
this.SuspendLayout();
//
// _charsPanel
//
this._charsPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this._charsPanel.AutoScroll = true;
this._charsPanel.Location = new System.Drawing.Point(10, 20);
this._charsPanel.Name = "_charsPanel";
this._charsPanel.Size = new System.Drawing.Size(901, 162);
this._charsPanel.TabIndex = 0;
//
// _previewPanel
//
this._previewPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this._previewPanel.AutoScroll = true;
this._previewPanel.Location = new System.Drawing.Point(10, 19);
this._previewPanel.Name = "_previewPanel";
this._previewPanel.Size = new System.Drawing.Size(901, 401);
this._previewPanel.TabIndex = 0;
//
// label3
//
this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(268, 55);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(96, 13);
this.label3.TabIndex = 8;
this.label3.Text = "Character spacing:";
//
// label2
//
this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(139, 55);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(58, 13);
this.label2.TabIndex = 6;
this.label2.Text = "Extra lines:";
//
// label1
//
this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(422, 55);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(60, 13);
this.label1.TabIndex = 10;
this.label1.Text = "Offset (x,y):";
//
// _charSpace
//
this._charSpace.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this._charSpace.Enabled = false;
this._charSpace.Location = new System.Drawing.Point(370, 53);
this._charSpace.Minimum = new decimal(new int[] {
100,
0,
0,
-2147483648});
this._charSpace.Name = "_charSpace";
this._charSpace.Size = new System.Drawing.Size(46, 20);
this._charSpace.TabIndex = 9;
this._charSpace.ValueChanged += new System.EventHandler(this._charSpace_ValueChanged);
//
// _extraLines
//
this._extraLines.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this._extraLines.Enabled = false;
this._extraLines.Location = new System.Drawing.Point(203, 53);
this._extraLines.Minimum = new decimal(new int[] {
100,
0,
0,
-2147483648});
this._extraLines.Name = "_extraLines";
this._extraLines.Size = new System.Drawing.Size(59, 20);
this._extraLines.TabIndex = 7;
this._extraLines.ValueChanged += new System.EventHandler(this._extraLines_ValueChanged);
//
// _xoffset
//
this._xoffset.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this._xoffset.Enabled = false;
this._xoffset.Location = new System.Drawing.Point(486, 53);
this._xoffset.Minimum = new decimal(new int[] {
100,
0,
0,
-2147483648});
this._xoffset.Name = "_xoffset";
this._xoffset.Size = new System.Drawing.Size(45, 20);
this._xoffset.TabIndex = 11;
this._xoffset.ValueChanged += new System.EventHandler(this._xoffset_ValueChanged);
//
// _yoffset
//
this._yoffset.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this._yoffset.Enabled = false;
this._yoffset.Location = new System.Drawing.Point(537, 53);
this._yoffset.Minimum = new decimal(new int[] {
100,
0,
0,
-2147483648});
this._yoffset.Name = "_yoffset";
this._yoffset.Size = new System.Drawing.Size(45, 20);
this._yoffset.TabIndex = 12;
this._yoffset.ValueChanged += new System.EventHandler(this._yoffset_ValueChanged);
//
// BottomToolStripPanel
//
this.BottomToolStripPanel.Location = new System.Drawing.Point(0, 0);
this.BottomToolStripPanel.Name = "BottomToolStripPanel";
this.BottomToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal;
this.BottomToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0);
this.BottomToolStripPanel.Size = new System.Drawing.Size(0, 0);
//
// TopToolStripPanel
//
this.TopToolStripPanel.Location = new System.Drawing.Point(0, 0);
this.TopToolStripPanel.Name = "TopToolStripPanel";
this.TopToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal;
this.TopToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0);
this.TopToolStripPanel.Size = new System.Drawing.Size(0, 0);
//
// RightToolStripPanel
//
this.RightToolStripPanel.Location = new System.Drawing.Point(0, 0);
this.RightToolStripPanel.Name = "RightToolStripPanel";
this.RightToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal;
this.RightToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0);
this.RightToolStripPanel.Size = new System.Drawing.Size(0, 0);
//
// LeftToolStripPanel
//
this.LeftToolStripPanel.Location = new System.Drawing.Point(0, 0);
this.LeftToolStripPanel.Name = "LeftToolStripPanel";
this.LeftToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal;
this.LeftToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0);
this.LeftToolStripPanel.Size = new System.Drawing.Size(0, 0);
//
// ContentPanel
//
this.ContentPanel.AutoScroll = true;
this.ContentPanel.Size = new System.Drawing.Size(773, 544);
//
// groupBox1
//
this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.groupBox1.Controls.Add(this._fontSize);
this.groupBox1.Controls.Add(this._btnBrowseFontFile);
this.groupBox1.Controls.Add(this.label1);
this.groupBox1.Controls.Add(this.label3);
this.groupBox1.Controls.Add(this._yoffset);
this.groupBox1.Controls.Add(this._editFontFile);
this.groupBox1.Controls.Add(this._xoffset);
this.groupBox1.Controls.Add(this._charSpace);
this.groupBox1.Controls.Add(this.label2);
this.groupBox1.Controls.Add(this.label5);
this.groupBox1.Controls.Add(this.label4);
this.groupBox1.Controls.Add(this._extraLines);
this.groupBox1.Location = new System.Drawing.Point(12, 12);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(595, 87);
this.groupBox1.TabIndex = 0;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Choose a font and size";
//
// _fontSize
//
this._fontSize.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this._fontSize.Location = new System.Drawing.Point(64, 53);
this._fontSize.Maximum = new decimal(new int[] {
999,
0,
0,
0});
this._fontSize.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this._fontSize.Name = "_fontSize";
this._fontSize.Size = new System.Drawing.Size(69, 20);
this._fontSize.TabIndex = 5;
this._fontSize.Value = new decimal(new int[] {
8,
0,
0,
0});
this._fontSize.ValueChanged += new System.EventHandler(this._fontSize_ValueChanged);
//
// _btnBrowseFontFile
//
this._btnBrowseFontFile.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this._btnBrowseFontFile.Location = new System.Drawing.Point(447, 21);
this._btnBrowseFontFile.Name = "_btnBrowseFontFile";
this._btnBrowseFontFile.Size = new System.Drawing.Size(135, 23);
this._btnBrowseFontFile.TabIndex = 3;
this._btnBrowseFontFile.Text = "Browse font file...";
this._btnBrowseFontFile.UseVisualStyleBackColor = true;
this._btnBrowseFontFile.Click += new System.EventHandler(this._btnBrowseFontFile_Click);
//
// _editFontFile
//
this._editFontFile.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this._editFontFile.Location = new System.Drawing.Point(64, 24);
this._editFontFile.Name = "_editFontFile";
this._editFontFile.ReadOnly = true;
this._editFontFile.Size = new System.Drawing.Size(377, 20);
this._editFontFile.TabIndex = 1;
//
// label5
//
this.label5.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.label5.AutoSize = true;
this.label5.Location = new System.Drawing.Point(6, 55);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(52, 13);
this.label5.TabIndex = 4;
this.label5.Text = "Font size:";
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(6, 27);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(47, 13);
this.label4.TabIndex = 0;
this.label4.Text = "Font file:";
//
// groupBox2
//
this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.groupBox2.Controls.Add(this._charsPanel);
this.groupBox2.Controls.Add(this._btnSelect7Bit);
this.groupBox2.Controls.Add(this._btnSelectAlpha);
this.groupBox2.Location = new System.Drawing.Point(12, 105);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(923, 217);
this.groupBox2.TabIndex = 1;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "Character selection";
//
// _btnSelect7Bit
//
this._btnSelect7Bit.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this._btnSelect7Bit.Enabled = false;
this._btnSelect7Bit.Location = new System.Drawing.Point(655, 188);
this._btnSelect7Bit.Name = "_btnSelect7Bit";
this._btnSelect7Bit.Size = new System.Drawing.Size(104, 23);
this._btnSelect7Bit.TabIndex = 1;
this._btnSelect7Bit.Text = "Select all 7-bit";
this._btnSelect7Bit.UseVisualStyleBackColor = true;
this._btnSelect7Bit.Click += new System.EventHandler(this._btnSelect7Bit_Click);
//
// _btnSelectAlpha
//
this._btnSelectAlpha.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this._btnSelectAlpha.Enabled = false;
this._btnSelectAlpha.Location = new System.Drawing.Point(765, 188);
this._btnSelectAlpha.Name = "_btnSelectAlpha";
this._btnSelectAlpha.Size = new System.Drawing.Size(146, 23);
this._btnSelectAlpha.TabIndex = 2;
this._btnSelectAlpha.Text = "Select all alphanumeric";
this._btnSelectAlpha.UseVisualStyleBackColor = true;
this._btnSelectAlpha.Click += new System.EventHandler(this._btnSelectAlpha_Click);
//
// groupBox3
//
this.groupBox3.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.groupBox3.Controls.Add(this._previewPanel);
this.groupBox3.Controls.Add(this._preview);
this.groupBox3.Location = new System.Drawing.Point(12, 328);
this.groupBox3.Name = "groupBox3";
this.groupBox3.Size = new System.Drawing.Size(923, 456);
this.groupBox3.TabIndex = 2;
this.groupBox3.TabStop = false;
this.groupBox3.Text = "Preview";
//
// _preview
//
this._preview.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this._preview.Location = new System.Drawing.Point(7, 426);
this._preview.Name = "_preview";
this._preview.Size = new System.Drawing.Size(904, 24);
this._preview.TabIndex = 1;
this._preview.Text = "The quick brown fox jumped over the lazy dogs.";
this._preview.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// _btnSave
//
this._btnSave.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this._btnSave.Enabled = false;
this._btnSave.Location = new System.Drawing.Point(954, 45);
this._btnSave.Name = "_btnSave";
this._btnSave.Size = new System.Drawing.Size(97, 23);
this._btnSave.TabIndex = 4;
this._btnSave.Text = "Save...";
this._btnSave.UseVisualStyleBackColor = true;
this._btnSave.Click += new System.EventHandler(this._btnSave_Click);
//
// _btnLoad
//
this._btnLoad.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this._btnLoad.Location = new System.Drawing.Point(954, 16);
this._btnLoad.Name = "_btnLoad";
this._btnLoad.Size = new System.Drawing.Size(97, 23);
this._btnLoad.TabIndex = 3;
this._btnLoad.Text = "Load...";
this._btnLoad.UseVisualStyleBackColor = true;
this._btnLoad.Click += new System.EventHandler(this._btnLoad_Click);
//
// _openFileDialog
//
this._openFileDialog.Filter = "XML Files(*.xml)|*.xml|All Files|*.*||";
//
// _saveFileDialog
//
this._saveFileDialog.Filter = "XML Files(*.xml)|*.xml|All Files|*.*||";
//
// _btnStm32plus
//
this._btnStm32plus.AutoSize = true;
this._btnStm32plus.Location = new System.Drawing.Point(10, 19);
this._btnStm32plus.Name = "_btnStm32plus";
this._btnStm32plus.Size = new System.Drawing.Size(72, 17);
this._btnStm32plus.TabIndex = 0;
this._btnStm32plus.TabStop = true;
this._btnStm32plus.Text = "stm32plus";
this._btnStm32plus.UseVisualStyleBackColor = true;
//
// _btnArduino
//
this._btnArduino.AutoSize = true;
this._btnArduino.Location = new System.Drawing.Point(10, 40);
this._btnArduino.Name = "_btnArduino";
this._btnArduino.Size = new System.Drawing.Size(61, 17);
this._btnArduino.TabIndex = 1;
this._btnArduino.TabStop = true;
this._btnArduino.Text = "Arduino";
this._btnArduino.UseVisualStyleBackColor = true;
//
// groupBox4
//
this.groupBox4.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.groupBox4.Controls.Add(this._btnStm32plus);
this.groupBox4.Controls.Add(this._btnArduino);
this.groupBox4.Location = new System.Drawing.Point(954, 74);
this.groupBox4.Name = "groupBox4";
this.groupBox4.Size = new System.Drawing.Size(97, 68);
this.groupBox4.TabIndex = 5;
this.groupBox4.TabStop = false;
this.groupBox4.Text = "Target";
//
// _openFontFileDialog
//
this._openFontFileDialog.Filter = "Font Files(*.ttf)|*.ttf|All Files(*.*)|*.*||";
//
// _logo
//
this._logo.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this._logo.Cursor = System.Windows.Forms.Cursors.Hand;
this._logo.Image = ((System.Drawing.Image)(resources.GetObject("_logo.Image")));
this._logo.Location = new System.Drawing.Point(632, 21);
this._logo.Name = "_logo";
this._logo.Size = new System.Drawing.Size(280, 78);
this._logo.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
this._logo.TabIndex = 6;
this._logo.TabStop = false;
this._logo.Click += new System.EventHandler(this._logo_Click);
//
// FormMain
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.SystemColors.Control;
this.ClientSize = new System.Drawing.Size(1068, 795);
this.Controls.Add(this._logo);
this.Controls.Add(this.groupBox4);
this.Controls.Add(this._btnLoad);
this.Controls.Add(this._btnSave);
this.Controls.Add(this.groupBox3);
this.Controls.Add(this.groupBox2);
this.Controls.Add(this.groupBox1);
this.MinimumSize = new System.Drawing.Size(1084, 833);
this.Name = "FormMain";
this.Text = "Font Converter";
((System.ComponentModel.ISupportInitialize)(this._charSpace)).EndInit();
((System.ComponentModel.ISupportInitialize)(this._extraLines)).EndInit();
((System.ComponentModel.ISupportInitialize)(this._xoffset)).EndInit();
((System.ComponentModel.ISupportInitialize)(this._yoffset)).EndInit();
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this._fontSize)).EndInit();
this.groupBox2.ResumeLayout(false);
this.groupBox3.ResumeLayout(false);
this.groupBox4.ResumeLayout(false);
this.groupBox4.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this._logo)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.FlowLayoutPanel _charsPanel;
private System.Windows.Forms.FlowLayoutPanel _previewPanel;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.NumericUpDown _xoffset;
private System.Windows.Forms.NumericUpDown _yoffset;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.NumericUpDown _extraLines;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.NumericUpDown _charSpace;
private System.Windows.Forms.ToolStripPanel BottomToolStripPanel;
private System.Windows.Forms.ToolStripPanel TopToolStripPanel;
private System.Windows.Forms.ToolStripPanel RightToolStripPanel;
private System.Windows.Forms.ToolStripPanel LeftToolStripPanel;
private System.Windows.Forms.ToolStripContentPanel ContentPanel;
private PreviewText _preview;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.TextBox _editFontFile;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.Button _btnBrowseFontFile;
private System.Windows.Forms.NumericUpDown _fontSize;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.GroupBox groupBox3;
private System.Windows.Forms.Button _btnSave;
private System.Windows.Forms.Button _btnLoad;
private System.Windows.Forms.FontDialog _fontDialog;
private System.Windows.Forms.OpenFileDialog _openFileDialog;
private System.Windows.Forms.SaveFileDialog _saveFileDialog;
private System.Windows.Forms.RadioButton _btnStm32plus;
private System.Windows.Forms.RadioButton _btnArduino;
private System.Windows.Forms.GroupBox groupBox4;
private System.Windows.Forms.OpenFileDialog _openFontFileDialog;
private System.Windows.Forms.Button _btnSelectAlpha;
private System.Windows.Forms.Button _btnSelect7Bit;
private System.Windows.Forms.PictureBox _logo;
private System.Windows.Forms.ToolTip _tooltip;
}
}

View File

@@ -0,0 +1,428 @@
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Diagnostics;
namespace FontConv
{
/*
* main form
*/
public partial class FormMain : Form {
/*
* members
*/
private SizedFont _sizedFont;
/*
* constructor
*/
public FormMain() {
InitializeComponent();
}
private void RefillCharsPanel() {
FontChar fc;
try {
_charsPanel.SuspendLayout();
// empty panel
_charsPanel.Controls.Clear();
// add new. not particularly fast.
using(Graphics g=CreateGraphics()) {
foreach(FontUtil.FontRange fr in FontUtil.GetFontUnicodeRanges(_sizedFont.GdiFont)) {
for(UInt16 code=fr.Low;code<=fr.High;code++) {
char c;
int width;
fc=new FontChar(_tooltip);
c=Convert.ToChar(code);
// special case for space which we map to the width of a "-"
width=(int)g.MeasureString(c==' ' ? "-" : c.ToString(),_sizedFont.GdiFont,PointF.Empty,StringFormat.GenericTypographic).Width;
fc.Text=c.ToString();
fc.Font=_sizedFont.GdiFont;
fc.Size=new Size(width,_sizedFont.Size);
fc.Selected=_sizedFont.ContainsChar(c);
fc.Click+=OnClickFontChar;
fc.Tag=c;
_charsPanel.Controls.Add(fc);
}
}
}
_preview.Font=_sizedFont.GdiFont;
RefillPreviews();
}
finally {
_charsPanel.ResumeLayout();
}
}
/*
* refill previews panel
*/
private void RefillPreviews() {
// refill the list
_previewPanel.Controls.Clear();
foreach(CharPreview cp in _sizedFont.CreatePreviews())
_previewPanel.Controls.Add(cp);
}
/*
* font char clicked
*/
private void OnClickFontChar(object sender,EventArgs args)
{
FontChar fc;
try
{
// get values
fc=(FontChar)sender;
// toggle select
_sizedFont.ToggleSelected(fc.Text[0]);
// select control
fc.Selected^=true;
fc.Invalidate();
// add/remove from the previews
if(fc.Selected)
AddPreview(fc.Text[0]);
else
RemovePreview(fc.Text[0]);
}
catch(Exception ex) {
Util.Error(ex);
}
}
/*
* add a preview
*/
private void AddPreview(char c) {
_previewPanel.Controls.Add(_sizedFont.CreatePreview(c));
}
/*
* remove preview
*/
private void RemovePreview(char c) {
foreach(CharPreview cp in _previewPanel.Controls) {
if((char)cp.Tag==c) {
_previewPanel.Controls.Remove(cp);
return;
}
}
}
/*
* offset changed
*/
private void _xoffset_ValueChanged(object sender,EventArgs e) {
try {
_sizedFont.XOffset=(int)_xoffset.Value;
RefillPreviews();
}
catch(Exception ex) {
Util.Error(ex);
}
}
/*
* Y offset changed
*/
private void _yoffset_ValueChanged(object sender,EventArgs e) {
try {
_sizedFont.YOffset=(int)_yoffset.Value;
RefillPreviews();
}
catch(Exception ex) {
Util.Error(ex);
}
}
/*
* extra lines changed
*/
private void _extraLines_ValueChanged(object sender,EventArgs e) {
try {
_sizedFont.ExtraLines=(int)_extraLines.Value;
RefillPreviews();
}
catch(Exception ex) {
Util.Error(ex);
}
}
/*
* Character space changed
*/
private void _charSpace_ValueChanged(object sender,EventArgs e)
{
try {
_sizedFont.CharSpace=(int)_charSpace.Value;
}
catch(Exception ex) {
Util.Error(ex);
}
}
/*
* Browse for font file
*/
private void _btnBrowseFontFile_Click(object sender,EventArgs e) {
try {
// browse for font
if(_openFontFileDialog.ShowDialog(this)==DialogResult.Cancel)
return;
// set the filename
_editFontFile.Text=_openFontFileDialog.FileName;
// create the font
_sizedFont=new SizedFont(_openFontFileDialog.FileName,Convert.ToInt32(_fontSize.Value));
_preview.Font=_sizedFont.GdiFont;
_preview.Invalidate();
EnableControls();
RefillCharsPanel();
}
catch(Exception ex) {
Util.Error(ex);
}
}
/*
* Enable/disable controls
*/
private void EnableControls() {
bool enable;
enable=_sizedFont!=null;
_extraLines.Enabled=enable;
_charSpace.Enabled=enable;
_xoffset.Enabled=enable;
_yoffset.Enabled=enable;
_btnSave.Enabled=enable;
_btnSelectAlpha.Enabled=enable;
_btnSelect7Bit.Enabled=enable;
}
/*
* Check if char is valid
*/
private bool IsValidChar(char c) {
foreach(FontChar fc in _charsPanel.Controls)
if((char)fc.Tag==c)
return true;
return false;
}
/*
* Select all alphanumeric
*/
private void _btnSelectAlpha_Click(object sender,EventArgs e)
{
String alphanum="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890";
try {
Cursor.Current=Cursors.WaitCursor;
foreach(char c in alphanum)
if(IsValidChar(c))
_sizedFont.Add(c);
RefillCharsPanel();
}
catch(Exception ex) {
Util.Error(ex);
}
finally {
Cursor.Current=Cursors.Default;
}
}
/*
* Select 7 bit chars
*/
private void _btnSelect7Bit_Click(object sender,EventArgs e) {
char c;
try {
Cursor.Current=Cursors.WaitCursor;
for(c=(char)32;c<=(char)127;c++)
if(IsValidChar(c))
_sizedFont.Add(c);
RefillCharsPanel();
}
catch(Exception ex) {
Util.Error(ex);
}
finally {
Cursor.Current=Cursors.Default;
}
}
/*
* New font size
*/
private void _fontSize_ValueChanged(object sender,EventArgs e) {
try {
_sizedFont.Size=Convert.ToInt32(_fontSize.Value);
_sizedFont.CreateFont();
RefillCharsPanel();
}
catch(Exception ex) {
Util.Error(ex);
}
}
/*
* Save out
*/
private void _btnSave_Click(object sender,EventArgs e) {
TargetDevice td;
try {
// target device
if(_btnArduino.Checked)
td=TargetDevice.ARDUINO;
else if(_btnStm32plus.Checked)
td=TargetDevice.STM32PLUS;
else
throw new Exception("Please select a target device");
// get filename
if(_saveFileDialog.ShowDialog()==DialogResult.Cancel)
return;
// save operation
FontWriter.Save(_sizedFont,_saveFileDialog.FileName,this,td);
}
catch(Exception ex) {
Util.Error(ex);
}
}
/*
* Load settings
*/
private void _btnLoad_Click(object sender,EventArgs e)
{
try {
// get filename
if(_openFileDialog.ShowDialog()==DialogResult.Cancel)
return;
// load operation
_sizedFont=FontReader.Load(_openFileDialog.FileName);
_editFontFile.Text=_sizedFont.Filename;
_fontSize.Value=_sizedFont.Size;
_extraLines.Value=_sizedFont.ExtraLines;
_xoffset.Value=_sizedFont.XOffset;
_yoffset.Value=_sizedFont.YOffset;
_charSpace.Value=_sizedFont.CharSpace;
EnableControls();
RefillCharsPanel();
}
catch(Exception ex) {
Util.Error(ex);
}
}
/*
* Logo clicked
*/
private void _logo_Click(object sender,EventArgs e)
{
Process.Start("http://www.andybrown.me.uk");
}
}
}

View File

@@ -0,0 +1,813 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="_fontDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="_openFileDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>131, 17</value>
</metadata>
<metadata name="_saveFileDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>270, 17</value>
</metadata>
<metadata name="_openFontFileDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>404, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="_logo.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
p0/EfF7D6sHDhowT9b8/Jg4fNnT4y0+cvvH5lx7/4lvI843n8MwvXMW9kO/zl3Ev1APK8sdvPf2liNce
uX3ZfVP//v1FRqOs6Itv3nz97c9c/cJbnxGe/523Xrz8+bfw+fbLKDfXwxtPfOHZK8eeO3tkk+vrX37p
79579hq9/vg5+txTF+mtm4/RWzcepdfw+6vPX6UvPnPhN3NmTg8i+14PpFAUiCZOHCsaM3bkkF07a4tf
funCY1/7wvN/8/YL13771rOX6K1bl+jNpx+j1544Ry8/fobeefo8vf3M2V++8sSp7184s+uyzaYqGTRk
8PDb2f2vSw8BpscB4eDvkeSKojl/+Wevfv/ske106mAjHdlZTSd219Ph7XV0ak8dnT3QQsd31NPzF3fS
Y7tzNGxw/2O4bFjn1Q9OkyePn/bVd5/52cldm+n0pio63FZLp7fU08ltTbS/KU/ntzXSe1cOUMJW9tc4
vajzqnunQ7taLr7/zA3amc3QifoaOlZfS1c6NtGZzU303O4d9MKevWQtKuRKcEKEnlFfnxD97Q8/P+av
vvTSn59v20zHcpV0vKqWTlXg+aqb6GC+mp5qaaXLbdvo0YatdLK8lg7nqul0DvWQr6djqSo6V9lETzRs
pseb2ulcbeNvr23u+GF5xL15wpSJy/ke90jD0w7Hn7zavJt2R3N0vXk7HS2vp7P5GjqKe5/MQarrkWcb
nfRHfztQ1K8c1/yuN/eRZsyaMuql56994eKRo3Ssrp5O1NXSmYZGOlhVTWebGulMWwO9dnQvvXnqJOUd
DtJIi9++fmz/j72lYmo0q6lCK6MtLjPllTLKqYppV9hFx5J+Gjpw4DvIvhhyF8isWr1IVF7u133lvee+
9PIz1z9+9uxxOt6xmfbXZqncbaUam5JaPQZKqEup3CimvFFJOxIuOtuepyf3NNGjW2o+3laTeH/ZsgXc
wz8RS/00pYcA0+OAcPD3SGajPPTe556jmqSBIo71VB4WU8JZTFmvhMoDYqoNlVFtUEYNMQW9cjJLS2ZN
+Ce+rPPqB6dx48bMev6Jsx82RYwUUKyiGifydKBzW0ooby2jKmsJXWz20uf25mj+hDFfxiV3mTc90+am
iqvnN28kb8EyymmKqN2uoWabgnZ5FbTVbaCzFUkqnj+XK+E5iED7g0Gr6OXPPjYeo+1fNBlNFCpcR5WK
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
B50lvbUtlHWeAAAAAElFTkSuQmCC
</value>
</data>
<metadata name="_tooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>567, 17</value>
</metadata>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>55</value>
</metadata>
</root>

View File

@@ -0,0 +1,37 @@
namespace FontConv
{
partial class PreviewText
{
/*
* Required designer variable.
*/
private System.ComponentModel.IContainer components=null;
/*
* Clean up any resources being used.
*/
protected override void Dispose(bool disposing)
{
if(disposing&&(components!=null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/*
* Required method for Designer support - do not modify
* the contents of this method with the code editor.
*/
private void InitializeComponent()
{
components=new System.ComponentModel.Container();
}
#endregion
}
}

View File

@@ -0,0 +1,18 @@
using System.Drawing;
using System.Drawing.Text;
using System.Windows.Forms;
namespace FontConv {
public partial class PreviewText : Label {
public PreviewText() {
InitializeComponent();
}
protected override void OnPaint(PaintEventArgs e) {
e.Graphics.TextRenderingHint=TextRenderingHint.SingleBitPerPixel;
e.Graphics.DrawString(this.Text,this.Font,SystemBrushes.WindowText,Point.Empty);
}
}
}

View File

@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace FontConv
{
static class Program
{
/*
* The main entry point for the application.
*/
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new FormMain());
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("FontConv")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("FontConv")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("e346db56-8c1a-462e-8782-ec7b61d64abb")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.237
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace FontConv.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("FontConv.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,26 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.237
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace FontConv.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}

View File

@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

View File

@@ -0,0 +1,204 @@
using System;
using System.Collections.Generic;
using System.Xml;
using System.Drawing;
using System.Drawing.Text;
using System.IO;
using System.Windows.Forms;
namespace FontConv {
/*
* Sized font class
*/
public class SizedFont {
/*
* members
*/
private SortedDictionary<char,char> _selections=new SortedDictionary<char,char>();
private PrivateFontCollection _winFontFamilies=new PrivateFontCollection();
public String Filename { get; set; }
public String Identifier { get; set; }
public String Name { get; set; }
public int Size { get; set; }
public int ExtraLines { get; set; }
public int CharSpace { get; set; }
public int XOffset { get; set; }
public int YOffset { get; set; }
public Font GdiFont { get; set; }
/*
* constructor
*/
public SizedFont(String filename,int size) {
this.Filename=filename;
this.Size=size;
this.XOffset=0;
this.YOffset=0;
this.ExtraLines=0;
this.CharSpace=0;
_winFontFamilies.AddFontFile(filename);
CreateFont();
}
/*
* return characters
*/
public ICollection<char> Characters() {
return _selections.Keys;
}
/*
* return the selected count
*/
public int SelectionCount() {
return _selections.Count;
}
/*
* Get first selected char
*/
public char GetFirstCharacter() {
IEnumerator<char> it;
if(Characters().Count==0)
throw new Exception("No characters are selected");
it=Characters().GetEnumerator();
it.MoveNext();
return it.Current;
}
/*
* check if contains char
*/
public bool ContainsChar(char c_) {
return _selections.ContainsKey(c_);
}
/*
* toggle selection state
*/
public void ToggleSelected(char c) {
if(ContainsChar(c))
Remove(c);
else
Add(c);
}
/*
* add char
*/
public void Add(char c_) {
_selections[c_]=c_;
}
/*
* remove char
*/
public void Remove(char c_) {
_selections.Remove(c_);
}
/*
* create previews for all selected
*/
public List<CharPreview> CreatePreviews() {
List<CharPreview> previews;
previews=new List<CharPreview>();
foreach(char c in this.Characters())
previews.Add(CreatePreview(c));
return previews;
}
/*
* Create the preview
*/
public CharPreview CreatePreview(char c) {
CharPreview cp;
cp=new CharPreview();
cp.Font=this.GdiFont;
cp.Create(c,this.XOffset,this.YOffset,this.ExtraLines);
cp.Tag=c;
return cp;
}
/*
* create GDI font
*/
public void CreateFont() {
this.GdiFont=new Font(
_winFontFamilies.Families[0],
this.Size,
GraphicsUnit.Pixel);
CreateFontName();
CreateFontId();
}
/*
* font name from filename
*/
private void CreateFontName() {
String str;
str=Path.GetFileName(this.Filename);
str=Path.GetFileNameWithoutExtension(str);
this.Name=str.ToUpperInvariant().Replace(" ","_");
this.Name=this.Name.Replace("-","_");
}
/*
* font id from filename
*/
private void CreateFontId() {
this.Identifier="FDEF_"+this.Name;
}
}
}

View File

@@ -0,0 +1,130 @@
using System;
using System.IO;
using System.Windows.Forms;
using System.Xml;
namespace FontConv {
/*
* Class for writing out fonts suitable for the stm32
*/
public class Stm32plusFontWriter : FontWriter {
/*
* Constructor
*/
public Stm32plusFontWriter(SizedFont sf,StreamWriter headerWriter,StreamWriter sourceWriter,XmlElement parent,Control refControl)
: base(sf,headerWriter,sourceWriter,parent,refControl) {
}
/*
* write trailer
*/
override protected void WriteTrailer() {
_headerWriter.Write("} }\n");
}
/*
* write source trailer
*/
override protected void WriteSourceTrailer() {
_sourceWriter.Write("} }\n");
}
/*
* write source header
*/
override protected void WriteSourceHeader() {
_sourceWriter.Write("#include \"config/stm32plus.h\"\n");
_sourceWriter.Write("#include \"config/display/font.h\"\n\n");
_sourceWriter.Write("namespace stm32plus { namespace display {\n\n");
}
/*
* write header
*/
override protected void WriteHeader() {
_headerWriter.Write("#pragma once\n\n");
_headerWriter.Write("#include \"display/graphic/Font.h\"\n\n");
_headerWriter.Write("namespace stm32plus { namespace display {\n\n");
}
/*
* write font byte declarations
*/
override protected void WriteFontBytes() {
string str;
bool[,] values;
byte b,bitpos;
int x,y;
_sourceWriter.Write(" // byte definitions for "+_font.Identifier+"\n\n");
foreach(char c in _font.Characters()) {
str=GetBytesName(c);
_sourceWriter.Write(" uint8_t "+str+"[]={ ");
values=FontUtil.GetCharacterBitmap(_refControl,_font.GdiFont,c,_font.XOffset,_font.YOffset,_font.ExtraLines);
b=0;
bitpos=0;
for(y=0;y<values.GetLength(1);y++)
{
for(x=0;x<values.GetLength(0);x++)
{
if(values[x,y])
b|=(byte)(1 << bitpos);
if(bitpos++==7)
{
_sourceWriter.Write(b.ToString()+",");
bitpos=0;
b=0;
}
}
}
if(bitpos>0)
_sourceWriter.Write(b.ToString()+",");
_sourceWriter.Write("};\n");
}
_sourceWriter.Write("\n");
}
/*
* write font char declarations
*/
override protected void WriteFontChars() {
_sourceWriter.Write(" // character definitions for "+_font.Identifier+"\n\n");
_sourceWriter.Write(" extern const struct FontChar "+GetCharName()+"[]={\n");
foreach(char c in _font.Characters()) {
_sourceWriter.Write(" { ");
_sourceWriter.Write(Convert.ToUInt16(c).ToString()+",");
_sourceWriter.Write(GetCharWidth(c)+",");
_sourceWriter.Write(GetBytesName(c)+" },\n");
}
_sourceWriter.Write(" };\n\n");
}
}
}

View File

@@ -0,0 +1,12 @@

namespace FontConv {
/*
* Possible devices
*/
public enum TargetDevice {
STM32PLUS,
ARDUINO
};
}

View File

@@ -0,0 +1,14 @@
using System;
using System.Windows.Forms;
namespace FontConv
{
class Util
{
static public void Error(Exception ex_)
{
MessageBox.Show(ex_.Message,"Error",MessageBoxButtons.OK,MessageBoxIcon.Error);
}
}
}

View File

@@ -0,0 +1,120 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
namespace FontConv
{
class XmlUtil
{
/*
* append XML child
*/
public static void AppendString(XmlElement parent_,string childName_,string value_)
{
XmlElement child;
XmlText text;
if(value_==null)
return;
child=parent_.OwnerDocument.CreateElement(childName_);
text=parent_.OwnerDocument.CreateTextNode(value_);
parent_.AppendChild(child);
child.AppendChild(text);
}
/*
* append boolean
*/
public static void AppendBool(XmlElement parent_,string childName_,bool value_)
{
AppendString(parent_,childName_,value_ ? "true" : "false");
}
/*
* append XML child CDATA
*/
public static void AppendCdata(XmlElement parent_,string childName_,string value_)
{
XmlElement child;
XmlCDataSection text;
child=parent_.OwnerDocument.CreateElement(childName_);
text=parent_.OwnerDocument.CreateCDataSection(value_);
parent_.AppendChild(child);
child.AppendChild(text);
}
/*
* append int
*/
public static void AppendInt(XmlElement parent_,string childName_,int value_)
{
AppendString(parent_,childName_,value_.ToString());
}
/*
* get string
*/
public static string GetString(XmlNode parent_,string xpath_,string default_,bool required_)
{
string str;
try
{
str=parent_.SelectSingleNode(xpath_).FirstChild.InnerText;
return str;
}
catch(Exception)
{
if(required_)
throw new Exception("XML value: "+default_+" is required but is not present in this document");
return default_;
}
}
/*
* get an integer
*/
public static Int32 GetInt(XmlElement parent_,string xpath_,Int32 default_,bool required_)
{
string str;
if((str=GetString(parent_,xpath_,null,required_))==null)
return default_;
return Int32.Parse(str);
}
/*
* get a boolean
*/
public static bool GetBool(XmlElement parent_,string xpath_,bool default_,bool required_)
{
string str;
if((str=GetString(parent_,xpath_,null,required_))==null)
return default_;
return str.Equals("true");
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@@ -0,0 +1,120 @@
/*
* This file is shared between the open source stm32plus and
* Arduino XMEM graphics libraries.
*
* Copyright (c) 2011,2012 Andy Brown <www.andybrown.me.uk>
* Please see website for licensing terms.
*/
using System;
using System.IO;
using System.Windows.Forms;
namespace LzgFontConv {
/// <summary>
/// specialisations for writing Arduino font files
/// </summary>
public class ArduinoFontWriter : FontWriter {
/// <summary>
/// write the header start
/// </summary>
protected override void WriteHeaderStart(TextWriter writer) {
writer.Write("#pragma once\n\n");
writer.Write("#include \"Font.h\"\n\n");
writer.Write("namespace lcd {\n\n");
}
/// <summary>
/// write the header end
/// </summary>
protected override void WriteHeaderEnd(TextWriter writer) {
writer.Write("}\n");
}
/// <summary>
/// write the source start
/// </summary>
protected override void WriteSourceStart(TextWriter writer) {
writer.Write("#include <avr/pgmspace.h>\n");
writer.Write("#include \"Font.h\"\n\n");
writer.Write("namespace lcd {\n\n");
}
/// <summary>
/// write the source end
/// </summary>
protected override void WriteSourceEnd(TextWriter writer) {
writer.Write("}\n");
}
/// <summary>
/// Write the source body
/// </summary>
protected override void WriteSourceBody(TextWriter writer) {
bool first;
writer.Write(" // byte definitions for "+GetFontNameAndSize()+"\n\n");
foreach(CharDef cd in _charDefs.Definitions) {
// don't write empty arrays (space character)
if(cd.CompressedBytes==null || cd.CompressedBytes.Length==0)
continue;
// opening declaration
writer.Write(" const uint8_t __attribute__((progmem)) "+GetCharacterName(cd.Character)+"[] PROGMEM={ ");
// bytes
first=true;
foreach(byte b in cd.CompressedBytes) {
if(first)
first=false;
else
writer.Write(",");
writer.Write(b.ToString());
}
// closing declaration
writer.Write("};\n");
}
writer.Write("\n // character definitions for "+GetFontNameAndSize()+"\n\n");
writer.Write(" extern const struct FontChar __attribute__((progmem)) FDEF_"+GetFontName()+"_CHAR[] PROGMEM={\n");
foreach(CharDef cd in _charDefs.Definitions) {
// don't write empty arrays (space character)
writer.Write(" { ");
writer.Write(Convert.ToUInt16(cd.Character).ToString()+",");
writer.Write(cd.Size.Width+",");
writer.Write((cd.Character==' ' ? "(const uint8_t *)0" : GetCharacterName(cd.Character))+" },\n");
}
writer.Write(" };\n\n");
}
}
}

View File

@@ -0,0 +1,201 @@
/*
* This file is shared between the open source stm32plus and
* Arduino XMEM graphics libraries.
*
* Copyright (c) 2011,2012 Andy Brown <www.andybrown.me.uk>
* Please see website for licensing terms.
*/
using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Forms;
namespace LzgFontConv {
/// <summary>
/// character definition class
/// </summary>
public class CharDef {
/// <summary>
/// properties
/// </summary>
public Size Size { get; private set; }
public Bitmap CharacterBitmap;
public byte[] CompressedBytes { get; private set; }
public char Character { get; private set; }
/// <summary>
/// parse the values for the character
/// </summary>
public void Parse(Control refCtrl,FontDefinition fd,Font font,char c,bool doCompression) {
SizeF size;
this.Character=c;
// space is a special case
if(c==' ') {
ParseSpace(refCtrl,font);
return;
}
using(Graphics g=refCtrl.CreateGraphics()) {
g.TextRenderingHint=fd.Hint;
// get the size that the system thinks the character occupies
size=TextRenderer.MeasureText(g,c.ToString(),font,new Size(int.MaxValue,int.MaxValue),TextFormatFlags.NoPadding | TextFormatFlags.NoPrefix);
this.CharacterBitmap=new Bitmap(Convert.ToInt32(size.Width)+fd.ExtraSpacing.Width,Convert.ToInt32(font.GetHeight())+fd.ExtraSpacing.Height);
this.Size=this.CharacterBitmap.Size;
using(Graphics charGraphics=Graphics.FromImage(this.CharacterBitmap)) {
charGraphics.TextRenderingHint=fd.Hint;
using(SolidBrush backBrush=new SolidBrush(fd.Background))
charGraphics.FillRectangle(backBrush,0,0,this.CharacterBitmap.Width,this.CharacterBitmap.Height);
// draw the character into the center of the bitmap
TextRenderer.DrawText(charGraphics,c.ToString(),font,new Point(0,0),fd.Foreground,fd.Background,TextFormatFlags.NoPadding | TextFormatFlags.NoPrefix);
}
// scan the bitmap
if(doCompression)
ScanBitmap(this.CharacterBitmap,fd);
}
}
/// <summary>
/// scan the bitmap for its values
/// </summary>
protected void ScanBitmap(Bitmap bm,FontDefinition fd) {
string tempFile,compressedName=null;
byte[] bytes;
// get a temporary filename
tempFile=Path.GetTempFileName()+".png";
try {
// write the bitmap as a PNG to the temporary file
bm.Save(tempFile,ImageFormat.Png);
// compress the bitmap
compressedName=CompressFile(fd,tempFile);
// read back the bytes
bytes=File.ReadAllBytes(compressedName);
// encode the bytes with a length prefix in LSB order
this.CompressedBytes=new byte[bytes.Length+2];
this.CompressedBytes[0]=(byte)(bytes.Length & 0xff);
this.CompressedBytes[1]=(byte)(bytes.Length >> 8);
bytes.CopyTo(this.CompressedBytes,2);
}
finally {
File.Delete(tempFile);
if(compressedName!=null)
File.Delete(compressedName);
}
}
/// <summary>
/// run bm2rgbi on the temp file
/// </summary>
private string CompressFile(FontDefinition fd,string tempFile) {
ProcessStartInfo pi;
Process p;
FileInfo fi;
string compressedName,args;
// run bm2rgbi on the file
compressedName=tempFile+".lzg";
args="\""+tempFile+"\" \""+compressedName+"\" "+fd.CompressionOptions+" -c";
pi=new ProcessStartInfo("bm2rgbi.exe",args);
pi.CreateNoWindow=true;
pi.UseShellExecute=false;
pi.WindowStyle=ProcessWindowStyle.Hidden;
p=Process.Start(pi);
p.WaitForExit();
// make sure that it did something
fi=new FileInfo(compressedName);
if(fi.Length==0)
throw new Exception("Failed to compress the font character. Verify that bm2rgbi.exe and lzg.exe are both present in the same directory as LzgFontConv.exe");
return compressedName;
}
/// <summary>
/// Copy a bitmap section
/// </summary>
private Bitmap CopyBitmap(Bitmap srcBitmap,Rectangle section) {
// Create the new bitmap and associated graphics object
Bitmap bmp=new Bitmap(section.Width, section.Height);
using(Graphics g=Graphics.FromImage(bmp))
g.DrawImage(srcBitmap,0,0,section,GraphicsUnit.Pixel);
return bmp;
}
/// <summary>
/// parse the space character
/// </summary>
private void ParseSpace(Control refCtrl,Font font) {
StringFormat sf;
Size size;
// measure the size of a space
sf=StringFormat.GenericTypographic;
sf.FormatFlags|=StringFormatFlags.MeasureTrailingSpaces;
using(Graphics g=refCtrl.CreateGraphics())
size=g.MeasureString(" ",font,new PointF(0,0),sf).ToSize();
// a space has no height
this.Size=new Size(size.Width,0);
this.CompressedBytes=new byte[0];
}
}
}

View File

@@ -0,0 +1,77 @@
/*
* This file is shared between the open source stm32plus and
* Arduino XMEM graphics libraries.
*
* Copyright (c) 2011,2012 Andy Brown <www.andybrown.me.uk>
* Please see website for licensing terms.
*/
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace LzgFontConv {
/// <summary>
/// class to manage the extraction of the character definitions
/// </summary>
public class CharacterDefinitions {
/// <summary>
/// properties
/// </summary>
public int Height { get; private set; }
public List<CharDef> Definitions { get; private set; }
/// <summary>
/// parse character definitions. The input string must be sorted.
/// </summary>
public void ParseCharacters(Control refCtrl,FontDefinition fd,string str,bool doCompression) {
CharDef cd;
FormProgress progress;
Font font;
progress=new FormProgress();
progress.ProgressBar.Minimum=0;
progress.ProgressBar.Maximum=str.Length;
if(doCompression)
progress.Show();
// create a font
font=new Font(fd.Family,fd.Size,fd.Style,GraphicsUnit.Pixel);
this.Height=Convert.ToInt32(font.GetHeight());
try {
this.Definitions=new List<CharDef>();
foreach(char c in str) {
// update progress
progress.ProgressBar.PerformStep();
Application.DoEvents();
// create character
cd=new CharDef();
cd.Parse(refCtrl,fd,font,c,doCompression);
Definitions.Add(cd);
}
}
finally {
if(doCompression)
progress.Close();
}
}
}
}

View File

@@ -0,0 +1,45 @@
/*
* This file is shared between the open source stm32plus and
* Arduino XMEM graphics libraries.
*
* Copyright (c) 2011,2012 Andy Brown <www.andybrown.me.uk>
* Please see website for licensing terms.
*/
using System.Drawing;
using System.Windows.Forms;
namespace LzgFontConv {
/// <summary>
/// Colour display panel
/// </summary>
class ColourPanel : Panel {
/// <summary>
/// properties
/// </summary>
public Color Value { get; set; }
/// <summary>
/// Constructor
/// </summary>
public ColourPanel() {
this.Value=Color.Black;
}
/// <summary>
/// paint the background
/// </summary>
protected override void OnPaintBackground(PaintEventArgs e) {
using(SolidBrush brush=new SolidBrush(this.Value))
e.Graphics.FillRectangle(brush,this.ClientRectangle);
}
}
}

View File

@@ -0,0 +1,91 @@
/*
* This file is shared between the open source stm32plus and
* Arduino XMEM graphics libraries.
*
* Copyright (c) 2011,2012 Andy Brown <www.andybrown.me.uk>
* Please see website for licensing terms.
*/
using System.Drawing;
using System.Drawing.Text;
using System.Xml;
namespace LzgFontConv {
/// <summary>
/// holder for all font definition parameters
/// </summary>
public class FontDefinition {
/// <summary>
/// properties
/// </summary>
public string Family { get; set; }
public int Size { get; set; }
public string Characters { get; set; }
public Color Background { get; set; }
public Color Foreground { get; set; }
public TextRenderingHint Hint { get; set; }
public FontStyle Style { get; set; }
public Size TftResolution { get; set; }
public int Spacing { get; set; }
public Size ExtraSpacing { get; set; }
public string PreviewText { get; set; }
public Point PreviewPosition { get; set; }
public string CompressionOptions { get; set; }
/// <summary>
/// write as XML
/// </summary>
public void WriteXml(XmlElement parent) {
XmlUtil.AppendString(parent,"Family",this.Family);
XmlUtil.AppendInt(parent,"Size",this.Size);
XmlUtil.AppendString(parent,"Characters",this.Characters);
XmlUtil.AppendColor(parent,"Background",this.Background);
XmlUtil.AppendColor(parent,"Foreground",this.Foreground);
XmlUtil.AppendInt(parent,"TextRenderingHint",(int)this.Hint);
XmlUtil.AppendInt(parent,"Style",(int)this.Style);
XmlUtil.AppendSize(parent,"TftResolution",this.TftResolution);
XmlUtil.AppendInt(parent,"Spacing",this.Spacing);
XmlUtil.AppendSize(parent,"ExtraSpacing",this.ExtraSpacing);
XmlUtil.AppendString(parent,"PreviewText",this.PreviewText);
XmlUtil.AppendPoint(parent,"PreviewPosition",this.PreviewPosition);
XmlUtil.AppendString(parent,"CompressionOptions",this.CompressionOptions);
}
/// <summary>
/// Read from XML document
/// </summary>
public void ReadXml(string filename) {
XmlDocument doc;
XmlElement parent;
doc=new XmlDocument();
doc.Load(filename);
parent=(XmlElement)doc.SelectSingleNode("LzgFontConv");
this.Family=XmlUtil.GetString(parent,"Family",null,true);
this.Size=XmlUtil.GetInt(parent,"Size",10,true);
this.Characters=XmlUtil.GetString(parent,"Characters",null,true);
this.Background=XmlUtil.GetColor(parent,"Background");
this.Foreground=XmlUtil.GetColor(parent,"Foreground");
this.Hint=(TextRenderingHint)XmlUtil.GetInt(parent,"TextRenderingHint",0,true);
this.Style=(FontStyle)XmlUtil.GetInt(parent,"Style",0,true);
this.TftResolution=XmlUtil.GetSize(parent,"TftResolution");
this.Spacing=XmlUtil.GetInt(parent,"Spacing",0,true);
this.ExtraSpacing=XmlUtil.GetSize(parent,"ExtraSpacing");
this.PreviewText=XmlUtil.GetString(parent,"PreviewText",null,true);
this.PreviewPosition=XmlUtil.GetPoint(parent,"PreviewPosition");
this.CompressionOptions=XmlUtil.GetString(parent,"CompressionOptions",null,true);
}
}
}

View File

@@ -0,0 +1,50 @@
/*
* This file is shared between the open source stm32plus and
* Arduino XMEM graphics libraries.
*
* Copyright (c) 2011,2012 Andy Brown <www.andybrown.me.uk>
* Please see website for licensing terms.
*/
using System.IO;
using System.Windows.Forms;
namespace LzgFontConv {
/// <summary>
/// wrapper for the 3 filenames we need
/// </summary>
public class FontFilenames {
public string Header { get; set; }
public string Source { get; set; }
public string Definition { get; set; }
/// <summary>
/// Use the system dialog to get the font filenames
/// </summary>
public DialogResult GetFilenames() {
SaveFileDialog sfd;
sfd=new SaveFileDialog();
sfd.Filter="Saved Fonts (*.xml)|*.xml|All Files (*.*)|*.*||";
// show the dialog
if(sfd.ShowDialog()==DialogResult.Cancel)
return DialogResult.Cancel;
// get teh XML definition name and calculate the others
this.Definition=sfd.FileName;
this.Header=Path.Combine(Path.GetDirectoryName(sfd.FileName),Path.GetFileNameWithoutExtension(sfd.FileName)+".h");
this.Source=Path.Combine(Path.GetDirectoryName(sfd.FileName),Path.GetFileNameWithoutExtension(sfd.FileName)+".cpp");
return DialogResult.OK;
}
}
}

Some files were not shown because too many files have changed in this diff Show More