I am trying to use the following example: http://www.faqstackoverflow.com/answered/using-a-bmp-image-as-font-in-monogame
The concept seems sound. I'm using a .fnt generated by the suggested tool. It looks properly formatted and makes sense based on the [Serialization] used in the classes.
However, Every time I run the code I get this error: "An unhandled exception of type 'System.InvalidOperationException' occurred in System.Xml.dll
Additional information: There is an error in XML document (1, 1)."
I have looked feverishly around StackExchange and google, and tried many things before coming here and posting my question. I have many of the messy leavings of those attempts still in the comments posted below inside the FontLoader class I am modifying to try to fix the issue. No matter how it is sliced, it gives the same error, or worse.
public class FontLoader
{
public static FontFile Load(String filename)
{
/* XmlSerializer deserializer = new XmlSerializer(typeof(FontFile));
TextReader textReader = new StreamReader(Encoding.UTF8.GetBytes(filename).ToString());
FontFile file = (FontFile)deserializer.Deserialize(textReader);
textReader.Close();
return file;*/
byte[] bytes = Encoding.UTF8.GetBytes(System.IO.File.ReadAllText(filename));
FontFile myInstance = null;
using (MemoryStream memStream = new MemoryStream(bytes))
{
XmlSerializer tokenSerializer = new XmlSerializer(typeof(FontFile));
myInstance = (FontFile)tokenSerializer.Deserialize(memStream);
Console.WriteLine(myInstance);
return myInstance;
}
/*
XmlSerializer deserializer = new XmlSerializer(typeof(FontFile));
TextReader textReader = new StreamReader(filename);
FontFile file = (FontFile)deserializer.Deserialize(textReader);
textReader.Close();
return file;*/
/* var xml = System.IO.File.ReadAllText(filename);
using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
{
XmlSerializer serializer = new XmlSerializer(typeof(FontFile));
FontFile file = (FontFile)serializer.Deserialize(stream);
return file;
}*/
/* var writer = new StringWriter();
var serializer = new XmlSerializer((filename.GetType()));
serializer.Serialize(writer, filename);
string xml = writer.ToString();
return xml;*/
}
}
The font I'm using is Arial, as a test, so it should be ok to use. It starts out with these lines:
info face="Arial" size=32 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 outline=0
common lineHeight=32 base=26 scaleW=256 scaleH=256 pages=1 packed=0 alphaChnl=1 redChnl=0 greenChnl=0 blueChnl=0
page id=0 file="arial_0.png"
chars count=191
char id=32 x=155 y=75 width=3 height=1 xoffset=-1 yoffset=31 xadvance=8 page=0 chnl=15
And then contineus with many "char" lines that have identical structure, followed by the kernings line, and then a bunce of "kerning" lines as below with identical structure to one another:
kernings count=91
kerning first=32 second=65 amount=-2
If it ends up being something wrong with the serialization, I apologize for positing, but I am not seeing it. Please let me know if anyone has a solution. Thank you.
The issue is actually obvious from your original question, but like you I overlooked the problem at first.
After you sent me the .fnt file I spotted the issue almost immediately because I compared it to one I exported earlier. The problem is that you've exported the file in the wrong format. As you said in your question, your file looks like this:
info face="Arial" size=32 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 outline=0
common lineHeight=32 base=26 scaleW=256 scaleH=256 pages=1 packed=0 alphaChnl=1 redChnl=0 greenChnl=0 blueChnl=0
page id=0 file="arial_0.png"
chars count=191
char id=32 x=155 y=75 width=3 height=1 xoffset=-1 yoffset=31 xadvance=8 page=0 chnl=15
But it should look more like this:
<?xml version="1.0"?>
<font>
<info face="Arial" size="32" bold="1" italic="0" charset="" unicode="1" stretchH="100" smooth="1" aa="1" padding="0,0,0,0" spacing="1,1" outline="1"/>
<common lineHeight="32" base="26" scaleW="256" scaleH="256" pages="1" packed="0" alphaChnl="1" redChnl="0" greenChnl="0" blueChnl="0"/>
<pages>
<page id="0" file="arial_0.png" />
</pages>
<chars count="191">
Once you compare them side by side the difference is obvious. The first file is plain text and the second file is XML. It happens to the best of us :)
Anyway, to fix it you just need to set the file format to XML in the BMFont tool.
Click Options
Click Export Options
Click the XML radio button near the bottom of the dialog
Then export your file again.
A few things have changed since that answer you're referring to was written. Rather than writing it yourself you can use the MonoGame.Extended library to do exactly what you're trying to do. I wrote a detailed blog post about it a while back.
The first thing you'll need to do is install the MonoGame.Extended NuGet package. Run the following command in the Package Manager Console.
Install-Package MonoGame.Extended -Pre
Once it's installed you'll have a couple of DLLs in your packages folder. One of them will need to be referenced by the MonoGame Pipeline tool. The easiest way to do that is to edit your Content.mgcb file manually in a text editor. Add a reference line like this, but be sure to match the current version.
#-------------------------------- References --------------------------------#
/reference:..\..\packages\MonoGame.Extended.0.3.44-alpha\lib\MonoGame.Extended.Content.Pipeline.dll
Lastly, you can add your font file and texture to the MonoGame Pipeline tool and load like any other content.
_bitmapFont = Content.Load<BitmapFont>("my-font");
Then draw it using a sprite batch
_spriteBatch.Begin();
_spriteBatch.DrawString(_bitmapFont, "Hello World", new Vector2(100, 200), Color.Red);
_spriteBatch.End();
If you really do want to write it yourself you can look at the implementation from MonoGame.Extended as it's open source.
Related
So I'm currently working on an ASP.NET project. It requires me to write a List<> onto a XML file. I created a "data.xml" file within the project folder and here are my few lines of code:
XmlSerializer serializer = new XmlSerializer(typeof(List<BookItem>));
TextWriter filestream = new StreamWriter("data.xml");
serializer.Serialize(filestream, book);
filestream.Close();
it works well
like this
until I want to add a new record, then the file is overwritten every single time. I believe i only need few tricky lines of code to solve this problem but since my research didn't bring up any answer, i really need your help.
I am writing a plugin in c#. And I have an html in a Stringwriter and I am trying to output it as a Word document based on other samples I have researched on SO and other places on the web. Such as this: Exporting data from c# to word document and http://www.codeproject.com/Questions/196851/export-an-html-to-word-document-with-fixed-headers
For the life of me I cannot figure out why I get a NullReference exception on the first line HttpContext appears (actually how to handle it is what I am stuck on).
Here is the code:
using System.Web;
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.Buffer = true;
HttpContext.Current.Response.ContentType = "application//ms-word";
HttpContext.Current.Response.AddHeader("Content-Disposition", #"attachment; filename=D:\WORK_ORDER.doc");
HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF32;
HttpContext.Current.Response.Charset = "UTF-16";
// HttpContext.Current.EnableViewState = false;
HttpContext.Current.Response.BinaryWrite(System.Text.Encoding.UTF8.GetPreamble());
HttpContext.Current.Response.Output.Write(swSource.ToString());
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();
I am sure it is too simple. Can somebody point out what I am missing here? Thanks.
Update: I had posted the stack trace, but it is non-informative an lengthy. The additional information is more telling:
Additional information: Object reference not set to an instance of an object.
All the similar examples show only this code, no instantiation, so I am at loss how to do this, so I'd appreciate some advice.
Update:
According to the approved answer all that happened, that importing the reference library System.Web does not mean that you can use this HttpContext object in a non-web app.
See my solution posted below as an answer.
If I were to guess I'd say your project is a class library or some non web application project.
If this is the case you will not have access to httpcontext and you'll either have to change your project to a web project or you can look at alternative methods of saving your file. For example:
Writing Text File to Folder on Desktop
*note I've not tried the suggested solution.
As per Lee's answer the solution was not to use HttpContext at all.
Instead write this Word doc to file directly (and it WORKS perfectly), by replacing the above snippet to this code:
StringBuilder sb1 = new StringBuilder();
StringWriter swSource = new StringWriter(sb1);
//load swSource here with an HTML through an XSL Transformation
sb1.Replace("<html>","<html xmlns:o='urn:schemas-microsoft-com:office:office'" +
"xmlns:w='urn:schemas-microsoft-com:office:word' xmlns='http://www.w3.org/TR/REC-html40'>" +
"<head><title>Time</title>"+
"<!--[if gte mso 9]><xml><w:WordDocument>"+
"<w:View>Print</w:View><w:Zoom>100</w:Zoom>"+
"<w:DoNotOptimizeForBrowser/></w:WordDocument></xml><![endif]-->");
System.IO.StreamWriter writer = new System.IO.StreamWriter(#"D:\Test.doc", false, Encoding.Unicode); //open the file for writing.
writer.Write(sb1.ToString()); //write the current date to the file. change this with your date or something.
writer.Close();
I posted this here so the data is available if there are others like me believing they can use HttpContext just by referencing the System.Web library.
I found this great tutorial for loading XML using XLINQ (LINQ to XML).
http://www.codearsenal.net/2012/07/c-sharp-load-xml-using-xlinq.html
It helped me a lot and I got the job done with it.
The only change I made was where he had this line:
from e in XDocument.Load(#"..\..\Employees.xml").Root.Elements("employee")
I write it like this:
from el in XDocument.Load("XML_Files/Employees.xml").Root.Elements("employee")
I had to change the path like this to access a local xml file found right inside my Visual Studio project.
But now I need to save the data back to the file in my project solution. Again, my xml file is located inside my C# project. It's not on the desktop or anything, it is a file added to the project solution.
I can't seem to find any good resources for how to do this task. Does anyone know a good tutorial, or code, a reference to start?
I am inserting a list of objects into the xml files. The objects have basic data type properties, except for one of the object properties, which is a List of doubles.
Can anyone advise a good tutorial or link? Or even a generic code sample?
I'd like to keep this function as basic as possible.
Please help.
------------------ UPDATE ------------------
I actually got this kind of working now. The below code does what I need EXCEPT that it won't write the data to my local file in the Visual Studio project. It will gladly write the data to a test file I created on my desktop, however.
Does anyone know why this is??
//create the serialiser to create the xml
XmlSerializer serialiser = new XmlSerializer(typeof(List<Student>));
// Create the TextWriter for the serialiser to use
TextWriter Filestream = new StreamWriter(#"C:\\Users\\MyName\\Desktop\\output.xml");
//write to the file
serialiser.Serialize(Filestream, employees);
// Close the file
Filestream.Close();
-------- UPDATE ---------
Okay, figured it out.
This code works:
public void WriteXML()
{
//create the serialiser to create the xml
XmlSerializer serialiser = new XmlSerializer(typeof(List<Student>));
// Create the TextWriter for the serialiser to use
TextWriter Filestream = new StreamWriter(#"XML_Files\Employees.xml");
//write to the file
serialiser.Serialize(Filestream, employees);
// Close the file
Filestream.Close();
}
The data is inserted to the xml file, but it does not show in Visual Studio. But when I checked here:
C:\Users\Me\Desktop\MyProject\MyProject\bin\Debug\XML_Files
The file is overwritten.
Also, when I reload the data from the application again, the new entries come up.
The problem is in line:
TextWriter Filestream = new StreamWriter(#"C:\\Users\\MyName\\Desktop\\output.xml");
Change it to one of following:
TextWriter Filestream = new StreamWriter("C:\\Users\\MyName\\Desktop\\output.xml");
TextWriter Filestream = new StreamWriter(#"C:\Users\MyName\Desktop\output.xml");
Simply remove the "#", OR use single slashes:
This is pretty odd. I have a configuration file which is well formed XML. I create a stream from the file and serialize it using what seems to be pretty typical code:
TextWriter tw = new StreamWriter(tempFile);
I use a serializer created as follows:
XmlSerializer ConfigSettingSerializer = new XmlSerializer(typeof(ConfigSettings));
Where ConfigSettings is just a container class containing string variables and values.
I then take the serialized stream and stash it away as a configuration using the ConfigurationManager class and AppSettings. I then retrieve the serialized data from appSettings and attempt to convert the stream back to the original class:
string configXml = ConfigurationManager.AppSettings[Id];
using (StringReader reader = new StringReader(configXml))
{
retVal = (ConfigSettings)MVHelper.ConfigSettingSerializer.Deserialize(reader);
}
This all works perfectly well until I switch from Debug to Release, when I get an error on the Deserialize call about invalid XML, complaining about the very last character in the document: There is an error in XML document (92, 18). The inner exception is: "Data at the root level is invalid. Line 92, position 18". The document is identical to the one generated in debug mode, and it renders fine in any browser. My guess is that there maybe something else going on and that the real error is somehow being masked, but so far I don't see it. Any advice would be greatly appreciated.
Thanks,
Gary
Load the XML file in a hex editor or other binary editor and check for unprintable characters like an encoding preamble.
I have a problem. I have an XML spreadsheet file that I'm trying to send via email. So I converted into a binary file and attached it to an email. The problem is when I'm trying to open it (on Excel), it's not showing the data that I saved. When I opened it like an XML file I realized that it didn't saved the XML header:
The way it should be:
<?xml version="1.0" encoding="utf-8"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40">
...
<Styles>
...
</Styles>
<Worksheet>
...
</Worksheet></Workbook>
after converting:
<Worksheet>
...
</Worksheet>
I've tried to use an xmldocument but i wasn't working, I also tried using a string, still not working. This is how I convert the XML to binary:
UTF8Encoding encoding = new UTF8Encoding();
binaryFile = encoding.GetBytes(xmlFile);
How can I fix this problem?
Thanks.
I think we need more information on how you're converting the XML file.
From your description it sounds like you've saved an Excel Spreadsheet to XML and for whatever reason you cannot just attach this text document to an email. My guess is you're using a method to attach the XML file that requires a byte array and can't just be provided a file location. If you could provide more information on this, it would help us figure out where things are going wrong for you.
The part I'm really stuck on is:
I've tried to use an xmldocument but i wasn't working, I also tried
using a string, still not working.
How did you try string? Did you read the file from disk using FileStream? If so, you should have been able to retrieve the full contents of the file.
Were you using XmlDocument the whole time and trying XmlDocument.OuterXml? This probably won't give you the control headers since they're not part of the XML body inside the root node.
So really there are two things I would have tried. First, if I had an XML file on disk and needed to attach it to an email through code and my only option was to provide a byte array, I'd do something like:
using (FileStream fs = new FileStream("", FileMode.Open, FileAccess.Read))
{
byte[] binaryFile = new byte[fs.Length];
fs.Read(binaryFile, 0, buff.LongLength);
//Copy the byte array to your email object.
}
Now if this isn't what you're doing, you'll need to provide a lot more detail on what you are starting with (file on disk?), what you need to do (send automated email?), what constraints you have and any other information that would limit potential solutions.
I've found my mistake: I didn't serialized the XML file so that's why after the conversion it just shows the data without the XML header. so there's 2 ways to resolve this problem:
first, we can concatenate the header with the data string, or we can use the serialize function. This is where I've found how to do it.