preliminary implementation of bitmap font editor which can edit Webfoot engine fonts

This commit is contained in:
Michael Becker 2023-06-25 00:22:34 -04:00
parent ca2dbbdac5
commit 4429c66c27
15 changed files with 942 additions and 6 deletions

View File

@ -0,0 +1,379 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.40.0 -->
<interface>
<requires lib="gtk+" version="3.24"/>
<object class="GtkWindow">
<property name="can-focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="margin-start">16</property>
<property name="margin-end">16</property>
<property name="margin-top">16</property>
<property name="margin-bottom">16</property>
<property name="orientation">vertical</property>
<child>
<!-- n-columns=3 n-rows=4 -->
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="row-spacing">8</property>
<property name="column-spacing">8</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Name</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="txtName">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="hexpand">True</property>
<property name="text" translatable="yes">FROGGREN</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Title</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="txtTitle">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="hexpand">True</property>
<property name="text" translatable="yes">Frogger Green Font</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">1</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Size</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
<property name="height">2</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Width</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Height</property>
</object>
<packing>
<property name="left-attach">2</property>
<property name="top-attach">3</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="txtWidth">
<property name="visible">True</property>
<property name="can-focus">True</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">2</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="txtHeight">
<property name="visible">True</property>
<property name="can-focus">True</property>
</object>
<packing>
<property name="left-attach">2</property>
<property name="top-attach">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="margin-top">16</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkEntry" id="txtRenderTest">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="text" translatable="yes">enter some text...</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkDrawingArea" id="canvas">
<property name="name">MBS.Framework.UserInterface.CustomControl</property>
<property name="height-request">96</property>
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkNotebook">
<property name="visible">True</property>
<property name="can-focus">True</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="shadow-type">in</property>
<child>
<object class="GtkTreeView" id="tvImages">
<property name="visible">True</property>
<property name="can-focus">True</property>
<child internal-child="selection">
<object class="GtkTreeSelection"/>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Images</property>
</object>
<packing>
<property name="tab-fill">False</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkToolbar">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkToolButton">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="tooltip-text" translatable="yes">Add</property>
<property name="label" translatable="yes">Add</property>
<property name="use-underline">True</property>
<property name="stock-id">gtk-add</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="tooltip-text" translatable="yes">Edit</property>
<property name="label" translatable="yes">Edit</property>
<property name="use-underline">True</property>
<property name="stock-id">gtk-edit</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="tooltip-text" translatable="yes">Remove</property>
<property name="label" translatable="yes">Remove</property>
<property name="use-underline">True</property>
<property name="stock-id">gtk-remove</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkSeparatorToolItem">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="tooltip-text" translatable="yes">Move Up</property>
<property name="label" translatable="yes">Move Up</property>
<property name="use-underline">True</property>
<property name="stock-id">gtk-go-up</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="tooltip-text" translatable="yes">Move Down</property>
<property name="label" translatable="yes">Move Down</property>
<property name="use-underline">True</property>
<property name="stock-id">gtk-go-down</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="shadow-type">in</property>
<child>
<object class="GtkIconView" id="lv">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="margin">6</property>
<property name="model">lmIcons</property>
<child>
<object class="GtkCellRendererPixbuf"/>
<attributes>
<attribute name="pixbuf">0</attribute>
</attributes>
</child>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Glyphs</property>
</object>
<packing>
<property name="position">1</property>
<property name="tab-fill">False</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
<object class="GtkListStore" id="lmIcons">
<columns>
<!-- column-name colIconTitle -->
<column type="gchararray"/>
<!-- column-name colIconImage -->
<column type="GdkPixbuf"/>
</columns>
</object>
</interface>

View File

@ -389,6 +389,7 @@
<Content Include="Editors\Roland\VDrumKit\TD20\Sounds\Tom\ClscElec.uexml" />
<Content Include="Editors\Roland\VDrumKit\TD20\Sounds\Tom\TR808.uexml" />
<Content Include="Editors\Roland\VDrumKit\TD20\Sounds\Tom\TR909.uexml" />
<Content Include="Editors\Multimedia\Font\Bitmap\BitmapFontEditor.glade" />
</ItemGroup>
<ItemGroup>
<Content Include="Configuration\Application.upl" />

View File

