using FastReport.Utils;
using System;
using System.Collections;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using FastReport.Export.TTF;
namespace FastReport.Export.OoXML
{
///
/// Font container
///
internal class XPS_Font : OoXMLBase, IDisposable
{
#region DLL import
[DllImport("Gdi32.dll")]
private static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
[DllImport("Gdi32.dll")]
private static extern IntPtr DeleteObject(IntPtr hgdiobj);
[DllImport("Gdi32.dll", CharSet = CharSet.Auto)]
private static extern uint GetFontData(IntPtr hdc, uint dwTable, uint dwOffset, [In, Out] byte[] lpvBuffer, uint cbData);
[DllImport("Gdi32.dll", CharSet = CharSet.Auto)]
private static extern uint GetFontData(IntPtr hdc, uint dwTable, uint dwOffset, [In, Out] IntPtr lpvBuffer, uint cbData);
#endregion
#region "Class overrides"
public override string RelationType { get { return "http://schemas.microsoft.com/xps/2005/06/required-resource"; } }
public override string ContentType { get { return null; } } //"application/vnd.openxmlformats-officedocument.presentationml.slide+xml"; } }
public override string FileName { get { return "/Resources/" + generatedName + ".odttf"; } }
// public override string FileName { get { return "/Resources/" + GeneratedName + ".ttf"; } }
#endregion
private Hashtable listOfUsedGlyphs;
private FontFamily fontFamily;
private ExportTTFFont export_font;
internal float size;
internal FontStyle style;
internal float height;
public Guid fontGuid;
public string generatedName;
internal Font SourceFont
{
set
{
fontFamily = value.FontFamily;
size = value.Size;
style = value.Style;
height = value.Height;
}
}
///
/// Font obfuscation procedure
///
internal void Obfuscation(byte[] data)
{
if (data.Length < 32) throw new Exception("Font header error");
byte[] guidByteArray = new byte[16];
string guidString = fontGuid.ToString("N");
for (int i = 0; i < guidByteArray.Length; i++)
{
guidByteArray[i] = Convert.ToByte(guidString.Substring(i * 2, 2), 16);
}
for (int j = 0; j < 2; j++)
{
for (int i = 0; i < 16; i++)
{
data[i + j * 16] ^= guidByteArray[15 - i];
}
}
}
public byte[] ExportFont(XPSExport export)
{
float FDpiFX = 96f / DrawUtils.ScreenDpi;
byte[] result = null;
using (Font current_font = new Font(this.fontFamily, this.size * FDpiFX, this.style))
{
try
{
result = export_font.GetFontData(true);
Obfuscation(result);
MemoryStream file = new MemoryStream();
file.Write(result, 0, result.Length);
file.Position = 0;
export.Zip.AddStream(ExportUtils.TruncLeadSlash(this.FileName), file);
}
finally
{
}
}
return result;
}
public XPS_Font(Font f)
{
int i, j;
this.fontFamily = f.FontFamily;
this.size = f.Size;
this.style = f.Style;
fontGuid = SystemFake.Guid.NewGuid();
export_font = new ExportTTFFont(f);
listOfUsedGlyphs = new Hashtable();
string Name = fontGuid.ToString("N");
generatedName = "";
for (i = 0; i < 8; i++) generatedName += Name[i];
generatedName += '-';
for (j = 0; j < 4; j++, i++) generatedName += Name[i];
generatedName += '-';
for (j = 0; j < 4; j++, i++) generatedName += Name[i];
generatedName += '-';
for (j = 0; j < 4; j++, i++) generatedName += Name[i];
generatedName += '-';
for (j = 0; j < 12; j++, i++) generatedName += Name[i];
}
// cut off --- Samuray
internal string AddString(string str, bool rtl)
{
StringBuilder sb = new StringBuilder();
foreach (var run in export_font.GetFontRuns(str, rtl))
{
if (run.Font == export_font.SourceFont)
{
export_font.AddUsedGlyphs(run);
foreach (ushort c in run.Glyphs)
AddGlyph(c);
for (int i = 0; i < run.Glyphs.Length; i++)
{
sb.Append((char)run.Glyphs[i]);
}
}
}
return sb.ToString();
}
// end cut off
private void AddGlyph(ushort symbol)
{
if (!listOfUsedGlyphs.ContainsKey(symbol))
{
int id = listOfUsedGlyphs.Count;
listOfUsedGlyphs.Add(symbol, id);
}
}
internal string GetXpsIndexes(string text)
{
int i;
StringBuilder indices = new StringBuilder(text.Length * 4);
indices.Append("Indices=\"");
//float WIDTH_DIVIDER = 10;
for (i = 0; i < text.Length; i++)
{
indices.Append(((int)text[i]).ToString()).
//Append(',').
//Append(Converter.ToString(export_font.GetGlyphWidth(text[i]) / WIDTH_DIVIDER)).
Append(';');
}
indices.Remove(indices.Length - 1, 1);
indices.Append("\" ");
return indices.ToString();
}
#region IDisposable Members
public void Dispose()
{
export_font.Dispose();
}
#endregion
}
}