#include <mil.h>
#include <math.h>
#include "FontUtil.h"
#include "CharacterCreator.h"
#include "VisualizeFont.h"
static const MIL_INT MAX_DISPLAY_SIZE_X = 1600;
static const MIL_INT TEXT_SIZE_Y = 20;
static const MIL_INT MIN_CHAR_SPACE = 20;
static const MIL_INT MIN_CHAR_SIZE_X = 120;
const MIL_DOUBLE SCALE_FACTOR = 0.333;
CVisualizeFont::CVisualizeFont(MIL_ID MilSystem, MIL_ID MilDmrContext)
: m_NumberOfChar(0),
m_ValidFontFile(true)
{
MdmrInquireFont(MilDmrContext, M_FONT_INDEX(0), M_DEFAULT, M_NULL,
M_NUMBER_OF_CHARS + M_TYPE_MIL_INT, &m_NumberOfChar);
if (m_NumberOfChar == 0)
{
m_ValidFontFile = false;
return;
}
MdmrInquireFont(MilDmrContext, M_FONT_INDEX(0), M_DEFAULT, M_NULL,
M_FONT_SIZE_COLUMNS + M_TYPE_MIL_INT, &m_FontSizeX);
if (m_FontSizeX == M_DEFAULT)
MdmrInquireFont(MilDmrContext, M_FONT_INDEX(0), M_DEFAULT, M_NULL,
M_FONT_SIZE_COLUMNS + M_TYPE_MIL_INT + M_DEFAULT, &m_FontSizeX);
MdmrInquireFont(MilDmrContext, M_FONT_INDEX(0), M_DEFAULT, M_NULL,
M_FONT_SIZE_ROWS + M_TYPE_MIL_INT, &m_FontSizeY);
if (m_FontSizeY == M_DEFAULT)
MdmrInquireFont(MilDmrContext, M_FONT_INDEX(0), M_DEFAULT, M_NULL,
M_FONT_SIZE_ROWS + M_TYPE_MIL_INT + M_DEFAULT, &m_FontSizeY);
m_pCharCreator = new CCharCreator(MilSystem, m_FontSizeX, m_FontSizeY);
CalculateDisplaySize();
MdispAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_WINDOWED, &m_MilDisplay);
MdispControl(m_MilDisplay, M_TITLE, MIL_TEXT("Dot Matrix Font"));
MbufAlloc2d(MilSystem, m_DisplaySizeX, m_DisplaySizeY, 8 + M_UNSIGNED,
M_IMAGE + M_PROC + M_DISP, &m_MilDisplayBuffer);
MbufClear(m_MilDisplayBuffer, M_COLOR_WHITE);
DrawAllCharFontToDisplay(MilDmrContext);
}
CVisualizeFont::~CVisualizeFont()
{
if (m_ValidFontFile)
{
MdispSelect(m_MilDisplay, M_NULL);
MdispFree(m_MilDisplay);
MbufFree(m_MilDisplayBuffer);
delete m_pCharCreator;
}
}
void CVisualizeFont::VisualizeFont()
{
if (m_ValidFontFile)
{
MdispSelect(m_MilDisplay, m_MilDisplayBuffer);
}
}
void CVisualizeFont::SaveDisplayFontImage()
{
if (m_ValidFontFile)
{
MIL_TEXT_CHAR MyChar = ' ';
MosPrintf(MIL_TEXT("Press 'S' to save the display font or any other key to continue.\n\n"));
MyChar = (MIL_TEXT_CHAR)MosGetch();
if ((MyChar != 's') && (MyChar != 'S'))
return;
MIL_INT ExportError = M_NULL_ERROR;
do
{
MappControl(M_ERROR, M_PRINT_DISABLE);
MbufSave(M_INTERACTIVE, m_MilDisplayBuffer);
MappGetError(M_DEFAULT, M_CURRENT, &ExportError);
MappControl(M_ERROR, M_PRINT_ENABLE);
if (ExportError != M_NULL_ERROR)
{
MosPrintf(MIL_TEXT("Displayed font image could not be exported!\n\n"));
MosPrintf(MIL_TEXT("Press <Enter> to retry or any other key to continue.\n\n"));
if (MosGetch() != MIL_TEXT('\r'))
ExportError = M_NULL_ERROR;
}
else
MosPrintf(MIL_TEXT("The display font has been succesfully saved.\n\n"));
} while (ExportError != M_NULL_ERROR);
}
}
void CVisualizeFont::CalculateDisplaySize(void)
{
MIL_INT CharSizeX = MbufInquire(m_pCharCreator->CharacterImage(), M_SIZE_X, M_NULL);
MIL_INT CharSizeY = MbufInquire(m_pCharCreator->CharacterImage(), M_SIZE_Y, M_NULL);
m_SizeChildX = (MIL_INT)(SCALE_FACTOR * (MIL_DOUBLE)CharSizeX);
m_SizeChildY = (MIL_INT)(SCALE_FACTOR * (MIL_DOUBLE)CharSizeY);
m_CharSpaceX = MIN_CHAR_SPACE;
if (m_SizeChildX < MIN_CHAR_SIZE_X)
m_CharSpaceX += (MIN_CHAR_SIZE_X - m_SizeChildX)/2;
MIL_INT NbColumnsX = (MAX_DISPLAY_SIZE_X + m_CharSpaceX) / (m_SizeChildX + m_CharSpaceX);
NbColumnsX = (NbColumnsX > m_NumberOfChar) ? m_NumberOfChar : NbColumnsX;
MIL_INT NbSpaceX = NbColumnsX - 1;
m_DisplaySizeX = NbColumnsX * m_SizeChildX + (NbSpaceX + 2) * m_CharSpaceX;
MIL_INT NbRows = (MIL_INT)ceil((MIL_DOUBLE)m_NumberOfChar / NbColumnsX);
MIL_INT NbSpaceY = NbRows - 1;
m_DisplaySizeY = NbRows * (m_SizeChildY + TEXT_SIZE_Y) + (NbSpaceY + 2) * MIN_CHAR_SPACE;
}
void CVisualizeFont::DrawCharFontToDisplay(MIL_ID MilDmrContext, MIL_INT Index,
MIL_INT OffsetX, MIL_INT OffsetY)
{
vector<MIL_UINT8> DotCharMatrix(m_FontSizeX * m_FontSizeY);
MdmrInquireFont(MilDmrContext, M_FONT_INDEX(0), Index, M_NULL,
M_CHAR_TEMPLATE + M_TYPE_MIL_UINT8, &DotCharMatrix[0]);
CCharCreator CharCreator(M_DEFAULT_HOST, m_FontSizeX, m_FontSizeY);
CharCreator.LoadCharacter(DotCharMatrix);
MbufChild2d(m_MilDisplayBuffer, OffsetX, OffsetY + TEXT_SIZE_Y,
m_SizeChildX, m_SizeChildY, &m_MilDisplayChildBuffer);
MimResize(CharCreator.CharacterImage(), m_MilDisplayChildBuffer,
M_FILL_DESTINATION, M_FILL_DESTINATION, M_AVERAGE + M_OVERSCAN_DISABLE);
MgraControl(M_DEFAULT, M_BACKGROUND_MODE, M_TRANSPARENT);
MgraColor(M_DEFAULT, M_COLOR_BLACK);
MgraControl(M_DEFAULT, M_FONT_SIZE, 16);
MappControl(M_DEFAULT, M_ERROR, M_PRINT_DISABLE);
MgraFont(M_DEFAULT, MIL_FONT_NAME(M_FONT_DEFAULT_TTF MIL_TEXT(":Bold")));
MappControl(M_DEFAULT, M_ERROR, M_PRINT_ENABLE);
mstring CharName;
FontUtil::GetCharName(MilDmrContext, Index, M_NULL, &CharName);
mstring CharHexName;
FontUtil::GetCharName(MilDmrContext, Index, M_HEX_UTF16_FOR_ALL, &CharHexName);
mstring FullName = CharName + MIL_TEXT(" (") + CharHexName + MIL_TEXT(")");
if (!(CCharCreator::DrawCharacterName(m_MilDisplayBuffer, OffsetX, OffsetY, FullName.c_str())))
{
FullName = MIL_TEXT(" (") + CharHexName + MIL_TEXT(")");
MgraText(M_DEFAULT, m_MilDisplayBuffer, OffsetX, OffsetY, FullName.c_str());
}
MbufFree(m_MilDisplayChildBuffer);
}
void CVisualizeFont::DrawAllCharFontToDisplay(MIL_ID MilDmrContext)
{
MIL_INT OffsetX = m_CharSpaceX;
MIL_INT OffsetY = MIN_CHAR_SPACE;
for (MIL_INT i = 0; i < m_NumberOfChar; i++)
{
if (OffsetX > m_DisplaySizeX - m_CharSpaceX - 1)
{
OffsetY += m_SizeChildY + TEXT_SIZE_Y + MIN_CHAR_SPACE;
OffsetX = m_CharSpaceX;
}
DrawCharFontToDisplay(MilDmrContext, i, OffsetX, OffsetY);
OffsetX += m_SizeChildX + m_CharSpaceX;
}
}