@ -0,0 +1,149 @@
//
// BitmapFontEditor.cs
//
// Author:
// beckermj <>
//
// Copyright (c) 2023 ${CopyrightHolder}
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using MBS.Framework.UserInterface;
using MBS.Framework.UserInterface.Controls;
using MBS.Framework.UserInterface.Controls.ListView;
using UniversalEditor.ObjectModels.Multimedia.Font.Bitmap;
using UniversalEditor.ObjectModels.Multimedia.Picture;
using UniversalEditor.UserInterface;
namespace UniversalEditor.Plugins.Multimedia.UserInterface.Editors.Multimedia.Font.Bitmap
{
[ContainerLayout("~/Editors/Multimedia/Font/Bitmap/BitmapFontEditor.glade")]
public class BitmapFontEditor : Editor
{
private ListViewControl lv;
private TextBox txtTitle;
private NumericTextBox txtWidth;
private NumericTextBox txtHeight;
private CustomControl canvas;
private TextBox txtRenderTest;
private static EditorReference _er = null;
public override EditorReference MakeReference()
{
if (_er == null)
{
_er = base.MakeReference();
_er.SupportedObjectModels.Add(typeof(BitmapFontObjectModel));
}
return _er;
}
protected override void OnObjectModelChanged(EventArgs e)
{
if (IsCreated)
{
lv.Model.Rows.Clear();
base.OnObjectModelChanged(e);
BitmapFontObjectModel font = (ObjectModel as BitmapFontObjectModel);
//txtName.Text = font.Name;
txtTitle.Text = font.Title;
txtWidth.Value = font.Size.Width;
txtHeight.Value = font.Size.Height;
foreach (BitmapFontPixmap pixmap in font.Pixmaps)
{
foreach (BitmapFontGlyph glyph in pixmap.Glyphs)
{
MBS.Framework.UserInterface.Drawing.Image image = null;
if (glyph.Picture != null)
{
image = glyph.Picture.ToImage();
}
else if (pixmap.Picture != null)
{
if (!((int)pixmap.Picture.Width == (int)font.Size.Width && (int)pixmap.Picture.Height == (int)font.Size.Height))
{
// pixmap size does not equal font size - pixmap contains multiple glyphs
PictureObjectModel pic = new PictureObjectModel((int)font.Size.Width, (int)font.Size.Height);
pixmap.Picture.CopyTo(pic, glyph.X, glyph.Y, font.Size.Width, font.Size.Height);
image = pic.ToImage();
}
else
{
// pixmap size equal to font size - pixmap is one per glyph
image = pixmap.Picture.ToImage();
}
}
if (image != null)
{
_glyphs[glyph.Character] = image;
}
TreeModelRow row = new TreeModelRow(new TreeModelRowColumn[]
{
new TreeModelRowColumn(lv.Model.Columns[0], glyph.Character.ToString()),
new TreeModelRowColumn(lv.Model.Columns[1], image)
});
lv.Model.Rows.Add(row);
}
}
}
}
protected override void OnCreated(EventArgs e)
{
base.OnCreated(e);
OnObjectModelChanged(e);
}
[EventHandler(nameof(txtRenderTest), nameof(TextBox.Changed))]
private void txtRenderTest_Changed(object sender, EventArgs e)
{
canvas.Refresh();
}
private System.Collections.Generic.Dictionary<char, MBS.Framework.UserInterface.Drawing.Image> _glyphs = new System.Collections.Generic.Dictionary<char, MBS.Framework.UserInterface.Drawing.Image>();
[EventHandler(nameof(canvas), nameof(Paint))]
private void canvas_Paint(object sender, PaintEventArgs e)
{
e.Graphics.Clear(MBS.Framework.Drawing.Colors.Black);
int x = 16, y = 16;
for (int i = 0; i < txtRenderTest.Text.Length; i++)
{
BitmapFontObjectModel font = (ObjectModel as BitmapFontObjectModel);
if (_glyphs.ContainsKey(txtRenderTest.Text[i]))
{
MBS.Framework.UserInterface.Drawing.Image image = _glyphs[txtRenderTest.Text[i]];
e.Graphics.DrawImage(image, x, y);
}
x += (int)font.Size.Width;
}
}
public override void UpdateSelections()
{
}
protected override Selection CreateSelectionInternal(object content)
{
return null;
}
}
}

View File

