/* csf12png.cpp */
/* Programed by AZO */
/* This code is free. At Your Own Risk. */

/* This program uses wxWidget >3.0.0 */
/* build: g++ `wx-config --cppflags` csf12png.cpp csf1.c `wx-config --libs` -o csf12png */

#include "csf1.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <wx/wx.h>
#include <wx/image.h>
#include <wx/graphics.h>

CSF1_GlyphsData_t g_tCSF1GlyphsData;

typedef struct C2L_Vector {
	signed int FromX;
	signed int FromY;
	signed int ToX;
	signed int ToY;
} C2L_Vector_t;

typedef struct C2L_Glyph {
	unsigned int Code;
	unsigned int VectorsCount;
	C2L_Vector_t Vectors[155];
} C2L_Glyph_t;

typedef struct C2L_GlyphData {
	unsigned int GlyphsCount;
	C2L_Glyph_t Glyphs[10000];
} C2L_GlyphsData_t;

C2L_GlyphsData_t g_tGlyphsData;

void CSF1ToVector(C2L_GlyphsData_t* o_ptGlyphsData, CSF1_GlyphsData_t* i_ptCSF1GlyphsData) {
	signed int iFromX, iFromY, iToX;
	CSF1_Glyph_t* ptCSF1Glyph;
	C2L_Glyph_t* ptGlyph;
	CSF1_Item_t* ptCSF1Item;
	unsigned int uiVectorCount;
	unsigned int uiCount1, uiCount2;

	memset(&g_tGlyphsData, 0, sizeof(C2L_GlyphsData_t));

	for(uiCount1 = 0; uiCount1 < i_ptCSF1GlyphsData->GlyphsCount; uiCount1++) {
		ptCSF1Glyph = &(i_ptCSF1GlyphsData->Glyphs[uiCount1]);
		ptGlyph = &(o_ptGlyphsData->Glyphs[uiCount1]);

		ptGlyph->Code = ptCSF1Glyph->JIS;

		uiVectorCount = 0;
		iFromX = 0;
		iFromY = 0;
		iToX = 0;

		for(uiCount2 = 0; uiCount2 < ptCSF1Glyph->ItemCount; uiCount2++) {
			ptCSF1Item = &(ptCSF1Glyph->Items[uiCount2]);

			switch(ptCSF1Item->Action) {
				case CSF1_INIT:
				case CSF1_TERM:
					break;
				case CSF1_MOVE_X:
					iFromX = (signed int)(ptCSF1Item->Val);
					iToX = iFromX;
					break;
				case CSF1_DRAW_X:
					ptGlyph->Vectors[uiVectorCount].FromX = iFromX;
					ptGlyph->Vectors[uiVectorCount].FromY = iFromY;
					ptGlyph->Vectors[uiVectorCount].ToX = (signed int)(ptCSF1Item->Val);
					ptGlyph->Vectors[uiVectorCount].ToY = iFromY;
					uiVectorCount++;
					iFromX = (signed int)(ptCSF1Item->Val);
					iToX = iFromX;
					break;
				case CSF1_NEXT_X:
					iToX = (signed int)(ptCSF1Item->Val);
					break;
				case CSF1_MOVE_Y:
					iFromY = (signed int)(ptCSF1Item->Val);
					break;
				case CSF1_DRAW_Y:
					ptGlyph->Vectors[uiVectorCount].FromX = iFromX;
					ptGlyph->Vectors[uiVectorCount].FromY = iFromY;
					ptGlyph->Vectors[uiVectorCount].ToX = iToX;
					ptGlyph->Vectors[uiVectorCount].ToY = (signed int)(ptCSF1Item->Val);
					uiVectorCount++;
					iFromX = iToX;
					iFromY = (signed int)(ptCSF1Item->Val);
					break;
			}
		}
		ptGlyph->VectorsCount = uiVectorCount;
	}
	o_ptGlyphsData->GlyphsCount = i_ptCSF1GlyphsData->GlyphsCount;
}

