2019-07-17 20:14:55 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
using System.Data;
|
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
using Toolbox.Library.Forms;
|
2019-07-18 17:33:16 +00:00
|
|
|
|
using Toolbox.Library;
|
2019-07-17 20:14:55 +00:00
|
|
|
|
|
|
|
|
|
namespace FirstPlugin.Forms
|
|
|
|
|
{
|
2019-07-18 17:33:16 +00:00
|
|
|
|
public class ImagePaenl : STPanel
|
|
|
|
|
{
|
|
|
|
|
public ImagePaenl()
|
|
|
|
|
{
|
|
|
|
|
this.SetStyle(
|
|
|
|
|
ControlStyles.AllPaintingInWmPaint |
|
|
|
|
|
ControlStyles.UserPaint |
|
|
|
|
|
ControlStyles.DoubleBuffer,
|
|
|
|
|
true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public partial class BffntEditor : STUserControl, IFIleEditor
|
2019-07-17 20:14:55 +00:00
|
|
|
|
{
|
|
|
|
|
public BffntEditor()
|
|
|
|
|
{
|
|
|
|
|
InitializeComponent();
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-18 17:33:16 +00:00
|
|
|
|
public List<IFileFormat> GetFileFormats()
|
|
|
|
|
{
|
|
|
|
|
return new List<IFileFormat>() { FileFormat };
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-18 02:02:57 +00:00
|
|
|
|
private Image PanelImage { get; set; }
|
|
|
|
|
|
2019-07-17 20:14:55 +00:00
|
|
|
|
private FFNT ActiveFile;
|
2019-07-18 17:33:16 +00:00
|
|
|
|
private BFFNT FileFormat;
|
|
|
|
|
|
2019-07-17 20:14:55 +00:00
|
|
|
|
public void LoadFontFile(BFFNT fontFile)
|
|
|
|
|
{
|
2019-07-18 17:33:16 +00:00
|
|
|
|
FileFormat = fontFile;
|
2019-07-17 20:14:55 +00:00
|
|
|
|
ActiveFile = fontFile.bffnt;
|
|
|
|
|
|
|
|
|
|
fontTypeCB.Bind(typeof(FINF.FontType), ActiveFile.FontSection, "Type");
|
|
|
|
|
fontTypeCB.SelectedItem = ActiveFile.FontSection.Type;
|
|
|
|
|
|
|
|
|
|
encodingTypeCB.Bind(typeof(FINF.CharacterCode), ActiveFile.FontSection, "CharEncoding");
|
|
|
|
|
encodingTypeCB.SelectedItem = ActiveFile.FontSection.CharEncoding;
|
|
|
|
|
|
|
|
|
|
lineFeedUD.Bind(ActiveFile.FontSection, "LineFeed");
|
|
|
|
|
leftSpacingUD.Bind(ActiveFile.FontSection, "DefaultLeftWidth");
|
|
|
|
|
charWidthUD.Bind(ActiveFile.FontSection, "DefaultCharWidth");
|
|
|
|
|
glyphWidthCB.Bind(ActiveFile.FontSection, "DefaultGlyphWidth");
|
|
|
|
|
ascentUD.Bind(ActiveFile.FontSection, "Ascent");
|
|
|
|
|
fontWidthUD.Bind(ActiveFile.FontSection, "Width");
|
|
|
|
|
fontHeightUD.Bind(ActiveFile.FontSection, "Height");
|
|
|
|
|
|
2019-07-18 02:02:57 +00:00
|
|
|
|
ReloadCharacterCodes();
|
2019-07-17 20:14:55 +00:00
|
|
|
|
ReloadTextures();
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-18 02:02:57 +00:00
|
|
|
|
private void ReloadCharacterCodes()
|
|
|
|
|
{
|
|
|
|
|
foreach (char entry in ActiveFile.FontSection.CodeMapDictionary.Keys)
|
|
|
|
|
characterCodeCB.Items.Add(entry);
|
|
|
|
|
|
|
|
|
|
if (ActiveFile.FontSection.CodeMapDictionary.Count > 0)
|
|
|
|
|
characterCodeCB.SelectedIndex = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-17 20:14:55 +00:00
|
|
|
|
private void ReloadTextures()
|
|
|
|
|
{
|
|
|
|
|
imagesCB.Items.Clear();
|
|
|
|
|
var textureGlyph = ActiveFile.FontSection.TextureGlyph;
|
|
|
|
|
for (int i = 0; i < textureGlyph.SheetCount; i++)
|
|
|
|
|
imagesCB.Items.Add($"Image {i}");
|
|
|
|
|
|
|
|
|
|
if (textureGlyph.SheetCount > 0)
|
|
|
|
|
imagesCB.SelectedIndex = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-18 18:31:27 +00:00
|
|
|
|
private void imagePanel_MouseClick(object sender, MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (ActiveFile == null) return;
|
|
|
|
|
|
|
|
|
|
int ImageIndex = imagesCB.SelectedIndex;
|
|
|
|
|
if (e.Button == MouseButtons.Right && ImageIndex != -1)
|
|
|
|
|
{
|
|
|
|
|
var image = ActiveFile.FontSection.TextureGlyph.GetImageSheet(ImageIndex);
|
|
|
|
|
|
|
|
|
|
if (image is IContextMenuNode)
|
|
|
|
|
{
|
|
|
|
|
imageMenuStrip.Items.Clear();
|
|
|
|
|
imageMenuStrip.Items.AddRange(((IContextMenuNode)image).GetContextMenuItems());
|
|
|
|
|
imageMenuStrip.Show(Cursor.Position);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-17 20:14:55 +00:00
|
|
|
|
private void imagesCB_SelectedIndexChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
int ImageIndex = imagesCB.SelectedIndex;
|
|
|
|
|
if (ImageIndex != -1)
|
|
|
|
|
{
|
|
|
|
|
var image = ActiveFile.FontSection.TextureGlyph.GetImageSheet(ImageIndex);
|
|
|
|
|
bool IsBntx = ActiveFile.FontSection.TextureGlyph.BinaryTextureFile != null;
|
|
|
|
|
|
|
|
|
|
if (IsBntx)
|
|
|
|
|
{
|
2019-07-18 02:02:57 +00:00
|
|
|
|
PanelImage = image.GetBitmap(ImageIndex);
|
2019-07-17 20:14:55 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2019-07-18 02:02:57 +00:00
|
|
|
|
PanelImage = image.GetBitmap();
|
2019-07-17 20:14:55 +00:00
|
|
|
|
}
|
2019-07-18 17:33:16 +00:00
|
|
|
|
|
|
|
|
|
if (PanelImage != null)
|
|
|
|
|
{
|
|
|
|
|
PanelImage.RotateFlip(RotateFlipType.RotateNoneFlipY);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FillCells();
|
2019-07-17 20:14:55 +00:00
|
|
|
|
}
|
2019-07-18 17:33:16 +00:00
|
|
|
|
|
|
|
|
|
imagePanel.Refresh();
|
2019-07-17 20:14:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-07-18 02:02:57 +00:00
|
|
|
|
private void pictureBox1_Paint(object sender, PaintEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Rectangle ee = new Rectangle(10, 10, 30, 30);
|
|
|
|
|
using (Pen pen = new Pen(Color.Red, 2))
|
|
|
|
|
{
|
|
|
|
|
e.Graphics.DrawRectangle(pen, ee);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-17 20:14:55 +00:00
|
|
|
|
private void exportToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
int ImageIndex = imagesCB.SelectedIndex;
|
|
|
|
|
if (ImageIndex != -1)
|
|
|
|
|
{
|
|
|
|
|
var image = ActiveFile.FontSection.TextureGlyph.GetImageSheet(ImageIndex);
|
|
|
|
|
bool IsBntx = ActiveFile.FontSection.TextureGlyph.BinaryTextureFile != null;
|
|
|
|
|
|
2019-07-18 17:33:16 +00:00
|
|
|
|
var args = new STGenericTexture.ImageExportArguments()
|
|
|
|
|
{
|
|
|
|
|
FlipY = true,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (IsBntx)
|
|
|
|
|
image.ExportArrayImage(ImageIndex, args);
|
2019-07-17 20:14:55 +00:00
|
|
|
|
else
|
2019-07-18 17:33:16 +00:00
|
|
|
|
image.ExportImage(args);
|
2019-07-17 20:14:55 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-18 02:02:57 +00:00
|
|
|
|
public class FontCell
|
|
|
|
|
{
|
|
|
|
|
public Rectangle DrawnRectangle;
|
|
|
|
|
|
|
|
|
|
public Color Color { get; set; }
|
|
|
|
|
|
|
|
|
|
public FontCell()
|
|
|
|
|
{
|
|
|
|
|
Color = Color.Cyan;
|
|
|
|
|
}
|
2019-07-18 17:33:16 +00:00
|
|
|
|
|
|
|
|
|
public bool IsHit(int X, int Y)
|
|
|
|
|
{
|
|
|
|
|
if (DrawnRectangle == null) return false;
|
|
|
|
|
|
|
|
|
|
if ((X > DrawnRectangle.X) && (X < DrawnRectangle.X + DrawnRectangle.Width) &&
|
|
|
|
|
(Y > DrawnRectangle.Y) && (Y < DrawnRectangle.Y + DrawnRectangle.Height))
|
|
|
|
|
return true;
|
|
|
|
|
else
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool IsSelected { get; private set; }
|
|
|
|
|
|
|
|
|
|
public void Select()
|
|
|
|
|
{
|
|
|
|
|
Color = Color.Blue;
|
|
|
|
|
IsSelected = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Unselect()
|
|
|
|
|
{
|
|
|
|
|
Color = Color.Cyan;
|
|
|
|
|
IsSelected = false;
|
|
|
|
|
}
|
2019-07-18 02:02:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private FontCell[] FontCells;
|
|
|
|
|
|
2019-07-18 17:33:16 +00:00
|
|
|
|
private void LoadGlyphs()
|
|
|
|
|
{
|
|
|
|
|
var textureGlyph = ActiveFile.FontSection.TextureGlyph;
|
|
|
|
|
|
|
|
|
|
for (int c = 0; c < (int)textureGlyph.ColumnCount; c++)
|
|
|
|
|
{
|
|
|
|
|
for (int r = 0; r < (int)textureGlyph.RowCount; r++)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public GlyphImage[] GlyphImages;
|
|
|
|
|
|
|
|
|
|
public class GlyphImage
|
|
|
|
|
{
|
|
|
|
|
public Image Image { get; set; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void FillCells()
|
|
|
|
|
{
|
|
|
|
|
List<GlyphImage> images = new List<GlyphImage>();
|
|
|
|
|
List<FontCell> Cells = new List<FontCell>();
|
|
|
|
|
|
|
|
|
|
var textureGlyph = ActiveFile.FontSection.TextureGlyph;
|
|
|
|
|
var fontSection = ActiveFile.FontSection;
|
|
|
|
|
|
|
|
|
|
PanelImage = BitmapExtension.Resize(PanelImage, textureGlyph.SheetWidth, textureGlyph.SheetHeight);
|
|
|
|
|
|
|
|
|
|
Console.WriteLine($"ColumnCount {textureGlyph.ColumnCount}");
|
|
|
|
|
Console.WriteLine($"RowCount {textureGlyph.RowCount}");
|
|
|
|
|
|
|
|
|
|
int y = 0;
|
|
|
|
|
for (int c = 0; c < (int)textureGlyph.RowCount; c++)
|
|
|
|
|
{
|
|
|
|
|
int x = 0;
|
|
|
|
|
for (int r = 0; r < (int)textureGlyph.ColumnCount; r++)
|
|
|
|
|
{
|
|
|
|
|
var rect = new Rectangle(x, y, textureGlyph.CellWidth, textureGlyph.CellHeight);
|
|
|
|
|
|
|
|
|
|
Cells.Add(new FontCell()
|
|
|
|
|
{
|
|
|
|
|
DrawnRectangle = rect,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
/* var glyphImage = new GlyphImage();
|
|
|
|
|
glyphImage.Image = CopyRegionIntoImage(bitmap, rect);
|
|
|
|
|
glyphImage.Image.Save($"Glpyh{c} {r}.png");
|
|
|
|
|
images.Add(glyphImage);*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
x += (int)textureGlyph.CellWidth;
|
|
|
|
|
}
|
|
|
|
|
y += (int)textureGlyph.CellHeight;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GlyphImages = images.ToArray();
|
|
|
|
|
FontCells = Cells.ToArray();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static Bitmap CopyRegionIntoImage(Image srcBitmap, Rectangle srcRegion)
|
|
|
|
|
{
|
|
|
|
|
Bitmap destBitmap = new Bitmap(srcRegion.Width, srcRegion.Height);
|
|
|
|
|
using (Graphics grD = Graphics.FromImage(destBitmap))
|
|
|
|
|
{
|
|
|
|
|
grD.DrawImage(srcBitmap, new Rectangle(0,0,destBitmap.Width, destBitmap.Height), srcRegion, GraphicsUnit.Pixel);
|
|
|
|
|
}
|
|
|
|
|
return destBitmap;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-18 02:02:57 +00:00
|
|
|
|
private void imagePanel_Paint(object sender, PaintEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Graphics graphics = e.Graphics;
|
|
|
|
|
graphics.DrawImage(PanelImage, 0.0f, 0.0f);
|
|
|
|
|
|
|
|
|
|
if (ActiveFile == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
var textureGlyph = ActiveFile.FontSection.TextureGlyph;
|
|
|
|
|
|
2019-07-18 17:33:16 +00:00
|
|
|
|
if (FontCells == null)
|
|
|
|
|
return;
|
2019-07-18 02:02:57 +00:00
|
|
|
|
|
2019-07-18 17:33:16 +00:00
|
|
|
|
for (int i = 0; i < FontCells.Length; i++) {
|
|
|
|
|
if (FontCells[i].IsSelected)
|
2019-07-18 02:02:57 +00:00
|
|
|
|
{
|
2019-07-18 17:33:16 +00:00
|
|
|
|
SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(70, 0, 255, 255));
|
2019-07-18 02:02:57 +00:00
|
|
|
|
|
2019-07-18 17:33:16 +00:00
|
|
|
|
graphics.DrawRectangle(new Pen(FontCells[i].Color, 1), FontCells[i].DrawnRectangle);
|
|
|
|
|
graphics.FillRectangle(semiTransBrush, FontCells[i].DrawnRectangle);
|
2019-07-18 02:02:57 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2019-07-18 17:33:16 +00:00
|
|
|
|
|
|
|
|
|
graphics.ScaleTransform(textureGlyph.SheetWidth, textureGlyph.SheetHeight);
|
2019-07-18 02:02:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-07-17 20:14:55 +00:00
|
|
|
|
private void copyToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
2019-07-18 02:02:57 +00:00
|
|
|
|
if (PanelImage != null)
|
|
|
|
|
Clipboard.SetImage(PanelImage);
|
2019-07-17 20:14:55 +00:00
|
|
|
|
}
|
2019-07-18 17:33:16 +00:00
|
|
|
|
|
|
|
|
|
bool isMouseDown = false;
|
|
|
|
|
private void imagePanel_MouseDown(object sender, MouseEventArgs e) {
|
|
|
|
|
isMouseDown = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void imagePanel_MouseUp(object sender, MouseEventArgs e) {
|
|
|
|
|
isMouseDown = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void imagePanel_MouseMove(object sender, MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (FontCells != null)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < FontCells.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
if (FontCells[i] == null) continue;
|
|
|
|
|
|
|
|
|
|
if (FontCells[i].IsHit(e.X, e.Y))
|
|
|
|
|
FontCells[i].Select();
|
|
|
|
|
else
|
|
|
|
|
FontCells[i].Unselect();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
imagePanel.Refresh();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void imagePanel_MouseLeave(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
isMouseDown = false;
|
|
|
|
|
|
|
|
|
|
if (FontCells != null)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < FontCells.Length; i++)
|
|
|
|
|
FontCells[i].Unselect();
|
|
|
|
|
|
|
|
|
|
imagePanel.Refresh();
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-07-17 20:14:55 +00:00
|
|
|
|
}
|
|
|
|
|
}
|