@ -63,6 +63,7 @@
<Compile Include="Plugins\Transport\TransportPlugin.cs" />
<Compile Include="Editors\Multimedia\InstrumentDefinition\InstrumentDefinitionEditor.cs" />
<Compile Include="Editors\Multimedia\Audio\Waveform\Dialogs\MultiTrackMappingDialog.cs" />
<Compile Include="Editors\Multimedia\Font\Bitmap\BitmapFontEditor.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="Editors\" />
@ -90,6 +91,8 @@
<Folder Include="Plugins\Transport\" />
<Folder Include="Editors\Multimedia\InstrumentDefinition\" />
<Folder Include="Editors\Multimedia\Audio\Waveform\Dialogs\" />
<Folder Include="Editors\Multimedia\Font\" />
<Folder Include="Editors\Multimedia\Font\Bitmap\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Libraries\UniversalEditor.Core\UniversalEditor.Core.csproj">

View File

@ -3,9 +3,10 @@
<Associations>
<Association>
<Filters>
<Filter Title="ZSoft PC Paintbrush PCX image">
<Filter Title="ZSoft PC Paintbrush PCX image" HintComparison="FilterOnly">
<FileNameFilters>
<FileNameFilter>*.pcx</FileNameFilter>
<FileNameFilter>*.PCX</FileNameFilter>
</FileNameFilters>
</Filter>
</Filters>

View File

@ -0,0 +1,41 @@
//
// BitmapFontGlyph.cs
//
// Author:
// beckermj <>
//
// Copyright (c) 2023 ${CopyrightHolder}
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using UniversalEditor.ObjectModels.Multimedia.Picture;
namespace UniversalEditor.ObjectModels.Multimedia.Font.Bitmap
{
public class BitmapFontGlyph
{
public class BitmapFontGlyphCollection
: System.Collections.ObjectModel.Collection<BitmapFontGlyph>
{
}
public char Character { get; set; }
public double X { get; set; }
public double Y { get; set; }
public BitmapFontPixmap Pixmap { get; set; } = null;
public PictureObjectModel Picture { get; set; }
}
}

View File

@ -0,0 +1,55 @@
//
// BitmapFontObjectModel.cs
//
// Author:
// beckermj <>
//
// Copyright (c) 2023 ${CopyrightHolder}
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using MBS.Framework.Drawing;
namespace UniversalEditor.ObjectModels.Multimedia.Font.Bitmap
{
public class BitmapFontObjectModel : ObjectModel
{
public string Title { get; set; } = null;
public Dimension2D Size { get; set; }
public BitmapFontPixmap.BitmapFontPixmapCollection Pixmaps { get; } = new BitmapFontPixmap.BitmapFontPixmapCollection();
public override void Clear()
{
throw new NotImplementedException();
}
public override void CopyTo(ObjectModel where)
{
throw new NotImplementedException();
}
public BitmapFontGlyph FindGlyph(char c)
{
foreach (BitmapFontPixmap pixmap in Pixmaps)
{
foreach (BitmapFontGlyph glyph in pixmap.Glyphs)
{
if (glyph.Character == c)
return glyph;
}
}
return null;
}
}
}

View File

@ -0,0 +1,38 @@
//
// BitmapFontPixmap.cs
//
// Author:
// beckermj <>
//
// Copyright (c) 2023 ${CopyrightHolder}
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using UniversalEditor.ObjectModels.Multimedia.Picture;
namespace UniversalEditor.ObjectModels.Multimedia.Font.Bitmap
{
public class BitmapFontPixmap
{
public class BitmapFontPixmapCollection
: System.Collections.ObjectModel.Collection<BitmapFontPixmap>
{
}
public string RelativePath { get; set; }
public PictureObjectModel Picture { get; set; } = null;
public BitmapFontGlyph.BitmapFontGlyphCollection Glyphs { get; } = new BitmapFontGlyph.BitmapFontGlyphCollection();
}
}

View File