void OutputPicture(C2L_GlyphsData_t* i_ptGlyphsData) {
	unsigned int uiBaseX;
	unsigned int uiBaseY;
	unsigned int uiBaseCode;
	unsigned int uiGlyphsLocate;
	unsigned int uiItem;
	unsigned int uiCode;
	C2L_Glyph_t* ptGlyph;
	char tempstr[16];

	wxPNGHandler *handler = new wxPNGHandler;
	wxImage::AddHandler(handler);
	wxFont font(wxFontInfo(20).FaceName("Helvetica"));
	wxColour colour(255, 255, 255);

	wxImage oImage(2212, 537, false);
	wxGraphicsContext *pGC = wxGraphicsContext::Create(oImage);
	if(pGC) {
		pGC->SetPen( *wxWHITE_PEN );
		pGC->SetFont(font, colour);
		pGC->SetBrush( *wxBLACK_BRUSH );
		pGC->DrawRectangle(0, 0, 2212, 537);

		uiBaseY = 0;
		for(uiBaseCode = 0x0000; uiBaseCode <= 0x00FF; uiBaseCode += 0x20) {
			sprintf(tempstr, "%04X", uiBaseCode);
			pGC->DrawText(tempstr, 2, uiBaseY + 10);

			wxGraphicsPath path = pGC->CreatePath();

			uiBaseX = 67;
			path.MoveToPoint(uiBaseX, uiBaseY);
			path.AddLineToPoint(2212, uiBaseY);
			path.MoveToPoint(uiBaseX, uiBaseY + 67);
			path.AddLineToPoint(2212, uiBaseY + 67);

			for(uiCode = uiBaseCode; uiCode < uiBaseCode + 0x20; uiCode++) {
				path.MoveToPoint(uiBaseX, uiBaseY);
				path.AddLineToPoint(uiBaseX, uiBaseY + 67);
				path.MoveToPoint(uiBaseX + 67, uiBaseY);
				path.AddLineToPoint(uiBaseX + 67, uiBaseY + 67);

				for(uiGlyphsLocate = 0; uiGlyphsLocate < i_ptGlyphsData->GlyphsCount; uiGlyphsLocate++) {
					ptGlyph = &(i_ptGlyphsData->Glyphs[uiGlyphsLocate]);
					if(ptGlyph->Code == uiCode) {
						for(uiItem = 0; uiItem < ptGlyph->VectorsCount; uiItem++) {
							path.MoveToPoint(uiBaseX + ptGlyph->Vectors[uiItem].FromX * 2 + 4, uiBaseY + 64 - (ptGlyph->Vectors[uiItem].FromY * 2 - 2));
							path.AddLineToPoint(uiBaseX + ptGlyph->Vectors[uiItem].ToX * 2 + 4, uiBaseY + 64 - (ptGlyph->Vectors[uiItem].ToY * 2 - 2));
						}
					}
				}
				uiBaseX += 67;
			}

			pGC->StrokePath(path);
			uiBaseY += 67;
		}
		delete pGC;
	}
	oImage.SaveFile("kst32b_ascii.png", wxBITMAP_TYPE_PNG);

	wxImage oImage1(2212, 202, false);
	pGC = wxGraphicsContext::Create(oImage1);
	if(pGC) {
		pGC->SetPen( *wxWHITE_PEN );
		pGC->SetFont(font, colour);
		pGC->SetBrush( *wxBLACK_BRUSH );
		pGC->DrawRectangle(0, 0, 2212, 202);

		uiBaseY = 0;
		for(uiBaseCode = 0x1A20; uiBaseCode <= 0x1A6F; uiBaseCode += 0x20) {
			sprintf(tempstr, "%04X", uiBaseCode);
			pGC->DrawText(tempstr, 2, uiBaseY + 10);

			wxGraphicsPath path = pGC->CreatePath();

			uiBaseX = 67;
			path.MoveToPoint(uiBaseX, uiBaseY);
			path.AddLineToPoint(2212, uiBaseY);
			path.MoveToPoint(uiBaseX, uiBaseY + 67);
			path.AddLineToPoint(2212, uiBaseY + 67);

			for(uiCode = uiBaseCode; uiCode < uiBaseCode + 0x20; uiCode++) {
				path.MoveToPoint(uiBaseX, uiBaseY);
				path.AddLineToPoint(uiBaseX, uiBaseY + 67);
				path.MoveToPoint(uiBaseX + 67, uiBaseY);
				path.AddLineToPoint(uiBaseX + 67, uiBaseY + 67);

				for(uiGlyphsLocate = 0; uiGlyphsLocate < i_ptGlyphsData->GlyphsCount; uiGlyphsLocate++) {
					ptGlyph = &(i_ptGlyphsData->Glyphs[uiGlyphsLocate]);
					if(ptGlyph->Code == uiCode) {
						for(uiItem = 0; uiItem < ptGlyph->VectorsCount; uiItem++) {
							path.MoveToPoint(uiBaseX + ptGlyph->Vectors[uiItem].FromX * 2 + 4, uiBaseY + 64 - (ptGlyph->Vectors[uiItem].FromY * 2 - 2));
							path.AddLineToPoint(uiBaseX + ptGlyph->Vectors[uiItem].ToX * 2 + 4, uiBaseY + 64 - (ptGlyph->Vectors[uiItem].ToY * 2 - 2));
						}
					}
				}
				uiBaseX += 67;
			}

			pGC->StrokePath(path);
			uiBaseY += 67;
		}
		delete pGC;
	}
	oImage1.SaveFile("kst32b_1A20.png", wxBITMAP_TYPE_PNG);

	wxImage oImage2(2212, 7974, false);
	pGC = wxGraphicsContext::Create(oImage2);
	if(pGC) {
		pGC->SetPen( *wxWHITE_PEN );
		pGC->SetFont(font, colour);
		pGC->SetBrush( *wxBLACK_BRUSH );
		pGC->DrawRectangle(0, 0, 2212, 7974);

		uiBaseY = 0;
		for(uiBaseCode = 0x2120; uiBaseCode <= 0x2FFF; uiBaseCode += 0x20) {
			sprintf(tempstr, "%04X", uiBaseCode);
			pGC->DrawText(tempstr, 2, uiBaseY + 10);

			wxGraphicsPath path = pGC->CreatePath();

			uiBaseX = 67;
			path.MoveToPoint(uiBaseX, uiBaseY);
			path.AddLineToPoint(2212, uiBaseY);
			path.MoveToPoint(uiBaseX, uiBaseY + 67);
			path.AddLineToPoint(2212, uiBaseY + 67);

			for(uiCode = uiBaseCode; uiCode < uiBaseCode + 0x20; uiCode++) {
				path.MoveToPoint(uiBaseX, uiBaseY);
				path.AddLineToPoint(uiBaseX, uiBaseY + 67);
				path.MoveToPoint(uiBaseX + 67, uiBaseY);
				path.AddLineToPoint(uiBaseX + 67, uiBaseY + 67);

				for(uiGlyphsLocate = 0; uiGlyphsLocate < i_ptGlyphsData->GlyphsCount; uiGlyphsLocate++) {
					ptGlyph = &(i_ptGlyphsData->Glyphs[uiGlyphsLocate]);
					if(ptGlyph->Code == uiCode) {
						for(uiItem = 0; uiItem < ptGlyph->VectorsCount; uiItem++) {
							path.MoveToPoint(uiBaseX + ptGlyph->Vectors[uiItem].FromX * 2 + 4, uiBaseY + 64 - (ptGlyph->Vectors[uiItem].FromY * 2 - 2));
							path.AddLineToPoint(uiBaseX + ptGlyph->Vectors[uiItem].ToX * 2 + 4, uiBaseY + 64 - (ptGlyph->Vectors[uiItem].ToY * 2 - 2));
						}
					}
				}
				uiBaseX += 67;
			}

			pGC->StrokePath(path);
			uiBaseY += 67;
		}
		delete pGC;
	}
	oImage2.SaveFile("kst32b_2120.png", wxBITMAP_TYPE_PNG);

	wxImage oImage3(2212, 8577, false);
	pGC = wxGraphicsContext::Create(oImage3);
	if(pGC) {
		pGC->SetPen( *wxWHITE_PEN );
		pGC->SetFont(font, colour);
		pGC->SetBrush( *wxBLACK_BRUSH );
		pGC->DrawRectangle(0, 0, 2212, 8577);

		uiBaseY = 0;
		for(uiBaseCode = 0x3000; uiBaseCode <= 0x3FFF; uiBaseCode += 0x20) {
			sprintf(tempstr, "%04X", uiBaseCode);
			pGC->DrawText(tempstr, 2, uiBaseY + 10);

			wxGraphicsPath path = pGC->CreatePath();

			uiBaseX = 67;
			path.MoveToPoint(uiBaseX, uiBaseY);
			path.AddLineToPoint(2212, uiBaseY);
			path.MoveToPoint(uiBaseX, uiBaseY + 67);
			path.AddLineToPoint(2212, uiBaseY + 67);

			for(uiCode = uiBaseCode; uiCode < uiBaseCode + 0x20; uiCode++) {
				path.MoveToPoint(uiBaseX, uiBaseY);
				path.AddLineToPoint(uiBaseX, uiBaseY + 67);
				path.MoveToPoint(uiBaseX + 67, uiBaseY);
				path.AddLineToPoint(uiBaseX + 67, uiBaseY + 67);

				for(uiGlyphsLocate = 0; uiGlyphsLocate < i_ptGlyphsData->GlyphsCount; uiGlyphsLocate++) {
					ptGlyph = &(i_ptGlyphsData->Glyphs[uiGlyphsLocate]);
					if(ptGlyph->Code == uiCode) {
						for(uiItem = 0; uiItem < ptGlyph->VectorsCount; uiItem++) {
							path.MoveToPoint(uiBaseX + ptGlyph->Vectors[uiItem].FromX * 2 + 4, uiBaseY + 64 - (ptGlyph->Vectors[uiItem].FromY * 2 - 2));
							path.AddLineToPoint(uiBaseX + ptGlyph->Vectors[uiItem].ToX * 2 + 4, uiBaseY + 64 - (ptGlyph->Vectors[uiItem].ToY * 2 - 2));
						}
					}
				}
				uiBaseX += 67;
			}

			pGC->StrokePath(path);
			uiBaseY += 67;
		}
		delete pGC;
	}
	oImage3.SaveFile("kst32b_3000.png", wxBITMAP_TYPE_PNG);

	wxImage oImage4(2212, 8577, false);
	pGC = wxGraphicsContext::Create(oImage4);
	if(pGC) {
		pGC->SetPen( *wxWHITE_PEN );
		pGC->SetFont(font, colour);
		pGC->SetBrush( *wxBLACK_BRUSH );
		pGC->DrawRectangle(0, 0, 2212, 8577);

		uiBaseY = 0;
		for(uiBaseCode = 0x4000; uiBaseCode <= 0x4FFF; uiBaseCode += 0x20) {
			sprintf(tempstr, "%04X", uiBaseCode);
			pGC->DrawText(tempstr, 2, uiBaseY + 10);

			wxGraphicsPath path = pGC->CreatePath();

			uiBaseX = 67;
			path.MoveToPoint(uiBaseX, uiBaseY);
			path.AddLineToPoint(2212, uiBaseY);
			path.MoveToPoint(uiBaseX, uiBaseY + 67);
			path.AddLineToPoint(2212, uiBaseY + 67);

			for(uiCode = uiBaseCode; uiCode < uiBaseCode + 0x20; uiCode++) {
				path.MoveToPoint(uiBaseX, uiBaseY);
				path.AddLineToPoint(uiBaseX, uiBaseY + 67);
				path.MoveToPoint(uiBaseX + 67, uiBaseY);
				path.AddLineToPoint(uiBaseX + 67, uiBaseY + 67);

				for(uiGlyphsLocate = 0; uiGlyphsLocate < i_ptGlyphsData->GlyphsCount; uiGlyphsLocate++) {
					ptGlyph = &(i_ptGlyphsData->Glyphs[uiGlyphsLocate]);
					if(ptGlyph->Code == uiCode) {
						for(uiItem = 0; uiItem < ptGlyph->VectorsCount; uiItem++) {
							path.MoveToPoint(uiBaseX + ptGlyph->Vectors[uiItem].FromX * 2 + 4, uiBaseY + 64 - (ptGlyph->Vectors[uiItem].FromY * 2 - 2));
							path.AddLineToPoint(uiBaseX + ptGlyph->Vectors[uiItem].ToX * 2 + 4, uiBaseY + 64 - (ptGlyph->Vectors[uiItem].ToY * 2 - 2));
						}
					}
				}
				uiBaseX += 67;
			}

			pGC->StrokePath(path);
			uiBaseY += 67;
		}
		delete pGC;
	}
	oImage4.SaveFile("kst32b_4000.png", wxBITMAP_TYPE_PNG);

	wxImage oImage5(2212, 8577, false);
	pGC = wxGraphicsContext::Create(oImage5);
	if(pGC) {
		pGC->SetPen( *wxWHITE_PEN );
		pGC->SetFont(font, colour);
		pGC->SetBrush( *wxBLACK_BRUSH );
		pGC->DrawRectangle(0, 0, 2212, 8577);

		uiBaseY = 0;
		for(uiBaseCode = 0x5000; uiBaseCode <= 0x5FFF; uiBaseCode += 0x20) {
			sprintf(tempstr, "%04X", uiBaseCode);
			pGC->DrawText(tempstr, 2, uiBaseY + 10);

			wxGraphicsPath path = pGC->CreatePath();

			uiBaseX = 67;
			path.MoveToPoint(uiBaseX, uiBaseY);
			path.AddLineToPoint(2212, uiBaseY);
			path.MoveToPoint(uiBaseX, uiBaseY + 67);
			path.AddLineToPoint(2212, uiBaseY + 67);

			for(uiCode = uiBaseCode; uiCode < uiBaseCode + 0x20; uiCode++) {
				path.MoveToPoint(uiBaseX, uiBaseY);
				path.AddLineToPoint(uiBaseX, uiBaseY + 67);
				path.MoveToPoint(uiBaseX + 67, uiBaseY);
				path.AddLineToPoint(uiBaseX + 67, uiBaseY + 67);

				for(uiGlyphsLocate = 0; uiGlyphsLocate < i_ptGlyphsData->GlyphsCount; uiGlyphsLocate++) {
					ptGlyph = &(i_ptGlyphsData->Glyphs[uiGlyphsLocate]);
					if(ptGlyph->Code == uiCode) {
						for(uiItem = 0; uiItem < ptGlyph->VectorsCount; uiItem++) {
							path.MoveToPoint(uiBaseX + ptGlyph->Vectors[uiItem].FromX * 2 + 4, uiBaseY + 64 - (ptGlyph->Vectors[uiItem].FromY * 2 - 2));
							path.AddLineToPoint(uiBaseX + ptGlyph->Vectors[uiItem].ToX * 2 + 4, uiBaseY + 64 - (ptGlyph->Vectors[uiItem].ToY * 2 - 2));
						}
					}
				}
				uiBaseX += 67;
			}

			pGC->StrokePath(path);
			uiBaseY += 67;
		}
		delete pGC;
	}
	oImage5.SaveFile("kst32b_5000.png", wxBITMAP_TYPE_PNG);

	wxImage oImage6(2212, 8577, false);
	pGC = wxGraphicsContext::Create(oImage6);
	if(pGC) {
		pGC->SetPen( *wxWHITE_PEN );
		pGC->SetFont(font, colour);
		pGC->SetBrush( *wxBLACK_BRUSH );
		pGC->DrawRectangle(0, 0, 2212, 8577);

		uiBaseY = 0;
		for(uiBaseCode = 0x6000; uiBaseCode <= 0x6FFF; uiBaseCode += 0x20) {
			sprintf(tempstr, "%04X", uiBaseCode);
			pGC->DrawText(tempstr, 2, uiBaseY + 10);

			wxGraphicsPath path = pGC->CreatePath();

			uiBaseX = 67;
			path.MoveToPoint(uiBaseX, uiBaseY);
			path.AddLineToPoint(2212, uiBaseY);
			path.MoveToPoint(uiBaseX, uiBaseY + 67);
			path.AddLineToPoint(2212, uiBaseY + 67);

			for(uiCode = uiBaseCode; uiCode < uiBaseCode + 0x20; uiCode++) {
				path.MoveToPoint(uiBaseX, uiBaseY);
				path.AddLineToPoint(uiBaseX, uiBaseY + 67);
				path.MoveToPoint(uiBaseX + 67, uiBaseY);
				path.AddLineToPoint(uiBaseX + 67, uiBaseY + 67);

				for(uiGlyphsLocate = 0; uiGlyphsLocate < i_ptGlyphsData->GlyphsCount; uiGlyphsLocate++) {
					ptGlyph = &(i_ptGlyphsData->Glyphs[uiGlyphsLocate]);
					if(ptGlyph->Code == uiCode) {
						for(uiItem = 0; uiItem < ptGlyph->VectorsCount; uiItem++) {
							path.MoveToPoint(uiBaseX + ptGlyph->Vectors[uiItem].FromX * 2 + 4, uiBaseY + 64 - (ptGlyph->Vectors[uiItem].FromY * 2 - 2));
							path.AddLineToPoint(uiBaseX + ptGlyph->Vectors[uiItem].ToX * 2 + 4, uiBaseY + 64 - (ptGlyph->Vectors[uiItem].ToY * 2 - 2));
						}
					}
				}
				uiBaseX += 67;
			}

			pGC->StrokePath(path);
			uiBaseY += 67;
		}
		delete pGC;
	}
	oImage6.SaveFile("kst32b_6000.png", wxBITMAP_TYPE_PNG);

	wxImage oImage7(2212, 2279, false);
	pGC = wxGraphicsContext::Create(oImage7);
	if(pGC) {
		pGC->SetPen( *wxWHITE_PEN );
		pGC->SetFont(font, colour);
		pGC->SetBrush( *wxBLACK_BRUSH );
		pGC->DrawRectangle(0, 0, 2212, 2279);

		uiBaseY = 0;
		for(uiBaseCode = 0x7000; uiBaseCode <= 0x743F; uiBaseCode += 0x20) {
			sprintf(tempstr, "%04X", uiBaseCode);
			pGC->DrawText(tempstr, 2, uiBaseY + 10);

			wxGraphicsPath path = pGC->CreatePath();

			uiBaseX = 67;
			path.MoveToPoint(uiBaseX, uiBaseY);
			path.AddLineToPoint(2212, uiBaseY);
			path.MoveToPoint(uiBaseX, uiBaseY + 67);
			path.AddLineToPoint(2212, uiBaseY + 67);

			for(uiCode = uiBaseCode; uiCode < uiBaseCode + 0x20; uiCode++) {
				path.MoveToPoint(uiBaseX, uiBaseY);
				path.AddLineToPoint(uiBaseX, uiBaseY + 67);
				path.MoveToPoint(uiBaseX + 67, uiBaseY);
				path.AddLineToPoint(uiBaseX + 67, uiBaseY + 67);

				for(uiGlyphsLocate = 0; uiGlyphsLocate < i_ptGlyphsData->GlyphsCount; uiGlyphsLocate++) {
					ptGlyph = &(i_ptGlyphsData->Glyphs[uiGlyphsLocate]);
					if(ptGlyph->Code == uiCode) {
						for(uiItem = 0; uiItem < ptGlyph->VectorsCount; uiItem++) {
							path.MoveToPoint(uiBaseX + ptGlyph->Vectors[uiItem].FromX * 2 + 4, uiBaseY + 64 - (ptGlyph->Vectors[uiItem].FromY * 2 - 2));
							path.AddLineToPoint(uiBaseX + ptGlyph->Vectors[uiItem].ToX * 2 + 4, uiBaseY + 64 - (ptGlyph->Vectors[uiItem].ToY * 2 - 2));
						}
					}
				}
				uiBaseX += 67;
			}

			pGC->StrokePath(path);
			uiBaseY += 67;
		}
		delete pGC;
	}
	oImage7.SaveFile("kst32b_7000.png", wxBITMAP_TYPE_PNG);
}

int main(int i_iArgc, char* lstrArgc[]) {
	LoadKST32B(&g_tCSF1GlyphsData);
	CSF1ToVector(&g_tGlyphsData, &g_tCSF1GlyphsData);
	OutputPicture(&g_tGlyphsData);
	return 0;
}