@ -74,6 +74,32 @@ namespace UniversalEditor.ObjectModels.Multimedia.Picture
return colorMap;
}
public void CopyTo(PictureObjectModel pic, double x, double y, double width, double height)
{
if (pic.Width < width || pic.Height < height)
{
throw new InvalidOperationException();
}
double ix = x, iy = y;
for (double xx = 0; xx < width; xx++)
{
for (double yy = 0; yy < height; yy++)
{
Console.WriteLine("src: ({0}, {1}) dst: ({2}, {3})", x, y, xx, yy);
pic.SetPixel(this.GetPixel((int)x, (int)y), (int)xx, (int)yy);
y++;
}
x++;
y = iy;
if (x == Width)
{
x = 0;
}
}
}
public void SetPixel(Color color)
{
if (lastAddedLocation.X >= mvarWidth && lastAddedLocation.Y >= mvarHeight)
@ -95,6 +121,7 @@ namespace UniversalEditor.ObjectModels.Multimedia.Picture
{
if (x >= mvarWidth || y >= mvarHeight)
{
Console.Error.WriteLine("ue: picture: out of image space @({0}, {1}) ({2}x{3})", x, y, Width, Height);
throw new InvalidOperationException("Out of image space. Try resizing the image");
}
@ -146,10 +173,10 @@ namespace UniversalEditor.ObjectModels.Multimedia.Picture
}
public PictureObjectModel(int width, int height)
{
InitializeBitmapData();
mvarWidth = width;
mvarHeight = height;
InitializeBitmapData();
}
private static void InitializeBitmapData(ref Color[][] array, int width, int height)

View File

@ -387,6 +387,9 @@
<Compile Include="DataFormats\Chunked\ISOMediaBase\ISOMediaBaseChunkLengthPosition.cs" />
<Compile Include="DataFormats\Chunked\ISOMediaBase\ISOMediaBaseChecksumPosition.cs" />
<Compile Include="DataFormats\Chunked\ISOMediaBase\ISOMediaBaseChunkLengthType.cs" />
<Compile Include="ObjectModels\Multimedia\Font\Bitmap\BitmapFontObjectModel.cs" />
<Compile Include="ObjectModels\Multimedia\Font\Bitmap\BitmapFontGlyph.cs" />
<Compile Include="ObjectModels\Multimedia\Font\Bitmap\BitmapFontPixmap.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Libraries\UniversalEditor.Compression\UniversalEditor.Compression.csproj">
@ -457,6 +460,8 @@
<Folder Include="DataFormats\Multimedia\Picture\AVIF\" />
<Folder Include="DataFormats\Chunked\" />
<Folder Include="DataFormats\Chunked\ISOMediaBase\" />
<Folder Include="ObjectModels\Multimedia\Font\" />
<Folder Include="ObjectModels\Multimedia\Font\Bitmap\" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Associations\Playlist\ASX.uexml" />

View File

@ -3,7 +3,7 @@
<Associations>
<Association>
<Filters>
<Filter Title="Webfoot DAT archive">
<Filter Title="Webfoot DAT archive" HintComparison="FilterOnly">
<FileNameFilters>
<FileNameFilter>*.dat</FileNameFilter>
</FileNameFilters>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8" ?>
<UniversalEditor Version="4.0">
<Associations>
<Association>
<Filters>
<Filter Title="Webfoot bitmap font (FNT)" HintComparison="MagicThenFilter">
<FileNameFilters>
<FileNameFilter>*.fnt</FileNameFilter>
</FileNameFilters>
<MagicBytes>
<MagicByte Type="String">[Font Properties]</MagicByte>
</MagicBytes>
</Filter>
</Filters>
<ObjectModels>
<ObjectModel TypeName="UniversalEditor.ObjectModels.Multimedia.Font.Bitmap.BitmapFontObjectModel" />
</ObjectModels>
<DataFormats>
<DataFormat TypeName="UniversalEditor.Plugins.Webfoot.DataFormats.Font.Bitmap.FNTDataFormat" />
</DataFormats>
</Association>
</Associations>
</UniversalEditor>

View File

@ -37,9 +37,9 @@ namespace UniversalEditor.Plugins.Webfoot.DataFormats.FileSystem.Webfoot
{
if (_dfr == null)
{
_dfr = base.MakeReferenceInternal();
_dfr = new DataFormatReference(GetType());
_dfr.Capabilities.Add(typeof(FileSystemObjectModel), DataFormatCapabilities.All);
_dfr.ExportOptions.SettingsGroups[0].Settings.Add(new RangeSetting("Key", "Encryption _key", 0xAA, 0x00, 0xFF));
_dfr.ExportOptions.SettingsGroups[0].Settings.Add(new RangeSetting("Key", "Encryption _key", 0xAA, 0x00, 0xFF));
}
return _dfr;
}

View File

@ -0,0 +1,202 @@
//
// FNTDataFormat.cs
//
// Author:
// beckermj <>
//
// Copyright (c) 2023 ${CopyrightHolder}
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
using UniversalEditor.Accessors;
using UniversalEditor.DataFormats.Multimedia.Picture.ZSoft;
using UniversalEditor.DataFormats.PropertyList;
using UniversalEditor.ObjectModels.Multimedia.Font.Bitmap;
using UniversalEditor.ObjectModels.Multimedia.Picture;
using UniversalEditor.ObjectModels.PropertyList;
namespace UniversalEditor.Plugins.Webfoot.DataFormats.Font.Bitmap
{
public class FNTDataFormat : WindowsConfigurationDataFormat
{
private static DataFormatReference _dfr = null;
protected override DataFormatReference MakeReferenceInternal()
{
if (_dfr == null)
{
_dfr = new DataFormatReference(GetType());
_dfr.Capabilities.Add(typeof(BitmapFontObjectModel), DataFormatCapabilities.All);
}
return _dfr;
}
public FNTDataFormat()
{
PropertyValuePrefix = String.Empty;
PropertyValueSuffix = String.Empty;
}
protected override void BeforeLoadInternal(Stack<ObjectModel> objectModels)
{
base.BeforeLoadInternal(objectModels);
objectModels.Push(new PropertyListObjectModel());
}
protected override void AfterLoadInternal(Stack<ObjectModel> objectModels)
{
base.AfterLoadInternal(objectModels);
string basePath = null;
if (Accessor is FileAccessor)
{
basePath = System.IO.Path.GetDirectoryName(((FileAccessor)Accessor).FileName);
}
PropertyListObjectModel plom = objectModels.Pop() as PropertyListObjectModel;
BitmapFontObjectModel font = objectModels.Pop() as BitmapFontObjectModel;
Group grpFontProperties = plom.Items["Font Properties"] as Group;
if (grpFontProperties != null)
{
font.Title = (grpFontProperties.Items["Name"] as Property).Value?.ToString();
double width =
Double.Parse((grpFontProperties.Items["Width"] as Property).Value?.ToString()),
height =
Double.Parse((grpFontProperties.Items["Height"] as Property).Value?.ToString());
font.Size = new MBS.Framework.Drawing.Dimension2D(width, height);
int filesCount = Int32.Parse((grpFontProperties.Items["NbFiles"] as Property).Value?.ToString());
string paletteFileName = (grpFontProperties.Items["Palette"] as Property).Value?.ToString();
for (int i = 0; i < filesCount; i++)
{
BitmapFontPixmap pixmap = new BitmapFontPixmap();
Group grpFile = plom.Items[String.Format("File{0}", (i + 1).ToString().PadLeft(3, '0'))] as Group;
if (grpFile != null)
{
string fileName = (grpFile.Items["Name"] as Property).Value?.ToString();
pixmap.RelativePath = fileName;
if (basePath != null)
{
string fullyQualifiedFileName = System.IO.Path.Combine(basePath, fileName);
if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX)
{
// try and fix Win32 assumptions on Linux
if (!System.IO.File.Exists(fullyQualifiedFileName))
{
fileName = fileName.ToUpper();
fullyQualifiedFileName = System.IO.Path.Combine(basePath, fileName);
}
if (!System.IO.File.Exists(fullyQualifiedFileName))
{
fileName = fileName.Replace("\\", "/");
fullyQualifiedFileName = System.IO.Path.Combine(basePath, fileName);
}
}
if (System.IO.File.Exists(fullyQualifiedFileName))
{
PictureObjectModel pic = new PictureObjectModel();
FileAccessor fa = new FileAccessor(fullyQualifiedFileName);
Association[] assocs = Association.FromCriteria(new AssociationCriteria() { Accessor = fa, ObjectModel = pic.MakeReference(), FileName = fa.FileName });
Document.Load(pic, new PCXDataFormat(), fa);
pixmap.Picture = pic;
}
}
int type = Int32.Parse((grpFile.Items["Type"] as Property).Value?.ToString());
int nbLines = Int32.Parse((grpFile.Items["NbLines"] as Property).Value?.ToString());
for (int j = 0; j < nbLines; j++)
{
string lineXXX = (grpFile.Items[String.Format("Line{0}", (j + 1).ToString().PadLeft(3, '0'))] as Property).Value?.ToString();
for (int k = 0; k < lineXXX.Length; k++)
{
BitmapFontGlyph glyph = new BitmapFontGlyph();
glyph.X = k * font.Size.Width;
glyph.Y = j * font.Size.Height;
glyph.Pixmap = pixmap;
glyph.Character = lineXXX[k];
pixmap.Glyphs.Add(glyph);
}
}
font.Pixmaps.Add(pixmap);
}
}
}
}
protected override void BeforeSaveInternal(Stack<ObjectModel> objectModels)
{
base.BeforeSaveInternal(objectModels);
BitmapFontObjectModel font = objectModels.Pop() as BitmapFontObjectModel;
PropertyListObjectModel plom = new PropertyListObjectModel();
Group grpFontProperties = new Group("Font Properties");
grpFontProperties.Items.AddProperty("Name", font.Title);
grpFontProperties.Items.AddProperty("Width", font.Size.Width);
grpFontProperties.Items.AddProperty("Height", font.Size.Height);
grpFontProperties.Items.AddProperty("NbFiles", font.Pixmaps.Count);
grpFontProperties.Items.AddProperty("Palette", font.Pixmaps[0].RelativePath);
plom.Items.Add(grpFontProperties);
Group grpCharacterProperties = new Group("Character Properties");
grpCharacterProperties.Items.AddProperty("MapSrc", "abcdefghijklmnopqrstuvwxyz\u0083\u0084\u0085\u0086\u00a0\u0082\u0088\u0089\u008a\u008b\u008c\u008d¡\u0093\u0094\u0095¢\u0081\u0096\u0097£\u0098\u0087¤\u008e\u008f\u0080\u0090¥\u0099¨­");
grpCharacterProperties.Items.AddProperty("MapDst", "ABCDEFGHIJKLMNOPQRSTUVWXYZaaaaaeeeeiiiioooouuuuycnAACENO?!");
plom.Items.Add(grpCharacterProperties);
for (int i = 0; i < font.Pixmaps.Count; i++)
{
BitmapFontPixmap pixmap = font.Pixmaps[i];
Group grpFile = new Group(String.Format("File{0}", (i + 1).ToString().PadLeft(3, '0')));
grpFile.Items.AddProperty("Name", font.Pixmaps[i].RelativePath);
grpFile.Items.AddProperty("Type", 1);
if (font.Pixmaps[i].Picture == null)
{
}
double picwidth = font.Pixmaps[i].Picture.Size.Width;
int nbLines = (int)Math.Round((font.Pixmaps[i].Glyphs.Count * font.Size.Width) / picwidth);
grpFile.Items.AddProperty("NbLines", font.Pixmaps[i].Glyphs.Count);
double x = 0;
int k = 0;
System.Text.StringBuilder sb = new System.Text.StringBuilder();
for (int j = 0; j < font.Pixmaps[i].Glyphs.Count; j++)
{
sb.Append(font.Pixmaps[i].Glyphs[j].Character);
x += font.Size.Width;
if (x >= picwidth)
{
grpFile.Items.AddProperty(String.Format("Line{0}", (k + 1).ToString().PadLeft(3, '0')), sb.ToString());
x = 0;
sb.Clear();
k++;
}
}
plom.Items.Add(grpFile);
}
objectModels.Push(plom);
}
}
}

View File

@ -33,12 +33,15 @@
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="DataFormats\FileSystem\Webfoot\DATDataFormat.cs" />
<Compile Include="DataFormats\Font\Bitmap\FNTDataFormat.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="DataFormats\" />
<Folder Include="DataFormats\FileSystem\" />
<Folder Include="DataFormats\FileSystem\Webfoot\" />
<Folder Include="Associations\" />
<Folder Include="DataFormats\Font\" />
<Folder Include="DataFormats\Font\Bitmap\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Libraries\UniversalEditor.Core\UniversalEditor.Core.csproj">
@ -57,9 +60,18 @@
<Project>{00266B21-35C9-4A7F-A6BA-D54D7FDCC25C}</Project>
<Name>MBS.Framework</Name>
</ProjectReference>
<ProjectReference Include="..\UniversalEditor.Plugins.Multimedia\UniversalEditor.Plugins.Multimedia.csproj">
<Project>{BE4D0BA3-0888-42A5-9C09-FC308A4509D2}</Project>
<Name>UniversalEditor.Plugins.Multimedia</Name>
</ProjectReference>
<ProjectReference Include="..\..\Libraries\UniversalEditor.Compression\UniversalEditor.Compression.csproj">
<Project>{3F664673-7E22-4486-9AD0-FC81861D0B78}</Project>
<Name>UniversalEditor.Compression</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Associations\DAT.uexml" />
<EmbeddedResource Include="Associations\FNT.uexml" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>