1
0
mirror of https://github.com/azure-rtos/guix.git synced 2025-02-04 07:13:17 +08:00
guix/guix_studio/resource_gen.cpp

5033 lines
146 KiB
C++

#include "studiox_includes.h"
#include "system_pngs.h"
extern "C"{
#include "gx_utility.h"
#include "gx_api.h"
extern GX_FONT _gx_system_font_8bpp;
extern GX_FONT _gx_system_font_4bpp;
extern GX_FONT _gx_system_font_mono;
extern GX_FONT _gx_dave2d_system_font_4bpp;
extern GX_FONT _gx_dave2d_system_font_mono;
}
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
CString ResourceCommentBlock(""
"/*******************************************************************************/\n"
"/* This file is auto-generated by Azure RTOS GUIX Studio. Do not edit this */\n"
"/* file by hand. Modifications to this file should only be made by running */\n"
"/* the Azure RTOS GUIX Studio application and re-generating the application */\n"
"/* resource file(s). For more information please refer to the Azure RTOS GUIX */\n"
"/* Studio User Guide, or visit our web site at azure.com/rtos */\n"
"/* */\n"
);
#define COLUMN_WIDTH 80
#define GX_CONVERT_VER 1
#define GX_CONVERT_SUBVER 0
static TCHAR *strColorFormat51[] = {
_T(""),
_T("GX_COLOR_FORMAT_MONOCHROME"),
_T("GX_COLOR_FORMAT_MONOCHROME_INVERTED"),
_T("GX_COLOR_FORMAT_2BIT_GRAY"),
_T("GX_COLOR_FORMAT_2BIT_GRAY_INVERTED"),
_T("GX_COLOR_FORMAT_4BIT_GRAY"),
_T("GX_COLOR_FORMAT_4BIT_GRAY_INVERTED"),
_T("GX_COLOR_FORMAT_4BIT_VGA"),
_T("GX_COLOR_FORMAT_8BIT_GRAY"),
_T("GX_COLOR_FORMAT_8BIT_GRAY_INVERTED"),
_T("GX_COLOR_FORMAT_8BIT_PALETTE"),
_T("GX_COLOR_FORMAT_8BIT_PACKED_PIXEL"),
_T("GX_COLOR_FORMAT_15BIT_BGR"),
_T("GX_COLOR_FORMAT_15BIT_RGB"),
_T("GX_COLOR_FORMAT_16BIT_RGB"),
_T("GX_COLOR_FORMAT_16BIT_ARGB"),
_T("GX_COLOR_FORMAT_16BIT_BGRA"),
_T("GX_COLOR_FORMAT_16BIT_BGR"),
_T("GX_COLOR_FORMAT_24BIT_RGB"),
_T("GX_COLOR_FORMAT_24BIT_BGR"),
_T("GX_COLOR_FORMAT_24BIT_XRGB"),
_T("GX_COLOR_FORMAT_24BIT_BGRX"),
_T("GX_COLOR_FORMAT_32BIT_ARGB"),
_T("GX_COLOR_FORMAT_32BIT_RGBA"),
_T("GX_COLOR_FORMAT_32BIT_ABGR"),
_T("GX_COLOR_FORMAT_32BIT_BGRA"),
};
static TCHAR *strColorFormat52[] = {
_T(""),
_T("GX_COLOR_FORMAT_MONOCHROME"),
_T("GX_COLOR_FORMAT_MONOCHROME_INVERTED"),
_T("GX_COLOR_FORMAT_2BIT_GRAY"),
_T("GX_COLOR_FORMAT_2BIT_GRAY_INVERTED"),
_T("GX_COLOR_FORMAT_4BIT_GRAY"),
_T("GX_COLOR_FORMAT_4BIT_GRAY_INVERTED"),
_T("GX_COLOR_FORMAT_4BIT_VGA"),
_T("GX_COLOR_FORMAT_8BIT_GRAY"),
_T("GX_COLOR_FORMAT_8BIT_GRAY_INVERTED"),
_T("GX_COLOR_FORMAT_8BIT_PALETTE"),
_T("GX_COLOR_FORMAT_8BIT_PACKED_PIXEL"),
_T("GX_COLOR_FORMAT_5551BGRX"),
_T("GX_COLOR_FORMAT_1555XRGB"),
_T("GX_COLOR_FORMAT_565RGB"),
_T("GX_COLOR_FORMAT_4444ARGB"),
_T("GX_COLOR_FORMAT_4444BGRA"),
_T("GX_COLOR_FORMAT_565BGR"),
_T("GX_COLOR_FORMAT_24RGB"),
_T("GX_COLOR_FORMAT_24BGR"),
_T("GX_COLOR_FORMAT_24XRGB"),
_T("GX_COLOR_FORMAT_24BGRX"),
_T("GX_COLOR_FORMAT_32ARGB"),
_T("GX_COLOR_FORMAT_32RGBA"),
_T("GX_COLOR_FORMAT_32ABGR"),
_T("GX_COLOR_FORMAT_32BGRA"),
_T("GX_COLOR_FORMAT_8BIT_ALPHAMAP"),
};
#define NUM_COLOR_FORMATS (sizeof(strColorFormat52) / sizeof(TCHAR *))
#define IS_RX_TARGET (m_project->mHeader.target_cpu == CPU_RX)
#define IS_RZ_TARGET (m_project->mHeader.target_cpu == CPU_RZ)
#define IS_GNU_TOOLS (m_project->mHeader.target_tools == TOOLS_GNU)
#define IS_IAR_TOOLS (m_project->mHeader.target_tools == TOOLS_IAR)
////////////////////////////////////////////////////////////////////////////////////////////////
resource_gen::resource_gen(studiox_project *proj)
{
m_project = proj;
m_num_displays = m_project->mHeader.num_displays;
mUsingDefault8BitFont = FALSE;
mUsingDefault4BitFont = FALSE;
mUsingDefaultMonoFont = FALSE;
if (GetCmdInfo()->IsNoGui())
{
m_big_endian = GetCmdInfo()->IsBigEndian();
}
else
{
m_big_endian = m_project->mHeader.big_endian;
}
mp_bin_generater = NULL;
m_warn_on_error = FALSE;
}
///////////////////////////////////////////////////////////////////////////////
//
// IsRotatedResourceSupported
//
// Static function used by resource_gen, binary_resource_gen, and
// screen generator to determine if screen rotation support is enabled.
///////////////////////////////////////////////////////////////////////////////
BOOL resource_gen::IsRotatedResourceSupported(studiox_project *project, int display)
{
#if !defined(ENABLE_RENESAS_DAVE2D_DISPLAY_ROTATION)
if (project->mHeader.target_cpu == CPU_SYNERGY)
{
return FALSE;
}
#endif
if (project->mDisplays[display].rotation_angle == GX_SCREEN_ROTATION_CW ||
project->mDisplays[display].rotation_angle == GX_SCREEN_ROTATION_CCW)
{
switch (project->mDisplays[display].colorformat)
{
case GX_COLOR_FORMAT_565RGB:
if (project->mHeader.guix_version >= GX_VERSION_DISPLAY_ROTATION)
{
return TRUE;
}
break;
case GX_COLOR_FORMAT_8BIT_PALETTE:
if (project->mHeader.guix_version >= GX_VERSION_8BIT_PALETTE_DISPLAY_ROTATION)
{
return TRUE;
}
break;
case GX_COLOR_FORMAT_24XRGB:
case GX_COLOR_FORMAT_32ARGB:
if (project->mHeader.guix_version >= GX_VERSION_8BIT_PALETTE_DISPLAY_ROTATION)
{
return TRUE;
}
break;
}
}
return FALSE;
}
////////////////////////////////////////////////////////////////////////////////////////////////
BOOL resource_gen::SetOutFile(CString filename, BOOL binary_mode)
{
CString pathname;
PATHINFO info;
CString outfile = m_project->mHeader.resource_path;
if (outfile.GetAt(outfile.GetLength() - 1) != '\\')
{
outfile += '\\';
}
outfile += filename;
if (outfile.GetAt(1) != ':')
{
ConvertToProjectRelativePath(outfile);
info.pathname = outfile;
info.pathtype = PATH_TYPE_PROJECT_RELATIVE;
outfile = MakeAbsolutePathname(info);
}
if (!CheckOutputFileSecurity(outfile, binary_mode))
{
return FALSE;
}
for (int index = 0; index < outfile_list.GetCount(); index++)
{
m_outfile = outfile_list.GetAt(index);
pathname = m_outfile->GetFilePath();
if (!outfile.Compare(pathname))
{
m_written_size = (ULONG)m_outfile->GetLength();
return TRUE;
}
}
m_outfile = new CFile();
m_written_size = 0;
if (!m_outfile->Open(outfile, CFile::modeCreate | CFile::modeWrite))
{
CString msg;
msg.Format(_T("Could not open output file:\n%s\nPlease check resource file path."), outfile);
ErrorMsg(msg);
delete m_outfile;
return FALSE;
}
outfile_list.Add(m_outfile);
if (binary_mode)
{
((binary_resource_gen *)this)->WriteStandaloneResHeader();
}
else
{
WriteCommentBlock(ResourceCommentBlock);
CString out;
if (m_project->mHeader.insert_headers_before)
{
// Insert additional headers before any other includes
WriteAdditionalHeaders(m_project->mHeader.additional_headers);
}
out.Format(_T("#include \"gx_api.h\"\n#include \"%s.h\"\n"), GetResourceFileName());
FileWrite(out);
if (!m_project->mHeader.insert_headers_before)
{
//Insert additional headers after any other includes
WriteAdditionalHeaders(m_project->mHeader.additional_headers);
}
}
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteErrorDirectives()
{
CCommandInfo *pCmdInfo = GetCmdInfo();
BOOL enabled;
BOOL UTF8 = FALSE;
BOOL EXTENDED_UNICODE = FALSE;
BOOL KERNING = FALSE;
CString out;
for (int theme = 0; theme < m_project->mDisplays[m_display].num_themes; theme++)
{
m_ThemeName = m_project->mDisplays[m_display].themes[theme].theme_name;
if (pCmdInfo->IsNoGui())
{
enabled = pCmdInfo->IsThemeEnabled(m_ThemeName);
}
else
{
enabled = m_project->mDisplays[m_display].themes[theme].gen_font_table;
}
if (!enabled) continue;
int font_id;
for (font_id = 0; font_id < m_project->CountResources(m_display, RES_TYPE_FONT); font_id++)
{
res_info *info = m_project->FindResource(m_display, theme, RES_TYPE_FONT, font_id);
if (info)
{
if (!KERNING && info->font_kerning)
{
KERNING = TRUE;
}
if ((!UTF8 || !EXTENDED_UNICODE) && !(info->is_default && info->pathinfo.pathname.IsEmpty()))
{
if (info->font_support_extended_unicode)
{
EXTENDED_UNICODE = TRUE;
UTF8 = TRUE;
}
else
{
GX_FONT *next_page = m_optimized_fonts[theme].GetAt(font_id);
if(!next_page)
{
next_page = MakeOptimizedFont(info, m_display, m_warn_on_error);
if (!next_page)
{
m_warn_on_error = FALSE;
}
// Reserve optimized font for later use.
m_optimized_fonts[theme].SetAt(font_id, next_page);
}
while (next_page)
{
if (next_page->gx_font_last_glyph > 0xffff)
{
EXTENDED_UNICODE = TRUE;
UTF8 = TRUE;
break;
}
else if (next_page->gx_font_last_glyph > 0xff)
{
UTF8 = TRUE;
}
next_page = (GX_FONT *)next_page->gx_font_next_page;
}
}
}
}
}
if (EXTENDED_UNICODE && KERNING)
{
break;
}
}
out = "";
if (UTF8)
{
out += _T("\n#if !defined(GX_UTF8_SUPPORT)\n");
out += _T("#error \"The symbol GX_UTF8_SUPPORT must be defined to support the Studio project settings\".\n");
out += _T("#endif\n");
}
if (EXTENDED_UNICODE)
{
out += _T("#if !defined(GX_EXTENDED_UNICODE_SUPPORT)\n");
out += _T("#error \"The symbol GX_EXTENDED_UNICODE_SUPPORT must be defined to support the Studio project settings\".\n");
out += _T("#endif\n");
}
if (KERNING)
{
out += _T("#if !defined(GX_FONT_KERNING_SUPPORT)\n");
out += _T("#error \"The symbol GX_FONT_KERNING_SUPPORT must be defined if \'Generate kerning info\' is selected in font edit dialog\".\n");
out += _T("#endif\n");
}
FileWrite(out);
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::CalculateTableSizes()
{
/* Calculate the size of color table, font table and pixelmap table. */
m_color_table_size = m_font_table_size = m_pixelmap_table_size = 0;
int active_theme = m_project->mDisplays[m_display].active_theme;
int res_id;
res_info *info;
m_color_table_size = m_project->CountResources(m_display, RES_TYPE_COLOR);
for (res_id = 0; res_id < m_project->CountResources(m_display, RES_TYPE_FONT); res_id++)
{
info = m_project->FindResource(m_display, active_theme, RES_TYPE_FONT, res_id);
if (IsResEnabled(info) && (!info->output_file_enabled || !info->binary_mode))
{
m_font_table_size++;
}
}
m_pixelmap_table_size = 1;
for (res_id = 1; res_id <= m_project->CountResources(m_display, RES_TYPE_PIXELMAP); res_id++)
{
info = m_project->FindResource(m_display, active_theme, RES_TYPE_PIXELMAP, res_id);
if ((IsResEnabled(info) && (!info->output_file_enabled || !info->binary_mode)) || IsSystemPixelmap(res_id))
{
m_pixelmap_table_size += info->GetPixelmapFrameCount();
}
}
}
///////////////////////////////////////////////////////////////////////////////
BOOL resource_gen::IsStringReferencedbyMlView(widget_info* info, GX_RESOURCE_ID resource_id)
{
while (info)
{
if ((info->basetype == GX_TYPE_MULTI_LINE_TEXT_VIEW) &&
(info->string_id[0] == resource_id))
{
return TRUE;
}
if (IsStringReferencedbyMlView(info->GetChildWidgetInfo(), resource_id))
{
return TRUE;
}
info = info->GetNextWidgetInfo();
}
return FALSE;
}
////////////////////////////////////////////////////////////////////////////////////////////////
BOOL resource_gen::GenerateResourceFile(int display)
{
m_display = display;
mDefaultPaletteWritten = FALSE;
GotoProjectDirectory();
// for now just use project name for output name
CCommandInfo *pCmdInfo = GetCmdInfo();
CString res_file_name;
BOOL gen_res_header;
if (m_outfile)
{
delete m_outfile;
}
InitOptimizedFonts();
m_outfile = new CFile();
CalculateTableSizes();
if (pCmdInfo->IsNoGui())
{
gen_res_header = pCmdInfo->GenResHeader();
}
else
{
gen_res_header = m_project->mHeader.gen_res_header;
}
m_project->CopyDictionary(m_display, RES_TYPE_PIXELMAP, &m_pixelmap_dictionary);
m_project->SortResDictionary(RES_TYPE_PIXELMAP, &m_pixelmap_dictionary);
if (gen_res_header)
{
res_file_name = m_project->mHeader.header_path;
if (!res_file_name.IsEmpty())
{
if (res_file_name.GetAt(res_file_name.GetLength() - 1) != '\\')
{
res_file_name += "\\";
}
}
res_file_name += GetResourceFileName() + _T(".h");
if (!CheckOutputFileSecurity(res_file_name))
{
return FALSE;
}
/* Generate head file. */
if (!m_outfile->Open(res_file_name, CFile::modeCreate | CFile::modeWrite))
{
CString msg;
msg.Format(_T("Could not open output file:\n%s\nPlease check resource file path."), res_file_name);
ErrorMsg(msg);
delete m_outfile;
DestroyOptimizedFonts();
return FALSE;
}
GenerateResourceHeader();
m_outfile->Close();
}
res_file_name = m_project->mHeader.resource_path;
if (!res_file_name.IsEmpty())
{
if (res_file_name.GetAt(res_file_name.GetLength() - 1) != '\\')
{
res_file_name += "\\";
}
}
res_file_name += GetResourceFileName() + _T(".c");
/* Generate c file. */
if (!m_outfile->Open(res_file_name, CFile::modeCreate | CFile::modeWrite))
{
CString msg;
msg.Format(_T("Could not open output file:\n%s\nPlease check resource file path."), res_file_name);
ErrorMsg(msg);
EndBusyMsg();
delete m_outfile;
DestroyOptimizedFonts();
return FALSE;
}
outfile_list.Add(m_outfile);
if (pCmdInfo->IsXmlMode())
{
WriteFontData();
WritePixelmapData();
}
else
{
GenerateResourceData();
}
DestroyOptimizedFonts();
CloseOutputFiles();
if (mp_bin_generater)
{
mp_bin_generater->DestroyResource();
delete mp_bin_generater;
mp_bin_generater = NULL;
}
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::CloseOutputFiles()
{
for (int index = 0; index < outfile_list.GetCount(); index++)
{
m_outfile = outfile_list.GetAt(index);
m_outfile->Close();
delete m_outfile;
}
m_outfile = NULL;
outfile_list.RemoveAll();
}
////////////////////////////////////////////////////////////////////////////////////////////////
CString resource_gen::UpperProjectName()
{
CString name(m_project->mHeader.project_name);
name.MakeUpper();
return name;
}
////////////////////////////////////////////////////////////////////////////////////////////////
CString resource_gen::UpperProjDisplayName()
{
CString name(m_project->mHeader.project_name);
name += "_";
name += m_project->mDisplays[m_display].name;
name.MakeUpper();
return name;
}
////////////////////////////////////////////////////////////////////////////////////////////////
BOOL resource_gen::GenerateResourceHeader()
{
WriteCommentBlock(ResourceCommentBlock);
CString out;
CString name;
name = UpperProjDisplayName();
out.Format(_T("#ifndef _%s_RESOURCES_H_\n#define _%s_RESOURCES_H_\n\n"), name, name);
FileWrite(out);
FileWrite(CString("#include \"gx_api.h\"\n"));
WriteErrorDirectives();
WriteDisplayDefines();
WriteThemeDefines();
WriteLanguageDefines();
WriteColorDefines();
WriteFontDefines();
WritePixelmapDefines();
WriteStringDefines();
FileWrite(CString("\n#endif /* sentry */\n"));
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////////////////////
BOOL resource_gen::GenerateResourceData()
{
string_table *table = GetActiveStringTable();
if (table)
{
table->GenerateCleanCharacterMap();
}
WriteCommentBlock(ResourceCommentBlock);
CString out;
if (m_project->mHeader.insert_headers_before)
{
//Insert additional headers before any other includes
WriteAdditionalHeaders(m_project->mHeader.additional_headers);
}
out.Format(_T("#include \"gx_api.h\"\n#include \"%s.h\"\n"), GetResourceFileName());
FileWrite(out);
if (!m_project->mHeader.insert_headers_before)
{
WriteAdditionalHeaders(m_project->mHeader.additional_headers);
}
WriteColorTable();
WriteFontData();
WriteFontTable();
WritePixelmapData();
WritePixelmapTable();
WriteStringData();
WriteStringTable();
WriteThemes();
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::InitOptimizedFonts()
{
int font_count = m_project->CountResources(m_display, RES_TYPE_FONT);
for (int theme = 0; theme < m_project->mDisplays[m_display].num_themes; theme++)
{
m_optimized_fonts[theme].RemoveAll();
for (int index = 0; index < font_count; index++)
{
m_optimized_fonts[theme].Add(GX_NULL);
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::DestroyOptimizedFonts()
{
GX_FONT* font;
for (int theme = 0; theme < m_project->mDisplays[m_display].num_themes; theme++)
{
for (int index = 0; index < m_optimized_fonts[theme].GetCount(); index++)
{
font = m_optimized_fonts[theme].GetAt(index);
if (font)
{
DestroyFont(font);
}
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
TCHAR **resource_gen::GetColorFormatTable(studiox_project *project)
{
TCHAR** format_name = strColorFormat52;
/* switch for backward compatibility */
if (project->mHeader.guix_version < 50200)
{
format_name = strColorFormat51;
}
return format_name;
}
////////////////////////////////////////////////////////////////////////////////////////////////
TCHAR *resource_gen::GetColorFormatName(int color_format)
{
if (color_format >= NUM_COLOR_FORMATS)
{
ErrorMsg("Invalid color format in project header");
return(_T("INVALID_FORMAT"));
}
studiox_project* project = GetOpenProject();
if (!project)
{
return L"";
}
return(GetColorFormatTable(project)[color_format]);
}
////////////////////////////////////////////////////////////////////////////////////////////////
int resource_gen::GetColorFormatVal(CString name)
{
if (name.IsEmpty())
{
return 0;
}
studiox_project* project = GetOpenProject();
if (!project)
{
return 0;
}
TCHAR** table = GetColorFormatTable(project);
for(int index = 0; index < NUM_COLOR_FORMATS; index++)
{
if (CString(table[index]) == name)
{
return index;
}
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteDisplayDefines()
{
CString out;
WriteComment("Display and theme definitions");
out.Format(_T("#define %s %d\n"), UpperDisplayName(), m_display);
FileWrite(out);
out.Format(_T("#define %s_COLOR_FORMAT %s\n"), UpperDisplayName(), GetColorFormatName(m_project->mDisplays[m_display].colorformat));
FileWrite(out);
out.Format(_T("#define %s_X_RESOLUTION %d\n"), UpperDisplayName(), m_project->mDisplays[m_display].xres);
FileWrite(out);
out.Format(_T("#define %s_Y_RESOLUTION %d\n"), UpperDisplayName(), m_project->mDisplays[m_display].yres);
FileWrite(out);
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteThemeDefines()
{
/* Pickup command info class instance. */
CCommandInfo *pCmdInfo = GetCmdInfo();
theme_info *info;
CString theme_name;
BOOL enabled;
CString out;
int theme_count = 0;
for (int theme = 0; theme < m_project->mDisplays[m_display].num_themes; theme++)
{
info = &(m_project->mDisplays[m_display].themes[theme]);
theme_name = info->theme_name;
if (pCmdInfo->IsNoGui())
{
enabled = pCmdInfo->IsThemeEnabled(theme_name);
}
else
{
enabled = info->enabled;
}
// Include the definitions of enabled themes
if (enabled)
{
theme_name.MakeUpper();
out.Format(_T("#define %s_%s %d\n"), UpperDisplayName(), theme_name, theme_count);
FileWrite(out);
theme_count++;
}
}
if (m_project->mHeader.guix_version > 50302)
{
if (theme_count)
{
out.Format(_T("#define %s_THEME_TABLE_SIZE %d\n"), UpperDisplayName(), theme_count);
FileWrite(out);
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteLanguageDefines()
{
CString out;
INT language_count = 0;
WriteComment("Language definitions");
/* Pickup command info class instance. */
CCommandInfo *pCmdInfo = GetCmdInfo();
CString lang_name;
BOOL enabled;
CString display_name;
if (m_project->mHeader.num_displays > 1)
{
display_name = UpperDisplayName() + _T("_");
}
else
{
display_name = _T("");
}
for (int language = 0; language < m_project->mHeader.num_languages; language++)
{
lang_name = m_project->mHeader.languages[language].name;
if (pCmdInfo->IsNoGui())
{
enabled = pCmdInfo->IsLanguageEnabled(lang_name);
}
else
{
enabled = m_project->mDisplays[m_display].gen_string_table[language];
}
/* Include the definicions of enabled languages. */
if(enabled)
{
lang_name.MakeUpper();
out.Format(_T("#define %sLANGUAGE_%s %d\n"), display_name, lang_name, language_count);
FileWrite(out);
language_count++;
}
}
if (language_count)
{
out.Format(_T("#define %s_LANGUAGE_TABLE_SIZE %d\n"), UpperDisplayName(), language_count);
FileWrite(out);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteColorDefines(void)
{
int color_id;
int active_theme = m_project->mDisplays[m_display].active_theme;
WriteComment("Color ID definitions");
CString out;
CString res_name;
CString upper_name;
CString display_name = UpperDisplayName();
BOOL gen_system_color_ids = FALSE;
if (project_lib_version() < GX_VERSION_RESOURCE_ID_GENERATE_FIX)
{
gen_system_color_ids = TRUE;
}
for (color_id = 0; color_id < m_project->CountResources(m_display, RES_TYPE_COLOR); color_id++)
{
res_info *info = m_project->FindResource(m_display, active_theme, RES_TYPE_COLOR, color_id);
if (info)
{
upper_name = CString(info->name);
upper_name.MakeUpper();
if (info->is_default)
{
if ((m_display == 0) && gen_system_color_ids)
{
out.Format(_T("#define GX_COLOR_ID_%s %d\n"), upper_name, color_id);
FileWrite(out);
}
}
else
{
if (m_num_displays > 1)
{
out.Format(_T("#define GX_COLOR_ID_%s_%s %d\n"), display_name, upper_name, color_id);
}
else
{
out.Format(_T("#define GX_COLOR_ID_%s %d\n"), upper_name, color_id);
}
FileWrite(out);
}
}
}
out.Format(_T("#define %s_COLOR_TABLE_SIZE %d\n"),
display_name, m_color_table_size);
FileWrite(out);
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteColorTable(void)
{
int color_id;
res_info *info;
WriteComment("Color Table");
CString out;
GX_COLOR rgb_color;
GX_COLOR native_color;
int color_format;
color_format = m_project->mDisplays[m_display].colorformat;
CCommandInfo *pCmdInfo = GetCmdInfo();
BOOL enabled;
for (int theme = 0; theme < m_project->mDisplays[m_display].num_themes; theme++)
{
if (pCmdInfo->IsNoGui())
{
enabled = pCmdInfo->IsThemeEnabled(m_project->mDisplays[m_display].themes[theme].theme_name);
}
else
{
enabled = m_project->mDisplays[m_display].themes[theme].gen_color_table;
}
if (!enabled) continue;
out.Format(_T("GX_CONST GX_COLOR %s_%s_color_table[] =\n{\n"),
m_project->mDisplays[m_display].name,
m_project->mDisplays[m_display].themes[theme].theme_name);
FileWrite(out);
int end_id = m_project->CountResources(m_display, RES_TYPE_COLOR);
BOOL bFirstColor = TRUE;
for (color_id = 0; color_id < end_id; color_id++)
{
info = m_project->FindResource(m_display, theme, RES_TYPE_COLOR, color_id);
if (info)
{
rgb_color = info->colorval;
native_color = resource_view::GetNativeColor(rgb_color, color_format);
if (bFirstColor)
{
out.Format(_T(" 0x%08x"), native_color);
bFirstColor = FALSE;
}
else
{
out.Format(_T(",\n 0x%08x"), native_color);
}
FileWrite(out);
}
}
out.Format(_T("\n};\n\n"));
FileWrite(out);
/* Olny write palette for 8bit palette driver for now.
4bpp driver contains palette table. But should not write it to file. */
if (color_format == GX_COLOR_FORMAT_8BIT_PALETTE &&
m_project->mDisplays[m_display].themes[theme].palette)
{
WritePalette(theme);
mDefaultPaletteWritten = TRUE;
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WritePalette(int theme)
{
GX_COLOR *palette;
int palette_size;
// make sure the optimal palette is up to date:
m_project->CreateThemePalette(m_display, theme, NULL);
// CreateThemePalette() updates the display.themes.palette
palette_size = m_project->mDisplays[m_display].themes[theme].palette_total_size;
palette = m_project->mDisplays[m_display].themes[theme].palette;
WritePalette(palette_size, palette, m_project->mDisplays[m_display].themes[theme].theme_name);
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WritePalette(int palette_size, GX_COLOR *palette,
CString &pal_name)
{
CString out;
int palette_index;
WriteComment("Color Palette");
GX_COLOR rgb_color;
if (palette == NULL || palette_size == 0)
{
return;
}
out.Format(_T("GX_CONST GX_COLOR %s_%s_palette[%d] =\n{\n"),
m_project->mDisplays[m_display].name, pal_name, palette_size);
FileWrite(out);
for (palette_index = 0; palette_index < palette_size; palette_index++)
{
rgb_color = palette[palette_index];
if (palette_index < palette_size - 1)
{
out.Format(_T(" 0x%08x,\n"), rgb_color);
}
else
{
out.Format(_T(" 0x%08x\n"), rgb_color);
}
FileWrite(out);
}
out.Format(_T("};\n\n"));
FileWrite(out);
}
////////////////////////////////////////////////////////////////////////////////////////////////
CString resource_gen::UpperDisplayName()
{
CString upper_name = m_project->mDisplays[m_display].name;
upper_name.MakeUpper();
return upper_name;
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteFontDefines(void)
{
int font_id;
int active_theme = m_project->mDisplays[m_display].active_theme;
WriteComment("Font ID definitions");
CString out;
CString upper_name;
BOOL gen_system_font_ids = FALSE;
if (project_lib_version() < GX_VERSION_RESOURCE_ID_GENERATE_FIX)
{
gen_system_font_ids = TRUE;
}
for (font_id = 0; font_id < m_project->CountResources(m_display, RES_TYPE_FONT); font_id++)
{
res_info *info = m_project->FindResource(m_display, active_theme, RES_TYPE_FONT, font_id);
if (info && (!info->output_file_enabled || !info->binary_mode))
{
CString upper_name(info->name);
upper_name.MakeUpper();
if (info->is_default)
{
if ((m_display == 0) && gen_system_font_ids)
{
out.Format(_T("#define GX_FONT_ID_%s %d\n"), upper_name, font_id);
FileWrite(out);
}
}
else
{
if (m_num_displays > 1)
{
out.Format(_T("#define GX_FONT_ID_%s_%s %d\n"), UpperDisplayName(), upper_name, font_id);
}
else
{
out.Format(_T("#define GX_FONT_ID_%s %d\n"), upper_name, font_id);
}
FileWrite(out);
}
}
}
out.Format(_T("#define %s_FONT_TABLE_SIZE %d\n"),
UpperDisplayName(), m_font_table_size);
FileWrite(out);
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteFontData(void)
{
int font_id;
mUsingDefault8BitFont = FALSE;
mUsingDefault4BitFont = FALSE;
mUsingDefaultMonoFont = FALSE;
CCommandInfo *pCmdInfo = GetCmdInfo();
BOOL enabled;
for (int theme = 0; theme < m_project->mDisplays[m_display].num_themes; theme++)
{
m_ThemeName = m_project->mDisplays[m_display].themes[theme].theme_name;
if (pCmdInfo->IsNoGui())
{
enabled = pCmdInfo->IsThemeEnabled(m_ThemeName);
}
else
{
enabled = m_project->mDisplays[m_display].themes[theme].gen_font_table;
}
if (!enabled) continue;
for (font_id = 0; font_id < m_project->CountResources(m_display, RES_TYPE_FONT); font_id++)
{
res_info *info = m_project->FindResource(m_display, theme, RES_TYPE_FONT, font_id);
CString out;
if (info)
{
INT rotation_angle = m_project->mDisplays[m_display].rotation_angle;
if (info->is_default &&
info->pathinfo.pathname.IsEmpty() &&
!IsRotatedResourceSupported(m_project, m_display))
{
switch (info->font_bits)
{
case 8:
mUsingDefault8BitFont = TRUE;
break;
case 4:
mUsingDefault4BitFont = TRUE;
break;
case 1:
mUsingDefaultMonoFont = TRUE;
break;
}
}
else
{
if (FindResourceReferenceTheme(info, theme) == -1)
{
if ((!info->pathinfo.pathname.IsEmpty()) ||
(rotation_angle != 0))
{
if (info->output_file_enabled)
{
if (info->binary_mode)
{
if (!mp_bin_generater)
{
mp_bin_generater = new binary_resource_gen(m_project, BINARY_FILE_FORMAT_BIN_STANDALONE);
mp_bin_generater->SetDisplay(m_display);
mp_bin_generater->InitResource();
}
if (!mp_bin_generater->SetOutFile(info->output_file, info->binary_mode))
{
return;
}
mp_bin_generater->WriteFontBlock(info, font_id, theme);
continue;
}
if (!SetOutFile(info->output_file))
{
return;
}
}
out.Format(_T("\n/* Font %s_%s Data Definition */\n\n"), m_ThemeName.MakeUpper(), info->name);
FileWrite(out);
WriteFont(info, theme, font_id);
if (info->output_file_enabled)
{
m_outfile = outfile_list.GetAt(0);
}
}
}
}
}
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteFontTable(void)
{
int font_id;
WriteComment("Font Table");
CString out;
CString name;
if (mUsingDefault8BitFont)
{
out = CString("\nextern GX_CONST GX_FONT _gx_system_font_8bpp;\n");
FileWrite(out);
}
if (mUsingDefault4BitFont)
{
if (IsDave2dFontFormat(m_project, m_display))
{
if (m_project->mHeader.target_cpu == CPU_SYNERGY)
{
out = CString("\nextern GX_CONST GX_FONT _gx_synergy_system_font_4bpp;\n");
}
else
{
out = CString("\nextern GX_CONST GX_FONT _gx_dave2d_system_font_4bpp;\n");
}
}
else
{
out = CString("\nextern GX_CONST GX_FONT _gx_system_font_4bpp;\n");
}
FileWrite(out);
}
if (mUsingDefaultMonoFont)
{
if (IsDave2dFontFormat(m_project, m_display))
{
if (m_project->mHeader.target_cpu == CPU_SYNERGY)
{
out = CString("\nextern GX_CONST GX_FONT _gx_synergy_system_font_mono;\n");
}
else
{
out = CString("\nextern GX_CONST GX_FONT _gx_dave2d_system_font_mono;\n");
}
}
else
{
out = CString("\nextern GX_CONST GX_FONT _gx_system_font_mono;\n");
}
FileWrite(out);
}
CCommandInfo* pCmdInfo = GetCmdInfo();
BOOL enabled;
int end_id = m_project->CountResources(m_display, RES_TYPE_FONT);
res_info *info;
CString theme_name;
int reference_theme;
/* Extern fonts that defined in custom output files. */
for (int theme = 0; theme < m_project->mDisplays[m_display].num_themes; theme++)
{
m_ThemeName = m_project->mDisplays[m_display].themes[theme].theme_name;
if (pCmdInfo->IsNoGui())
{
enabled = pCmdInfo->IsThemeEnabled(m_ThemeName);
}
else
{
enabled = m_project->mDisplays[m_display].themes[theme].gen_font_table;
}
if (!enabled) continue;
for (font_id = 0; font_id < end_id; font_id++)
{
info = m_project->FindResource(m_display, theme, RES_TYPE_FONT, font_id);
if (IsResEnabled(info) && (info->output_file_enabled) && (!info->binary_mode))
{
theme_name = m_ThemeName;
reference_theme = FindResourceReferenceTheme(info, theme);
if (reference_theme >= 0)
{
theme_name = m_project->mDisplays[m_display].themes[reference_theme].theme_name;
}
out.Format(_T("extern GX_CONST GX_FONT %s_%s;\n"), theme_name.MakeUpper(), info->name);
FileWrite(out);
}
}
}
for (int theme = 0; theme < m_project->mDisplays[m_display].num_themes; theme++)
{
m_ThemeName = m_project->mDisplays[m_display].themes[theme].theme_name;
if (pCmdInfo->IsNoGui())
{
enabled = pCmdInfo->IsThemeEnabled(m_ThemeName);
}
else
{
enabled = m_project->mDisplays[m_display].themes[theme].gen_font_table;
}
if (!enabled) continue;
name = m_project->mDisplays[m_display].name;
name += "_";
name += m_project->mDisplays[m_display].themes[theme].theme_name;
out.Format(_T("GX_CONST GX_FONT *%s_font_table[] =\n{\n"), name);
FileWrite(out);
BOOL bFirstFont = TRUE;
for(font_id = 0; font_id < end_id; font_id++)
{
info = m_project->FindResource(m_display, theme, RES_TYPE_FONT, font_id);
if (info && (!info->output_file_enabled || !info->binary_mode))
{
if (info->is_default &&
info->pathinfo.pathname.IsEmpty() &&
(!IsRotatedResourceSupported(m_project, m_display)))
{
switch (info->font_bits)
{
case 8:
name = "_gx_system_font_8bpp";
break;
case 4:
if (IsDave2dFontFormat(m_project, m_display))
{
if (m_project->mHeader.target_cpu == CPU_SYNERGY)
{
name = "_gx_synergy_system_font_4bpp";
}
else
{
name = "_gx_dave2d_system_font_4bpp";
}
}
else
{
name = "_gx_system_font_4bpp";
}
break;
case 1:
if (IsDave2dFontFormat(m_project, m_display))
{
if (m_project->mHeader.target_cpu == CPU_SYNERGY)
{
name = "_gx_synergy_system_font_mono";
}
else
{
name = "_gx_dave2d_system_font_mono";
}
}
else
{
name = "_gx_system_font_mono";
}
break;
}
}
else
{
theme_name = m_ThemeName;
reference_theme = FindResourceReferenceTheme(info, theme);
if (reference_theme >= 0)
{
theme_name = m_project->mDisplays[m_display].themes[reference_theme].theme_name;
}
name.Format(_T("%s_%s"), theme_name.MakeUpper(), info->name);
}
if (bFirstFont)
{
out.Format(_T(" &%s"), name);
bFirstFont = FALSE;
}
else
{
out.Format(_T(",\n &%s"), name);
}
FileWrite(out);
}
}
out.Format(_T("\n};\n"));
FileWrite(out);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WritePixelmapDefines(void)
{
int pixelmap_id;
int output_pixelmap_id = 1;
int active_theme = m_project->mDisplays[m_display].active_theme;
WriteComment("Pixelmap ID definitions");
CString out;
BOOL gen_system_pixelmap_ids = FALSE;
if (project_lib_version() < GX_VERSION_RESOURCE_ID_GENERATE_FIX)
{
gen_system_pixelmap_ids = TRUE;
}
res_info *info;
int frame_id;
CString upper;
for (pixelmap_id = 1; pixelmap_id < m_pixelmap_dictionary.GetCount(); pixelmap_id++)
{
info = m_project->FindResource(m_display, active_theme, RES_TYPE_PIXELMAP, m_pixelmap_dictionary.GetAt(pixelmap_id));
if (!info)
{
continue;
}
if (IsResEnabled(info) || IsSystemPixelmap(pixelmap_id))
{
for (frame_id = 0; frame_id < info->GetPixelmapFrameCount(); frame_id++)
{
if (!info->output_file_enabled || !info->binary_mode)
{
// Generate pixlemap definitions for pixelmaps that are statically defined.
upper = MakePixelmapName(info, frame_id);
upper.MakeUpper();
if (info->is_default)
{
if ((m_display == 0) && gen_system_pixelmap_ids)
{
out.Format(_T("#define GX_PIXELMAP_ID_%s %d\n"), upper, output_pixelmap_id);
FileWrite(out);
}
}
else
{
if (m_num_displays > 1)
{
out.Format(_T("#define GX_PIXELMAP_ID_%s_%s %d\n"), UpperDisplayName(), upper, output_pixelmap_id);
}
else
{
out.Format(_T("#define GX_PIXELMAP_ID_%s %d\n"), upper, output_pixelmap_id);
}
FileWrite(out);
}
output_pixelmap_id++;
}
}
}
}
out.Format(_T("#define %s_PIXELMAP_TABLE_SIZE %d\n"),
UpperDisplayName(), m_pixelmap_table_size);
FileWrite(out);
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WritePixelmapData(void)
{
BOOL cpu_synergy = FALSE;
res_info *info;
CCommandInfo *pCmdInfo = GetCmdInfo();
BOOL enabled;
WriteComment("Pixelmap data definitions");
for (int theme = 0; theme < m_project->mDisplays[m_display].num_themes; theme++)
{
m_ThemeName = m_project->mDisplays[m_display].themes[theme].theme_name;
if (pCmdInfo->IsNoGui())
{
enabled = pCmdInfo->IsThemeEnabled(m_ThemeName);
}
else
{
enabled = m_project->mDisplays[m_display].themes[theme].gen_pixelmap_table;
}
if (!enabled) continue;
for (int index = 1; index < m_pixelmap_dictionary.GetCount(); index++)
{
info = m_project->FindResource(m_display, theme, RES_TYPE_PIXELMAP, m_pixelmap_dictionary.GetAt(index));
if (!info)
{
continue;
}
mPrivatePaletteWritten = FALSE;
if (info->GetPixelmapFrameCount() && IsResEnabled(info) && (FindResourceReferenceTheme(info, theme) == -1))
{
for (int frame_id = 0; frame_id < info->GetPixelmapFrameCount(); frame_id++)
{
m_map = info->GetPixelmap(frame_id);
if (!m_map)
{
continue;
}
if (info->output_file_enabled)
{
//Output pixelmap to the specified file
if (info->binary_mode)
{
if (!mp_bin_generater)
{
mp_bin_generater = new binary_resource_gen(m_project, BINARY_FILE_FORMAT_BIN_STANDALONE);
mp_bin_generater->SetDisplay(m_display);
mp_bin_generater->InitResource();
}
if (!mp_bin_generater->SetOutFile(info->output_file, info->binary_mode))
{
return;
}
mp_bin_generater->WritePixelmapBlock(info, 0, 0, theme, frame_id);
continue;
}
if (!SetOutFile(info->output_file))
{
return;
}
}
if (info->raw)
{
// special case of raw format, just write it and return:
WriteRawPixelmap(info, frame_id);
}
else
{
if (IsRenesasDave2D(m_project))
{
// force convert the 16 bit with alpha formats to 32 bit argb for Dave2D
// this should be removed once we only allow compatible formats
if (m_map->gx_pixelmap_format == GX_COLOR_FORMAT_565RGB &&
(m_map->gx_pixelmap_flags & GX_PIXELMAP_ALPHA) &&
(info->output_color_format != GX_COLOR_FORMAT_32ARGB) &&
(info->output_color_format != GX_COLOR_FORMAT_4444ARGB) &&
(info->output_color_format != GX_COLOR_FORMAT_4444BGRA))
{
// If this is 16 bit pixelmap with alpha, convert to 32 bit argb format for Dave2D
info->output_color_format = GX_COLOR_FORMAT_32ARGB;
}
}
WritePixelmapData(info, theme, frame_id);
}
if (info->output_file_enabled)
{
m_outfile = outfile_list.GetAt(0);
}
}
}
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WritePixelmapTable(void)
{
res_info *info;
CString out;
CCommandInfo *pCmdInfo = GetCmdInfo();
BOOL enabled;
int pixelmap_id;
int frame_id;
CString name;
WriteComment("Pixelmap Table");
/* Extern pixelmaps that defined in custom output files. */
for (int theme = 0; theme < m_project->mDisplays[m_display].num_themes; theme++)
{
m_ThemeName = m_project->mDisplays[m_display].themes[theme].theme_name;
if (pCmdInfo->IsNoGui())
{
enabled = pCmdInfo->IsThemeEnabled(m_ThemeName);
}
else
{
enabled = m_project->mDisplays[m_display].themes[theme].gen_pixelmap_table;
}
if (!enabled) continue;
for (pixelmap_id = 1; pixelmap_id < m_pixelmap_dictionary.GetCount(); pixelmap_id++)
{
info = m_project->FindResource(m_display, theme, RES_TYPE_PIXELMAP, m_pixelmap_dictionary.GetAt(pixelmap_id));
if (IsResEnabled(info) && (info->output_file_enabled) && (!info->binary_mode))
{
CString theme_name = m_ThemeName;
int reference_theme = FindResourceReferenceTheme(info, theme);
if (reference_theme >= 0)
{
theme_name = m_project->mDisplays[m_display].themes[reference_theme].theme_name;
}
for (frame_id = 0; frame_id < info->GetPixelmapFrameCount(); frame_id++)
{
name = MakePixelmapName(info, frame_id);
out.Format(_T("extern GX_CONST GX_PIXELMAP %s_%s_%s_pixelmap;\n"), UpperDisplayName(), theme_name.MakeUpper(), name);
FileWrite(out);
}
}
}
}
FileWrite(CString("\n"));
/* Write pixelmap table. */
for (int theme = 0; theme < m_project->mDisplays[m_display].num_themes; theme++)
{
m_ThemeName = m_project->mDisplays[m_display].themes[theme].theme_name;
if (pCmdInfo->IsNoGui())
{
enabled = pCmdInfo->IsThemeEnabled(m_ThemeName);
}
else
{
enabled = m_project->mDisplays[m_display].themes[theme].gen_pixelmap_table;
}
if (!enabled) continue;
CString name = m_project->mDisplays[m_display].name;
name += "_";
name += m_project->mDisplays[m_display].themes[theme].theme_name;
out.Format(_T("GX_CONST GX_PIXELMAP *%s_pixelmap_table[] =\n{\n GX_NULL"), name);
FileWrite(out);
for (pixelmap_id = 1; pixelmap_id < m_pixelmap_dictionary.GetCount(); pixelmap_id++)
{
info = m_project->FindResource(m_display, theme, RES_TYPE_PIXELMAP, m_pixelmap_dictionary.GetAt(pixelmap_id));
if (IsResEnabled(info))
{
CString theme_name = m_ThemeName;
int reference_theme = FindResourceReferenceTheme(info, theme);
if (reference_theme >= 0)
{
theme_name = m_project->mDisplays[m_display].themes[reference_theme].theme_name;
}
for (frame_id = 0; frame_id < info->GetPixelmapFrameCount(); frame_id++)
{
name = MakePixelmapName(info, frame_id);
if (!info->output_file_enabled || !info->binary_mode)
{
out.Format(_T(",\n &%s_%s_%s_pixelmap"), UpperDisplayName(), theme_name.MakeUpper(), name);
FileWrite(out);
}
}
}
else if (IsSystemPixelmap(pixelmap_id))
{
out.Format(_T(",\n GX_NULL"));
FileWrite(out);
}
}
out.Format(_T("\n};\n"));
FileWrite(out);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteStringDefines(void)
{
CString out;
int string_id;
string_table *pTable = m_project->mDisplays[m_display].stable;
CString display_name = UpperDisplayName();
display_name += "_";
CArray<widget_info*>* info_list;
widget_info* info;
int reference_count;
int output_id = 1;
if (pTable && pTable->CountStrings() > 0)
{
WriteComment("String Ids");
for (string_id = 1; string_id < pTable->CountStrings(); string_id++)
{
CString IdName = pTable->GetResourceIdName(string_id);
if (IdName.IsEmpty())
{
continue;
}
info_list = pTable->GetMLViewReferenceWidgetInfoList(IdName);
if (info_list)
{
reference_count = info_list->GetCount();
}
else
{
reference_count = 1;
}
info = NULL;
for (int index = 0; index < reference_count; index++)
{
if (info_list)
{
info = info_list->GetAt(index);
IdName = pTable->GetResourceIdName(string_id, info);
}
if (m_num_displays > 1)
{
out.Format(_T("#define GX_STRING_ID_%s %d\n"), CString(display_name + IdName), output_id);
}
else
{
out.Format(_T("#define GX_STRING_ID_%s %d\n"), CString(IdName), output_id);
}
output_id++;
FileWrite(out);
}
}
out.Format(_T("#define %s_STRING_TABLE_SIZE %d\n"),
UpperDisplayName(), pTable->CountGeneratedStrings());
FileWrite(out);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteStringData(void)
{
CString out;
int string_id = 1;
int num_strings;
int language = 0;
CString LanguageName;
CString display_name;
string_table *pTable = m_project->mDisplays[m_display].stable;
if (!pTable)
{
return;
}
num_strings = pTable->CountStrings();
if (num_strings > 0)
{
WriteComment("String values");
display_name = m_project->mDisplays[m_display].name;
/* Pickup command info class instance. */
CCommandInfo *pCmdInfo = GetCmdInfo();
BOOL enabled;
for (int language = 0; language < m_project->mHeader.num_languages; language++)
{
LanguageName = m_project->mHeader.languages[language].name;
if (pCmdInfo->IsNoGui())
{
enabled = pCmdInfo->IsLanguageEnabled(LanguageName);
}
else
{
enabled = m_project->mDisplays[m_display].gen_string_table[language];
}
if (!enabled) continue;
/* Include string data of enabled languages. */
for (string_id = 1; string_id < num_strings; string_id++)
{
WriteOneStringData(display_name, language, string_id);
}
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
CString resource_gen::RichTextResIdName2ResId(studiox_project* project, int display, CString &val)
{
CString out("");
CString tag;
CString id_name;
CString id_prefix;
CString id_val_string;
int res_type;
int res_id;
int index = 0;
while (1)
{
// Find tag start flag
index = val.Find('<');
if (index >= 0)
{
out.Append(val.Left(index + 1));
val = val.Mid(index + 1);
index = val.Find(_T(" "));
if (index >= 0)
{
// Get tag
tag = val.Left(index);
if (tag == "f")
{
res_type = RES_TYPE_FONT;
id_prefix = "GX_FONT_ID_";
}
else if ((tag == "c") || (tag == "hc"))
{
res_type = RES_TYPE_COLOR;
id_prefix = "GX_COLOR_ID_";
}
else
{
continue;
}
out.Append(val.Left(index + 1));
val = val.Mid(index + 1);
index = val.Find(_T(">"));
if (index >= 0)
{
// Get resource id name
id_name = val.Left(index);
if (id_name.Find(id_prefix) == 0)
{
id_name = id_name.Mid(id_prefix.GetLength());
res_id = project->GetResourceId(display, res_type, id_name);
if (res_id)
{
val = val.Mid(index + 1);
id_val_string.Format(_T("%d>"), res_id);
out += id_val_string;
}
}
}
}
}
else
{
out.Append(val);
break;
}
}
return out;
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::MakeUtf8String(studiox_project* project, CString val, int language_index, GX_STRING *out_string, int display, BOOL gen, widget_info *info)
{
val = RichTextResIdName2ResId(project, display, val);
// The maximun UTF8 character is 6 bytes, calculate the maximun utf8 buffer size needed for the string.
int max_length = val.GetLength() * 6 + 1;
GX_STRING string;
GX_STRING normalized_text;
string.gx_string_ptr = new char[max_length];
strcpy_s((char *)string.gx_string_ptr, max_length, CT2A(val.GetString(), CP_UTF8));
string.gx_string_length = strnlen_s(string.gx_string_ptr, max_length);
if (gx_studio_canonical_normalize((GX_CONST GX_STRING *)&string, &normalized_text) == GX_SUCCESS)
{
delete string.gx_string_ptr;
string = normalized_text;
}
if (project->mHeader.languages[language_index].support_bidi_text &&
project->mHeader.languages[language_index].gen_reordered_bidi_text && gen)
{
GX_STRING reordered_bidi_text;
MakeReorderedBidiText(&string, &reordered_bidi_text, display, info);
delete string.gx_string_ptr;
string = reordered_bidi_text;
}
if (project->mHeader.languages[language_index].support_thai_glyph_shaping &&
(!gen || project->mHeader.languages[language_index].gen_adjusted_thai_string))
{
GX_STRING adjusted_thai_string;
MakeAdjustedThaiString(&string, &adjusted_thai_string);
if (adjusted_thai_string.gx_string_ptr)
{
delete string.gx_string_ptr;
string = adjusted_thai_string;
}
}
*out_string = string;
}
////////////////////////////////////////////////////////////////////////////////////////////////
bool resource_gen::GetMlTextDisplayInfo(widget_info *info, int* font_id, GX_VALUE* display_width)
{
if (info && (info->basetype == GX_TYPE_MULTI_LINE_TEXT_VIEW))
{
// Calculate display width
GX_WIDGET widget;
GX_RECTANGLE client;
INT width;
widget.gx_widget_style = info->style;
widget.gx_widget_size = info->size;
gx_widget_client_get(&widget, -1, &client);
width = client.gx_rectangle_right - client.gx_rectangle_left + 1;
width = width - (info->ewi.text_info.whitespace << 1) - 3;
// Retrieve font
*font_id = info->font_id[NORMAL_FONT_INDEX];
widget_info *child = info->GetChildWidgetInfo();
while (child)
{
if (child->basetype == GX_TYPE_VERTICAL_SCROLL)
{
width -= (child->size.gx_rectangle_right - child->size.gx_rectangle_left + 1);
break;
}
child = child->GetNextWidgetInfo();
}
*display_width = (GX_VALUE)width;
return TRUE;
}
return FALSE;
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::MakeReorderedBidiText(GX_STRING *utf8str, GX_STRING *out_string, int display, widget_info *info)
{
//generate bidi text in display order
GX_BIDI_TEXT_INFO input_info;
GX_BIDI_RESOLVED_TEXT_INFO *resolved_info;
char *reordered_bidi_text = GX_NULL;
UINT reordered_index = 0;
GX_VALUE display_width;
int font_id;
memset(&input_info, 0, sizeof(GX_BIDI_TEXT_INFO));
if (GetMlTextDisplayInfo(info, &font_id, &display_width))
{
studiox_project* project = GetOpenProject();
res_info* info = project->FindResource(display, 0, RES_TYPE_FONT, font_id);
if (info)
{
input_info.gx_bidi_text_info_display_width = display_width;
input_info.gx_bidi_text_info_font = info->font;
}
}
input_info.gx_bidi_text_info_text = *utf8str;
if (_gx_utility_bidi_paragraph_reorder(&input_info, &resolved_info) == GX_SUCCESS)
{
int buffer_size = 0;
UINT index;
GX_BIDI_RESOLVED_TEXT_INFO* next = resolved_info;
GX_STRING* line_string;
// Calculate buffer size needed for loading the reordered bidi text.
while (next)
{
for (index = 0; index < next->gx_bidi_resolved_text_info_total_lines; index++)
{
if (next->gx_bidi_resolved_text_info_text)
{
buffer_size += next->gx_bidi_resolved_text_info_text[index].gx_string_length;
}
buffer_size++;
}
next = next->gx_bidi_resolved_text_info_next;
}
buffer_size++;
reordered_bidi_text = new char[buffer_size];
next = resolved_info;
GX_BOOL insert_line_break = GX_FALSE;
// Copy reordered bidi text to the buffer.
while (next)
{
for (index = 0; index < next->gx_bidi_resolved_text_info_total_lines; index++)
{
if (next->gx_bidi_resolved_text_info_text)
{
line_string = &next->gx_bidi_resolved_text_info_text[index];
memcpy_s(reordered_bidi_text + reordered_index, buffer_size - reordered_index, line_string->gx_string_ptr, line_string->gx_string_length);
reordered_index += line_string->gx_string_length;
}
if ((index < next->gx_bidi_resolved_text_info_total_lines - 1) ||
(next->gx_bidi_resolved_text_info_next))
{
reordered_bidi_text[reordered_index++] = GX_KEY_CARRIAGE_RETURN;
}
}
next = next->gx_bidi_resolved_text_info_next;
}
reordered_bidi_text[reordered_index] = '\0';
_gx_utility_bidi_resolved_text_info_delete(&resolved_info);
}
out_string->gx_string_ptr = reordered_bidi_text;
out_string->gx_string_length = reordered_index;
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::MakeAdjustedThaiString(GX_STRING *utf8str, GX_STRING *out_string)
{
ULONG *code_list;
UINT code_count;
UINT index;
GX_CHAR *adjusted_string;
UINT count;
UINT glyph_len;
out_string->gx_string_ptr = GX_NULL;
out_string->gx_string_length = 0;
if (_gx_utility_thai_glyph_shaping(utf8str, &code_list, &code_count) == GX_SUCCESS)
{
adjusted_string = new GX_CHAR[code_count * 6 + 1];
count = 0;
for (index = 0; index < code_count; index++)
{
_gx_utility_unicode_to_utf8(code_list[index], (GX_UBYTE *)(adjusted_string + count), &glyph_len);
count += glyph_len;
}
_gx_system_memory_free(code_list);
adjusted_string[count] = '\0';
out_string->gx_string_ptr = adjusted_string;
out_string->gx_string_length = count;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteOneStringData(CString &display_name, int language_index, int string_id)
{
CString out;
GX_STRING utf8str;
GX_CONST GX_CHAR *data;
unsigned char byte;
BOOL HasMultiByte = FALSE;
string_table* pTable = m_project->mDisplays[m_display].stable;
CString id_name = pTable->GetResourceIdName(string_id);
if (id_name.IsEmpty())
{
return;
}
CString val = pTable->GetString(id_name, language_index);
if (val.IsEmpty())
{
return;
}
CArray<widget_info*> *info_list = pTable->GetMLViewReferenceWidgetInfoList(id_name);
int reference_count = 1;
if (info_list)
{
reference_count = info_list->GetCount();
}
widget_info *info = NULL;
for (int index = 0; index < reference_count; index++)
{
if (info_list)
{
info = info_list->GetAt(index);
id_name = pTable->GetResourceIdName(string_id, info);
}
MakeUtf8String(m_project, val, language_index, &utf8str, m_display, TRUE, info);
data = utf8str.gx_string_ptr;
while (*data)
{
byte = *data++;
if (byte & 0x80)
{
HasMultiByte = TRUE;
break;
}
}
CString language_name = m_project->mHeader.languages[language_index].name;
language_name.Replace(' ', '_');
if (HasMultiByte)
{
out.Format(_T("GX_CONST GX_UBYTE %s_%s_%s[] = {"), display_name, id_name, language_name);
FileWrite(out);
data = utf8str.gx_string_ptr;
while (*data)
{
byte = *data++;
out.Format(_T("0x%02x, "), byte);
FileWrite(out);
}
FileWrite(CString("0x00};\n"));
}
else
{
val = utf8str.gx_string_ptr;
val.Replace(_T("\\"), _T("\\\\"));
val.Replace(_T("\""), _T("\\\""));
val.Replace(_T("\'"), _T("\\\'"));
val.Replace(_T("\n"), _T("\\n"));
val.Replace(_T("\r"), _T("\\r"));
out.Format(_T("GX_CONST GX_UBYTE %s_%s_%s[] = \"%s\";\n"), display_name, id_name, language_name, val);
FileWrite(out);
}
delete utf8str.gx_string_ptr;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteStringTable(void)
{
CString out;
int string_id = 1;
int num_strings;
int language = 0;
CString LanguageName;
CString display_name;
CString val;
string_table *pTable = m_project->mDisplays[m_display].stable;
if (!pTable)
{
return;
}
num_strings = pTable->CountStrings();
if (num_strings > 0)
{
display_name = m_project->mDisplays[m_display].name;
/* Pickup command info class instance. */
CCommandInfo *pCmdInfo = GetCmdInfo();
BOOL enabled;
INT language_count = 0;
for (int language = 0; language < m_project->mHeader.num_languages; language++)
{
LanguageName = m_project->mHeader.languages[language].name;
if (pCmdInfo->IsNoGui())
{
enabled = pCmdInfo->IsLanguageEnabled(LanguageName);
}
else
{
enabled = m_project->mDisplays[m_display].gen_string_table[language];
}
if (!enabled) continue;
out.Format(_T("\n/* String Table for %s language %s */\n\n"), display_name, LanguageName);
FileWrite(out);
LanguageName.Replace(' ', '_');
if(project_lib_version() >= GX_VERSION_STRING_LENGTH_FIX)
{
WriteOneStringTableExt(display_name, LanguageName, language, pTable, num_strings);
}
else
{
WriteOneStringTable(display_name, LanguageName, language, pTable, num_strings);
}
/* Output string table of enabled languages. */
language_count++;
}
// now write the language table
WriteComment(" Language Table ");
if (language_count)
{
if (project_lib_version() >= GX_VERSION_STRING_LENGTH_FIX)
{
WriteLanguageTableExt(display_name, language_count);
}
else
{
WriteLanguageTable(display_name, language_count);
}
if (string_table::TestGenerateLanguageDirectionTable())
{
WriteComment(" Language Direction Table ");
WriteLanguageDirectionTable(display_name, language_count);
}
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteLanguageTable(CString display_name, INT language_count)
{
CString out;
CString LanguageName;
CCommandInfo* pCmdInfo = GetCmdInfo();
BOOL enabled;
out.Format(_T("\nGX_CONST GX_UBYTE **%s_language_table[%d] = \n{\n"), m_project->mDisplays[m_display].name, language_count);
FileWrite(out);
for (int language = 0; language < m_project->mHeader.num_languages; language++)
{
LanguageName = m_project->mHeader.languages[language].name;
if (pCmdInfo->IsNoGui())
{
enabled = pCmdInfo->IsLanguageEnabled(LanguageName);
}
else
{
enabled = m_project->mDisplays[m_display].gen_string_table[language];
}
if (!enabled) continue;
/* Output language table with enabled string tables. */
LanguageName.Replace(' ', '_');
out.Format(_T(" %s_%s_string_table,\n"), display_name, LanguageName);
FileWrite(out);
}
FileWrite(CString("};\n"));
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteLanguageTableExt(CString display_name, INT language_count)
{
CString out;
CString LanguageName;
CCommandInfo* pCmdInfo = GetCmdInfo();
BOOL enabled;
out.Format(_T("\nGX_CONST GX_STRING *%s_language_table[%d] = \n{\n"), m_project->mDisplays[m_display].name, language_count);
FileWrite(out);
for (int language = 0; language < m_project->mHeader.num_languages; language++)
{
LanguageName = m_project->mHeader.languages[language].name;
if (pCmdInfo->IsNoGui())
{
enabled = pCmdInfo->IsLanguageEnabled(LanguageName);
}
else
{
enabled = m_project->mDisplays[m_display].gen_string_table[language];
}
if (!enabled) continue;
/* Output language table with enabled string tables. */
LanguageName.Replace(' ', '_');
out.Format(_T(" %s_%s_string_table,\n"), display_name, LanguageName);
FileWrite(out);
}
FileWrite(CString("};\n"));
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteLanguageDirectionTable(CString display_name, INT language_count)
{
CString out;
out.Format(_T("\nGX_CONST GX_UBYTE %s_language_direction_table[%d] = \n{\n"), m_project->mDisplays[m_display].name, language_count);
FileWrite(out);
for (int language = 0; language < m_project->mHeader.num_languages; language++)
{
if (string_table::IsRight2LeftLanguage(language))
{
out = L" GX_LANGUAGE_DIRECTION_RTL";
}
else
{
out = L" GX_LANGUAGE_DIRECTION_LTR";
}
FileWrite(out);
if (language == m_project->mHeader.num_languages - 1)
{
out = L"\n";
}
else
{
out = L",\n";
}
FileWrite(out);
}
FileWrite(CString("};\n"));
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteOneStringTable(CString &display_name, CString &language_name, int language_index,
string_table* string_table, int num_strings)
{
CString out;
CString val;
int string_id;
CString id_name;
out.Format(_T("GX_CONST GX_UBYTE *%s_%s_string_table[%d] =\n{\n GX_NULL,\n"),
display_name, language_name, num_strings);
FileWrite(out);
for (string_id = 1; string_id < num_strings; string_id++)
{
id_name = string_table->GetResourceIdName(string_id);
if (id_name.IsEmpty())
{
continue;
}
val = string_table->GetString(id_name, language_index);
if (val.IsEmpty())
{
if (string_id < num_strings - 1)
{
out.Format(_T(" GX_NULL,\n"));
}
else
{
out.Format(_T(" GX_NULL\n"));
}
}
else
{
if (string_id < num_strings - 1)
{
out.Format(_T(" %s_%s_%s,\n"), display_name, id_name, language_name);
}
else
{
out.Format(_T(" %s_%s_%s\n"), display_name, id_name, language_name);
}
}
FileWrite(out);
}
out.Format(_T("\n};\n"));
FileWrite(out);
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteOneStringTableExt(CString &display_name, CString &language_name, int language_index,
string_table* string_table, int num_strings)
{
CString out;
CString val;
int string_id;
CString id_name;
out.Format(_T("GX_CONST GX_STRING %s_%s_string_table[%d] =\n{\n {GX_NULL, 0},\n"),
display_name, language_name, string_table->CountGeneratedStrings());
FileWrite(out);
CArray<widget_info *> *info_list;
int reference_count;
widget_info *info;
for (string_id = 1; string_id < num_strings; string_id++)
{
id_name = string_table->GetResourceIdName(string_id);
if (id_name.IsEmpty())
{
continue;
}
val = string_table->GetString(id_name, language_index);
info_list = string_table->GetMLViewReferenceWidgetInfoList(id_name);
info = NULL;
reference_count = 1;
if (info_list)
{
reference_count = info_list->GetCount();
}
for (int index = 0; index < reference_count; index++)
{
if (info_list)
{
info = info_list->GetAt(index);
id_name = string_table->GetResourceIdName(string_id, info);
}
if (val.IsEmpty())
{
if (string_id < num_strings - 1)
{
out.Format(_T(" {GX_NULL, 0},\n"));
}
else
{
out.Format(_T(" {GX_NULL, 0}\n"));
}
}
else
{
if (string_id < num_strings - 1)
{
out.Format(_T(" {(GX_CONST GX_CHAR *)%s_%s_%s, sizeof(%s_%s_%s) - 1},\n"),
display_name, id_name, language_name,
display_name, id_name, language_name);
}
else
{
out.Format(_T(" {(GX_CONST GX_CHAR *)%s_%s_%s, sizeof(%s_%s_%s) - 1}\n"),
display_name, id_name, language_name,
display_name, id_name, language_name);
}
}
FileWrite(out);
}
}
out.Format(_T("};\n"));
FileWrite(out);
}
void resource_gen::WriteScrollbarAppearance(GX_SCROLLBAR_APPEARANCE &appear)
{
CString out;
if (project_lib_version() >= 50302)
{
out.Format(_T("")
_T(" {\n")
_T(" %d, /* scroll width */\n")
_T(" %d, /* thumb width */\n")
_T(" %d, /* thumb travel min */\n")
_T(" %d, /* thumb travel max */\n")
_T(" %d, /* thumb border style */\n")
_T(" %s, /* scroll fill pixelmap */\n")
_T(" %s, /* scroll thumb pixelmap */\n")
_T(" %s, /* scroll up pixelmap */\n")
_T(" %s, /* scroll down pixelmap */\n")
_T(" %s, /* scroll thumb color */\n")
_T(" %s, /* scroll thumb border color */\n")
_T(" %s, /* scroll button color */\n")
_T(" },\n"),
appear.gx_scroll_width,
appear.gx_scroll_thumb_width,
appear.gx_scroll_thumb_travel_min,
appear.gx_scroll_thumb_travel_max,
appear.gx_scroll_thumb_border_style,
screen_generator::GetPixelmapIdName(m_project, m_display, appear.gx_scroll_fill_pixelmap),
screen_generator::GetPixelmapIdName(m_project, m_display, appear.gx_scroll_thumb_pixelmap),
screen_generator::GetPixelmapIdName(m_project, m_display, appear.gx_scroll_up_pixelmap),
screen_generator::GetPixelmapIdName(m_project, m_display, appear.gx_scroll_down_pixelmap),
screen_generator::GetColorIdName(m_project, m_display, appear.gx_scroll_thumb_color),
screen_generator::GetColorIdName(m_project, m_display, appear.gx_scroll_thumb_border_color),
screen_generator::GetColorIdName(m_project, m_display, appear.gx_scroll_button_color));
}
else
{
out.Format(_T("")
_T(" {\n")
_T(" %d, /* scroll width */\n")
_T(" %d, /* thumb width */\n")
_T(" %d, /* thumb travel min */\n")
_T(" %d, /* thumb travel max */\n")
_T(" %s, /* scroll fill pixelmap */\n")
_T(" %s, /* scroll thumb pixelmap */\n")
_T(" %s, /* scroll up pixelmap */\n")
_T(" %s, /* scroll down pixelmap */\n")
_T(" %s, /* scroll fill color */\n")
_T(" %s, /* scroll button color */\n")
_T(" },\n"),
appear.gx_scroll_width,
appear.gx_scroll_thumb_width,
appear.gx_scroll_thumb_travel_min,
appear.gx_scroll_thumb_travel_max,
screen_generator::GetPixelmapIdName(m_project, m_display, appear.gx_scroll_fill_pixelmap),
screen_generator::GetPixelmapIdName(m_project, m_display, appear.gx_scroll_thumb_pixelmap),
screen_generator::GetPixelmapIdName(m_project, m_display, appear.gx_scroll_up_pixelmap),
screen_generator::GetPixelmapIdName(m_project, m_display, appear.gx_scroll_down_pixelmap),
_T("GX_COLOR_ID_SCROLL_FILL"),
screen_generator::GetColorIdName(m_project, m_display, appear.gx_scroll_button_color));
}
FileWrite(out);
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteThemes(void)
{
int theme;
int theme_count = 0;
CString out;
CString name;
BOOL enabled;
CString color_table_name("GX_NULL");
CString font_table_name("GX_NULL");
CString pixelmap_table_name("GX_NULL");
CCommandInfo *pCmdInfo = GetCmdInfo();
for (theme = 0; theme < m_project->mDisplays[m_display].num_themes; theme++)
{
if (pCmdInfo->IsNoGui())
{
enabled = pCmdInfo->IsThemeEnabled(m_project->mDisplays[m_display].themes[theme].theme_name);
}
else
{
enabled = m_project->mDisplays[m_display].themes[theme].enabled;
}
if (!enabled) continue;
theme_count++;
name = m_project->mDisplays[m_display].name;
name += "_";
name += m_project->mDisplays[m_display].themes[theme].theme_name;
if (m_project->mDisplays[m_display].themes[theme].gen_color_table || pCmdInfo->IsNoGui())
{
color_table_name.Format(_T("%s_color_table"), name);
}
if (m_project->mDisplays[m_display].themes[theme].gen_font_table || pCmdInfo->IsNoGui())
{
font_table_name.Format(_T("%s_font_table"), name);
}
if (m_project->mDisplays[m_display].themes[theme].gen_pixelmap_table || pCmdInfo->IsNoGui())
{
pixelmap_table_name.Format(_T("%s_pixelmap_table"), name);
}
out.Format(_T("\nGX_THEME %s =\n")
_T("{\n")
_T(" (GX_COLOR *) %s,\n")
_T(" (GX_FONT **) %s,\n")
_T(" (GX_PIXELMAP **) %s,\n"),
name, color_table_name, font_table_name, pixelmap_table_name);
FileWrite(out);
if (m_project->mDisplays[m_display].colorformat == GX_COLOR_FORMAT_8BIT_PALETTE &&
m_project->mDisplays[m_display].themes[theme].palette != NULL)
{
out.Format(_T(" (GX_COLOR *) %s_palette,\n"), name);
}
else
{
out.Format(_T(" NULL,\n"));
}
FileWrite(out);
WriteScrollbarAppearance(m_project->mDisplays[m_display].themes[theme].VScrollAppearance);
WriteScrollbarAppearance(m_project->mDisplays[m_display].themes[theme].HScrollAppearance);
out.Empty();
screen_generator::AddScrollbarStyles(m_project->mDisplays[m_display].themes[theme].VScrollStyle, out);
out.TrimLeft('|');
out = CString(_T(" ")) + out + _T(",\n");
FileWrite(out);
out.Empty();
screen_generator::AddScrollbarStyles(m_project->mDisplays[m_display].themes[theme].HScrollStyle, out);
out.TrimLeft('|');
out = CString(_T(" ")) + out + _T(",\n");
FileWrite(out);
out.Format(_T(" %d, /* color table size */\n"), m_color_table_size);
FileWrite(out);
out.Format(_T(" %d, /* font table size */\n"), m_font_table_size);
FileWrite(out);
out.Format(_T(" %d, /* pixelmap table size */\n"), m_pixelmap_table_size);
FileWrite(out);
if (m_project->mDisplays[m_display].colorformat == GX_COLOR_FORMAT_8BIT_PALETTE &&
m_project->mDisplays[m_display].themes[theme].palette != NULL)
{
/* Only 8bit palette size is wanted to be generated.
4bpp driver contains palette table. But it is just used inside Studio.*/
out.Format(_T(" %d /* palette size */\n"), m_project->mDisplays[m_display].themes[theme].palette_total_size);
}
else
{
out.Format(_T(" %d /* palette size */\n"), 0);
}
FileWrite(out);
FileWrite(CString("\n};\n"));
}
if (theme_count)
{
out.Format(_T("GX_CONST GX_THEME *%s_theme_table[%d] =\n{\n"),
m_project->mDisplays[m_display].name,
theme_count);
FileWrite(out);
INT count = 0;
for (theme = 0; theme < m_project->mDisplays[m_display].num_themes; theme++)
{
if (pCmdInfo->IsNoGui())
{
enabled = pCmdInfo->IsThemeEnabled(m_project->mDisplays[m_display].themes[theme].theme_name);
}
else
{
enabled = m_project->mDisplays[m_display].themes[theme].enabled;
}
if (!enabled) continue;
count++;
name = m_project->mDisplays[m_display].name;
name += "_";
name += m_project->mDisplays[m_display].themes[theme].theme_name;
if (count < theme_count)
{
out.Format(_T(" &%s,\n"), name);
}
else
{
out.Format(_T(" &%s\n"), name);
}
FileWrite(out);
}
FileWrite(CString("};\n\n"));
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
GX_FONT *resource_gen::GetPageHead(res_info* info, int theme_id, int font_id)
{
GX_FONT* head_page = NULL;
if (!info->pathinfo.pathname.IsEmpty())
{
head_page = m_optimized_fonts[theme_id].GetAt(font_id);
if (!head_page)
{
/* KGM Make the font again, with optimization, and write out the optimized version */
/* Don't forget to delete the temporary font */
head_page = MakeOptimizedFont(info, m_display, m_warn_on_error);
if (head_page)
{
m_optimized_fonts[theme_id].SetAt(font_id, head_page);
}
else
{
// Only generate error once.
m_warn_on_error = FALSE;
}
}
}
else
{
// Rotation angle is set, need to rotate default system font.
switch (info->font_bits)
{
case 8:
head_page = &_gx_system_font_8bpp;
break;
case 4:
if (IsDave2dFontFormat(m_project, m_display))
{
head_page = &_gx_dave2d_system_font_4bpp;
}
else
{
head_page = &_gx_system_font_4bpp;
}
break;
case 1:
if (IsDave2dFontFormat(m_project, m_display))
{
head_page = &_gx_dave2d_system_font_mono;
}
else
{
head_page = &_gx_system_font_mono;
}
break;
default:
// Do nothing.
break;
}
}
return head_page;
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteFont(res_info *info, int theme_id, int font_id)
{
int pagecount = 1;
int pageindex;
GX_FONT *head_page = GetPageHead(info, theme_id, font_id);
BOOL IsLast = TRUE;
if (!head_page)
{
CString msg;
msg.Format(_T("Unable to create font: %s using pathname: %s"), info->name, info->pathinfo.pathname);
ErrorMsg(msg);
return;
}
// write the pages out in reverse order, so that we can link them together without
// first declaring them.
const GX_FONT *font_page = head_page;
while(font_page->gx_font_next_page)
{
font_page = font_page->gx_font_next_page;
pagecount++;
}
CString name;
while(pagecount)
{
font_page = head_page;
for (pageindex = 1; pageindex < pagecount; pageindex++)
{
font_page = font_page->gx_font_next_page;
}
name.Format(_T("%s_%s"), m_ThemeName.MakeUpper(), info->name);
WriteFontPage(font_page, name, pagecount, IsLast, info->output_file_enabled);
pagecount--;
IsLast = FALSE;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteKerningTable(GX_UBYTE *kerning_table, CString &name, GX_CHAR_CODE charval)
{
GX_UBYTE *data;
CString out;
CString val;
BOOL written = TRUE;
int table_size;
GX_UBYTE pair_counts = *kerning_table;
/* Add pair counts and kerning value size. */
table_size = sizeof(GX_UBYTE) + pair_counts * (sizeof(GX_CHAR) + sizeof(GX_UBYTE));
/* Write kerning table */
out.Format(_T("static GX_CONST GX_UBYTE FONT_%s_char_%2x_kerning_table[%u] =\n{\n"), name, charval, table_size);
FileWrite(out);
out = CString(" ");
data = kerning_table;
for (int i = 0; i < table_size; i++)
{
val.Format(_T("0x%02x"), *data);
out += val;
if (i != (table_size - 1))
{
out += ", ";
}
written = CheckLineFeed(out);
data++;
}
if (!written)
{
FileWrite(out);
}
out = CString("\n};\n");
FileWrite(out);
}
////////////////////////////////////////////////////////////////////////////////////////////////
GX_UBYTE *resource_gen::Rotate8bitGlyphData(GX_CONST GX_UBYTE* map, INT width, INT height)
{
int rotated_width = height;
int rotated_height = width;
int data_size = rotated_width * rotated_height;
int putsign;
if (!data_size)
{
return NULL;
}
GX_UBYTE* data = new GX_UBYTE[data_size];
GX_UBYTE* putrow = data;
GX_UBYTE* put;
GX_CONST GX_UBYTE* get = map;
if (m_project->mDisplays[m_display].rotation_angle == GX_SCREEN_ROTATION_CW)
{
/* Write row from top to bottom to colum from left to right. */
putrow += (rotated_height - 1) * rotated_width;
putsign = 1;
}
else
{
// CCW
putrow += (rotated_width - 1);
putsign = -1;
}
for (int h = 0; h < height; h++)
{
put = putrow;
for (int w = 0; w < width; w++)
{
*put = *get;
get++;
put -= rotated_width * putsign;
}
putrow += putsign;
}
return data;
}
////////////////////////////////////////////////////////////////////////////////////////////////
GX_UBYTE* resource_gen::Rotate4bitGlyphData(GX_CONST GX_UBYTE* map, INT width, INT height)
{
int datasize;
int rotated_width = height;
int rotated_height = width;
GX_UBYTE* data;
GX_UBYTE* putrow;
GX_UBYTE* put;
int putstride;
int putsign;
GX_CONST GX_UBYTE* getrow;
GX_CONST GX_UBYTE* get;
int getstride;
GX_UBYTE pixel;
putstride = GetRowPitch(rotated_width, 4);
datasize = putstride * rotated_height;
data = new GX_UBYTE[datasize];
putrow = data;
getstride = GetRowPitch(width, 4);
getrow = map;
if (m_project->mDisplays[m_display].rotation_angle == GX_SCREEN_ROTATION_CW)
{
/* Write row from top to bottom to colum from left to right. */
putrow += (rotated_height - 1) * putstride;
putsign = 1;
}
else
{
getrow += (height - 1) * getstride;
putsign = -1;
}
for (int h = 0; h < height; h++)
{
put = putrow;
get = getrow;
for (int w = 0; w < width; w++)
{
if (w & 1)
{
if (IsDave2dFontFormat(m_project, m_display))
{
pixel = (*get) & 0xf0;
}
else
{
pixel = ((*get) << 4);
}
get++;
}
else
{
if (IsDave2dFontFormat(m_project, m_display))
{
pixel = ((*get) << 4);
}
else
{
pixel = (*get) & 0xf0;
}
}
if (h & 1)
{
if (IsDave2dFontFormat(m_project, m_display))
{
*put |= pixel;
}
else
{
*put |= (pixel >> 4);
}
}
else
{
if (IsDave2dFontFormat(m_project, m_display))
{
*put = (pixel >> 4);
}
else
{
*put = pixel;
}
}
put -= putstride * putsign;
}
getrow += getstride * putsign;
if (h & 1)
{
putrow++;
}
}
return data;
}
////////////////////////////////////////////////////////////////////////////////////////////////
GX_UBYTE* resource_gen::Rotate1bitGlyphData(GX_CONST GX_UBYTE* map, INT width, INT height)
{
int datasize;
int rotated_width = height;
int rotated_height = width;
GX_UBYTE* data;
GX_UBYTE* putrow;
GX_UBYTE* put;
int putstride;
int putsign;
GX_UBYTE putmask;
GX_CONST GX_UBYTE* getrow;
GX_CONST GX_UBYTE* get;
int getstride;
GX_UBYTE getmask;
GX_UBYTE pixel;
putstride = GetRowPitch(rotated_width, 1);
datasize = putstride * rotated_height;
data = new GX_UBYTE[datasize];
memset(data, 0, datasize);
putrow = data;
getstride = GetRowPitch(width, 1);
getrow = map;
if (m_project->mDisplays[m_display].rotation_angle == GX_SCREEN_ROTATION_CW)
{
putrow += (rotated_height - 1) * putstride;
putsign = 1;
}
else
{
// CCW
getrow += (height - 1) * getstride;
putsign = -1;
}
if (IsDave2dFontFormat(m_project, m_display))
{
putmask = 0x01;
/* Write row from top to bottom to colum from left to right. */
for (int h = 0; h < height; h++)
{
put = putrow;
get = getrow;
getmask = 0x01;
for (int w = 0; w < width; w++)
{
pixel = *get;
if (pixel & getmask)
{
*put |= putmask;
}
if (getmask == 0x80)
{
getmask = 0x01;
get++;
}
else
{
getmask <<= 1;
}
put -= putstride * putsign;
}
getrow += getstride * putsign;
if (putmask == 0x80)
{
putmask = 0x01;
putrow++;
}
else
{
putmask <<= 1;
}
}
}
else
{
putmask = 0x80;
/* Write row from top to bottom to colum from left to right. */
for (int h = 0; h < height; h++)
{
put = putrow;
get = getrow;
getmask = 0x80;
for (int w = 0; w < width; w++)
{
pixel = *get;
if (pixel & getmask)
{
*put |= putmask;
}
if (getmask == 0x01)
{
getmask = 0x80;
get++;
}
else
{
getmask >>= 1;
}
put -= putstride * putsign;
}
getrow += getstride * putsign;
if (putmask == 0x01)
{
putmask = 0x80;
putrow++;
}
else
{
putmask >>= 1;
}
}
}
return data;
}
////////////////////////////////////////////////////////////////////////////////////////////////
VOID resource_gen::RotateGlyphData(GX_CONST GX_GLYPH* glyph, GX_UBYTE font_format, GX_UBYTE** rotated_map, INT* rotated_map_size)
{
GX_UBYTE* rotated_data = GX_NULL;
GX_UBYTE* decoded_data = GX_NULL;
GX_CONST GX_UBYTE* input_data;
if ((font_format & GX_FONT_FORMAT_COMPRESSED) &&
(((GX_COMPRESSED_GLYPH*)glyph)->gx_glyph_map_size & 0x8000))
{
decoded_data = RleDecodeGlyphData((GX_COMPRESSED_GLYPH*)glyph, GetFontBits(font_format));
input_data = decoded_data;
}
else
{
input_data = glyph->gx_glyph_map;
}
if (input_data)
{
switch (font_format & GX_FONT_FORMAT_BPP_MASK)
{
case GX_FONT_FORMAT_8BPP:
rotated_data = Rotate8bitGlyphData(input_data, glyph->gx_glyph_width, glyph->gx_glyph_height);
break;
case GX_FONT_FORMAT_4BPP:
rotated_data = Rotate4bitGlyphData(input_data, glyph->gx_glyph_width, glyph->gx_glyph_height);
break;
case GX_FONT_FORMAT_1BPP:
rotated_data = Rotate1bitGlyphData(input_data, glyph->gx_glyph_width, glyph->gx_glyph_height);
break;
}
}
if ((font_format & GX_FONT_FORMAT_COMPRESSED) && rotated_data)
{
if (decoded_data)
{
delete decoded_data;
}
GX_COMPRESSED_GLYPH cglyph;
cglyph.gx_glyph_map = rotated_data;
cglyph.gx_glyph_width = glyph->gx_glyph_height;
cglyph.gx_glyph_height = glyph->gx_glyph_width;
RleEncodeGlyphData(&cglyph, GetFontBits(font_format));
*rotated_map = (GX_UBYTE*)cglyph.gx_glyph_map;
*rotated_map_size = cglyph.gx_glyph_map_size;
}
else
{
*rotated_map = rotated_data;
*rotated_map_size = 0;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteFontPage(const GX_FONT *font, CString &name, int page, BOOL lastpage, BOOL custom_file_enabled)
{
GX_CHAR_CODE charval;
GX_CHAR_CODE index;
const GX_GLYPH *glyph;
const UCHAR *data;
UCHAR* rotated_data = NULL;
CString out;
CString val;
CString link;
int datasize;
int bytes_written = 0;
int max_ascent = 0;
int max_descent = 0;
int max_height = 0;
int guix_version = m_project->mHeader.guix_version;
int* mapsize_list = GX_NULL;
int mapsize;
if (!font)
{
return;
}
if (IsRotatedResourceSupported(m_project, m_display))
{
mapsize_list = new int[font->gx_font_last_glyph - font->gx_font_first_glyph + 1];
}
for (charval = font->gx_font_first_glyph; charval <= font->gx_font_last_glyph; charval++ )
{
index = charval - font->gx_font_first_glyph;
if (font->gx_font_format & GX_FONT_FORMAT_COMPRESSED)
{
glyph = (GX_GLYPH *)&font->gx_font_glyphs.gx_font_compressed_glyphs[index];
}
else if (font->gx_font_format & GX_FONT_FORMAT_KERNING)
{
glyph = (GX_GLYPH *)&font->gx_font_glyphs.gx_font_kerning_glyphs[index];
}
else
{
glyph = &font->gx_font_glyphs.gx_font_normal_glyphs[index];
}
if (IsRotatedResourceSupported(m_project, m_display))
{
RotateGlyphData(glyph, font->gx_font_format, &rotated_data, &mapsize);
if (font->gx_font_format & GX_FONT_FORMAT_COMPRESSED)
{
datasize = mapsize & 0x7fff;
}
else
{
datasize = GetRowPitch(glyph->gx_glyph_height, GetFontBits(font->gx_font_format));
datasize *= glyph->gx_glyph_width;
mapsize = datasize;
}
mapsize_list[index] = mapsize;
}
else
{
if (font->gx_font_format & GX_FONT_FORMAT_COMPRESSED)
{
datasize = ((GX_COMPRESSED_GLYPH*)glyph)->gx_glyph_map_size & 0x7fff;
}
else
{
datasize = GetRowPitch(glyph->gx_glyph_width, GetFontBits(font->gx_font_format));
datasize *= glyph->gx_glyph_height;
}
}
if (!datasize)
{
continue;
}
out.Format(_T("static GX_CONST GX_UBYTE FONT_%s_char_%2x[%u] =\n{\n"), name, charval, datasize);
FileWrite(out);
bytes_written = 0;
data = glyph->gx_glyph_map;
out = CString(" ");
BOOL written = TRUE;
if (rotated_data)
{
data = rotated_data;
}
else
{
data = glyph->gx_glyph_map;
}
for (int i = 0; i < datasize; i++)
{
val.Format(_T("0x%02x"), *data);
out += val;
if (i != (datasize - 1))
{
out += ", ";
}
written = CheckLineFeed(out);
data++;
}
if (rotated_data)
{
delete rotated_data;
}
if (!written)
{
FileWrite(out);
}
out = CString("\n};\n");
FileWrite(out);
/* Write glyph kerning table after it's map data. */
if (font->gx_font_format & GX_FONT_FORMAT_KERNING)
{
GX_CONST GX_KERNING_GLYPH *kerning_glyph = &font->gx_font_glyphs.gx_font_kerning_glyphs[index];
if (kerning_glyph -> gx_kerning_table)
{
WriteKerningTable(const_cast<GX_UBYTE *>(kerning_glyph->gx_kerning_table), name, charval);
}
}
}
/* Print out the font table */
CString struct_name;
CString glyph_cast_type = _T("");
if (font->gx_font_format & GX_FONT_FORMAT_COMPRESSED)
{
struct_name = _T("GX_COMPRESSED_GLYPH");
glyph_cast_type = _T("(GX_CONST GX_GLYPH *)");
}
else if (font->gx_font_format & GX_FONT_FORMAT_KERNING)
{
struct_name = _T("GX_KERNING_GLYPH");
glyph_cast_type = _T("(GX_CONST GX_GLYPH *)");
}
else
{
struct_name = _T("GX_GLYPH");
}
/* Write warning text on purpose. */
if (font->gx_font_format & GX_FONT_FORMAT_KERNING)
{
out.Format(_T("#ifndef GX_FONT_KERNING_SUPPORT\n#error GX_FONT_KERNING_SUPPORT should be defined if \'Generate Kerning Info\' is selected in font edit dialog.\n#endif\n"));
FileWrite(out);
}
out.Format(_T("static GX_CONST %s %s_FONT_PAGE_%d_GLYPHS[%u] =\n{\n"),
struct_name, name, page, (font->gx_font_last_glyph - font->gx_font_first_glyph + 1));
FileWrite(out);
for (charval = font->gx_font_first_glyph; charval <= font->gx_font_last_glyph; charval++ )
{
index = charval - font->gx_font_first_glyph;
CString kerning_table_name(_T("0"));
if (font->gx_font_format & GX_FONT_FORMAT_COMPRESSED)
{
glyph = (GX_GLYPH *)&font->gx_font_glyphs.gx_font_compressed_glyphs[index];
}
else if (font->gx_font_format & GX_FONT_FORMAT_KERNING)
{
glyph = (GX_GLYPH *)&font->gx_font_glyphs.gx_font_kerning_glyphs[index];
if (((GX_KERNING_GLYPH *)glyph)->gx_kerning_table)
{
kerning_table_name.Format(_T("FONT_%s_char_%2x_kerning_table"), name, charval);
}
}
else
{
glyph = &font->gx_font_glyphs.gx_font_normal_glyphs[index];
}
if (mapsize_list)
{
mapsize = mapsize_list[index];
datasize = mapsize & 0x7fff;
}
else
{
if (font->gx_font_format & GX_FONT_FORMAT_COMPRESSED)
{
mapsize = ((GX_COMPRESSED_GLYPH*)glyph)->gx_glyph_map_size;
datasize = mapsize & 0x7fff;
}
else
{
datasize = GetRowPitch(glyph->gx_glyph_width, GetFontBits(font->gx_font_format));
datasize *= glyph->gx_glyph_height;
}
}
if (!datasize)
{
out.Format(_T(" {GX_NULL, "));
}
else
{
out.Format(_T(" {FONT_%s_char_%2x, "), name, charval);
}
FileWrite(out);
if (guix_version < 50207)
{
//Generate old format for older libraries
out.Format(_T("%d, %d, %d, %d, %u, %u}"),
glyph->gx_glyph_ascent,
glyph->gx_glyph_descent,
glyph->gx_glyph_advance,
glyph->gx_glyph_leading,
glyph->gx_glyph_width,
glyph->gx_glyph_height);
}
else if (guix_version < 50303)
{
//Generate new format for library version 5.2.6 or greater
if (font->gx_font_format & GX_FONT_FORMAT_COMPRESSED)
{
datasize = mapsize;
}
out.Format(_T("%d, %d, %d, %d, %d, %u, %u}"),
datasize,
glyph->gx_glyph_ascent,
glyph->gx_glyph_descent,
glyph->gx_glyph_advance,
glyph->gx_glyph_leading,
glyph->gx_glyph_width,
glyph->gx_glyph_height);
}
else
{
//Generate new format for library version 5.3.3 or greater
if (font->gx_font_format & GX_FONT_FORMAT_COMPRESSED)
{
out.Format(_T("%d, %d, %d, %d, %u, %u, %d}"),
glyph->gx_glyph_ascent,
glyph->gx_glyph_descent,
glyph->gx_glyph_advance,
glyph->gx_glyph_leading,
glyph->gx_glyph_width,
glyph->gx_glyph_height,
mapsize);
}
else if (font->gx_font_format & GX_FONT_FORMAT_KERNING)
{
out.Format(_T("%d, %d, %d, %d, %u, %u, %s}"),
glyph->gx_glyph_ascent,
glyph->gx_glyph_descent,
glyph->gx_glyph_advance,
glyph->gx_glyph_leading,
glyph->gx_glyph_width,
glyph->gx_glyph_height,
kerning_table_name);
}
else
{
out.Format(_T("%d, %d, %d, %d, %u, %u}"),
glyph->gx_glyph_ascent,
glyph->gx_glyph_descent,
glyph->gx_glyph_advance,
glyph->gx_glyph_leading,
glyph->gx_glyph_width,
glyph->gx_glyph_height);
}
}
FileWrite(out);
if(charval != font->gx_font_last_glyph)
{
FileWrite(CString(",\n"));
}
else
{
FileWrite(CString("\n};\n\n"));
}
}
if (mapsize_list)
{
delete mapsize_list;
mapsize_list = NULL;
}
/* Print the GX_FONT */
if (page > 1)
{
out.Format(_T("static GX_CONST GX_FONT %s_PAGE_%d =\n"), name, page);
}
else
{
if (custom_file_enabled)
{
out.Format(_T("GX_CONST GX_FONT %s = \n"), name);
}
else
{
out.Format(_T("static GX_CONST GX_FONT %s = \n"), name);
}
}
CString font_format(_T(""));
switch (font->gx_font_format & GX_FONT_FORMAT_BPP_MASK)
{
case GX_FONT_FORMAT_1BPP:
font_format += "GX_FONT_FORMAT_1BPP";
break;
case GX_FONT_FORMAT_2BPP:
font_format += "GX_FONT_FORMAT_2BPP";
break;
case GX_FONT_FORMAT_4BPP:
font_format += "GX_FONT_FORMAT_4BPP";
break;
case GX_FONT_FORMAT_8BPP:
font_format += "GX_FONT_FORMAT_8BPP";
break;
}
if (font->gx_font_format & GX_FONT_FORMAT_COMPRESSED)
{
font_format += "|GX_FONT_FORMAT_COMPRESSED";
}
if (font->gx_font_format & GX_FONT_FORMAT_FREETYPE)
{
font_format += "|GX_FONT_FORMAT_FREETYPE";
}
if (guix_version >= 50402)
{
// font kerning suppot was not added until release 5.4.2
if (font->gx_font_format & GX_FONT_FORMAT_KERNING)
{
font_format += "|GX_FONT_FORMAT_KERNING";
}
}
if (guix_version >= 50500)
{
// support for this style flag was not added until release 5.5.0
if (font->gx_font_format & GX_FONT_FORMAT_REVERSED_ORDER)
{
font_format += "|GX_FONT_FORMAT_REVERSED_ORDER";
}
}
if (IsRotatedResourceSupported(m_project, m_display))
{
switch (m_project->mDisplays[m_display].rotation_angle)
{
case GX_SCREEN_ROTATION_CW:
font_format += "|GX_FONT_FORMAT_ROTATED_90";
break;
case GX_SCREEN_ROTATION_CCW:
font_format += "|GX_FONT_FORMAT_ROTATED_270";
break;
}
}
if (guix_version <= 50402)
{
link.Format(_T("{\n")
_T(" %s, /* format */\n")
_T(" 0, /* line pre-space */\n")
_T(" 0, /* line post-space */ \n")
_T(" %u, /* font data height */\n")
_T(" %u, /* font baseline offset */\n")
_T(" 0x%x, /* first glyph within data page */\n")
_T(" 0x%x, /* last glyph within data page */\n")
_T(" %s%s_FONT_PAGE_%d_GLYPHS, /* pointer to glyph data */\n"),
font_format,
font->gx_font_line_height,
font->gx_font_baseline,
font->gx_font_first_glyph,
font->gx_font_last_glyph,
glyph_cast_type, name, page);
}
else
{
link.Format(_T("{\n")
_T(" %s, /* format */\n")
_T(" 0, /* line pre-space */\n")
_T(" 0, /* line post-space */ \n")
_T(" %u, /* font data height */\n")
_T(" %u, /* font baseline offset */\n")
_T(" 0x%x, /* first glyph within data page */\n")
_T(" 0x%x, /* last glyph within data page */\n")
_T(" {%s%s_FONT_PAGE_%d_GLYPHS}, /* pointer to glyph data */\n"),
font_format,
font->gx_font_line_height,
font->gx_font_baseline,
font->gx_font_first_glyph,
font->gx_font_last_glyph,
glyph_cast_type, name, page);
}
out += link;
if (lastpage)
{
out += " GX_NULL /* next font page */\n";
}
else
{
link.Format(_T(" &%s_PAGE_%d /* next font page */\n"), name, page + 1);
out += link;
}
out += "};\n\n";
FileWrite(out);
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WritePixelmapStructure(res_info *pixinfo, int frame_id)
{
CString out;
/* Now write out the main structure. */
CString name = MakePixelmapName(pixinfo, frame_id);
out.Format(_T("GX_CONST GX_PIXELMAP %s_%s_%s_pixelmap =\n{\n"), UpperDisplayName(), m_ThemeName.MakeUpper(), name);
FileWrite(out);
out.Format(_T(" 0x%08x, /* major version */\n"), GX_CONVERT_VER);
FileWrite(out);
out.Format(_T(" 0x%08x, /* minor version */\n"), GX_CONVERT_SUBVER);
FileWrite(out);
BOOL orFlag = FALSE;
out = CString(" ");
if(m_map->gx_pixelmap_flags & GX_PIXELMAP_COMPRESSED)
{
out += "GX_PIXELMAP_COMPRESSED";
orFlag = TRUE;
}
if(m_map->gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
{
if (orFlag)
{
out += '|';
}
out += "GX_PIXELMAP_ALPHA";
orFlag = TRUE;
}
if(m_map->gx_pixelmap_flags & GX_PIXELMAP_TRANSPARENT)
{
if (orFlag)
{
out += '|';
}
out += "GX_PIXELMAP_TRANSPARENT";
orFlag = TRUE;
}
if(m_map -> gx_pixelmap_flags & GX_PIXELMAP_RAW_FORMAT)
{
if (orFlag)
{
out += '|';
}
out += "GX_PIXELMAP_RAW_FORMAT";
orFlag = TRUE;
}
if (IsRotatedResourceSupported(m_project, m_display))
{
switch (m_project->mDisplays[m_display].rotation_angle)
{
case GX_SCREEN_ROTATION_CW:
if (orFlag)
{
out += '|';
}
if (m_project->mHeader.guix_version >= GX_VERSION_PIXELMAP_ROTATION_FLAGS_FIX)
{
out += "GX_PIXELMAP_ROTATED_CW";
}
else
{
out += "GX_PIXELMAP_ROTATED_90";
}
orFlag = TRUE;
break;
case GX_SCREEN_ROTATION_CCW:
if (orFlag)
{
out += '|';
}
if (m_project->mHeader.guix_version >= GX_VERSION_PIXELMAP_ROTATION_FLAGS_FIX)
{
out += "GX_PIXELMAP_ROTATED_CCW";
}
else
{
out += "GX_PIXELMAP_ROTATED_270";
}
orFlag = TRUE;
break;
}
}
if(!orFlag)
{
out += "0, /* flags*/\n";
}
else
{
out += ", /* flags*/\n";
}
FileWrite(out);
out.Format(_T(" %s, /* Format */\n"), GetColorFormatName(m_map->gx_pixelmap_format));
FileWrite(out);
out.Format(_T(" (GX_UBYTE *) %s_%s_%s_pixelmap_data,\n"), UpperDisplayName(), m_ThemeName.MakeUpper(), name);
FileWrite(out);
out.Format(_T(" sizeof(%s_%s_%s_pixelmap_data), /* the size of pixelmap_data*/\n"), UpperDisplayName(), m_ThemeName.MakeUpper(), name);
FileWrite(out);
if(m_map -> gx_pixelmap_aux_data_size)
{
if (m_map->gx_pixelmap_format == GX_COLOR_FORMAT_8BIT_PALETTE)
{
if (pixinfo->palette_type == PALETTE_TYPE_PRIVATE)
{
out.Format(_T(" (GX_UBYTE *) %s_%s_palette,\n"),
m_project->mDisplays[m_display].name, pixinfo->name);
FileWrite(out);
out.Format(_T(" sizeof(%s_%s_palette), /* the size of pixelmap_data*/\n"),
m_project->mDisplays[m_display].name, pixinfo->name);
}
else
{
out.Format(_T(" (GX_UBYTE *) %s_shared_palette,\n"),
m_project->mDisplays[m_display].name);
FileWrite(out);
out.Format(_T(" sizeof(%s_shared_palette), /* the size of pixelmap_data*/\n"),
m_project->mDisplays[m_display].name);
}
}
else
{
out.Format(_T(" (GX_UBYTE *) %s_%s_%s_pixelmap_aux_data,\n"),
UpperDisplayName(), m_ThemeName.MakeUpper(), name);
FileWrite(out);
out.Format(_T(" sizeof(%s_%s_%s_pixelmap_aux_data), /* the size of pixelmap_data*/\n"),
UpperDisplayName(), m_ThemeName.MakeUpper(), name);
}
}
else
{
out.Format(_T(" NULL,\n"));
FileWrite(out);
out.Format(_T(" 0, /* auxiliary data size*/\n"));
}
FileWrite(out);
out.Format(_T(" 0x%02x, /* used for transparent iamges*/\n"), m_map->gx_pixelmap_transparent_color);
FileWrite(out);
out.Format(_T(" %u, /* width in pixel*/\n"), m_map->gx_pixelmap_width); // height
FileWrite(out);
out.Format(_T(" %u /* height in pixel*/\n"), m_map->gx_pixelmap_height);
FileWrite(out);
out.Format(_T("};\n"));
FileWrite(out);
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteRawPixelmap(res_info *pixinfo, int frame_id)
{
CString path;
CString out;
CString val;
unsigned char *data_p;
UCHAR buffer[32];
long file_size;
long total_data_size;
long total_bytes_written;
int chunk_size;
path = MakeAbsolutePathname(pixinfo->pathinfo);
FILE *file = _tfopen(path.GetBuffer(), _T("rb"));
if (!file)
{
return;
}
fseek(file, 0, SEEK_END);
file_size = ftell(file);
// calculate padded size
if (IsRenesasDave2D(m_project) || IS_RZ_TARGET)
{
total_data_size = (file_size | 0x07) + 1;
}
else
{
total_data_size = file_size;
}
fseek(file, 0, SEEK_SET);
out.Format(_T("\n/* %s_%s pixelmap data */\n\n"), m_ThemeName.MakeUpper(), pixinfo->name);
FileWrite(out);
// force 8 byte alignment for Dave2D target
if (IsRenesasDave2D(m_project) || IS_RZ_TARGET)
{
out.Format(_T("#ifdef WIN32\nstatic GX_CONST GX_UBYTE %s_%s_%s_pixelmap_data[%d] =\n#else\n"),
UpperDisplayName(), m_ThemeName.MakeUpper(), pixinfo->name, total_data_size);
switch(m_project->mHeader.target_tools)
{
case TOOLS_GNU:
FileWrite(out);
out.Format(_T("static GX_CONST GX_UBYTE %s_%s_%s_pixelmap_data[%d] __attribute__((aligned(8))) ="),
UpperDisplayName(), m_ThemeName.MakeUpper(), pixinfo->name, total_data_size);
out += "\n#endif\n{\n";
break;
case TOOLS_IAR:
FileWrite(out);
out.Format(_T("#pragma data_alignment=8\nstatic GX_CONST GX_UBYTE %s_%s_%s_pixelmap_data[%d] ="),
UpperDisplayName(), m_ThemeName.MakeUpper(), pixinfo->name, total_data_size);
out += "\n#endif\n{\n";
break;
default:
out.Format(_T("static GX_CONST GX_UBYTE %s_%s_%s_pixelmap_data[%d] =\n{\n"),
UpperDisplayName(), m_ThemeName.MakeUpper(), pixinfo->name, total_data_size);
break;
}
FileWrite(out);
}
else
{
out.Format(_T("static GX_CONST GX_UBYTE %s_%s_%s_pixelmap_data[%d] =\n{\n"),
UpperDisplayName(), m_ThemeName.MakeUpper(), pixinfo->name, total_data_size);
FileWrite(out);
}
total_bytes_written = 0;
while(total_bytes_written < file_size)
{
chunk_size = fread(buffer, 1, 32, file);
data_p = (unsigned char*) buffer;
out = CString(" ");
for(int i = 0; i < chunk_size; i++)
{
val.Format(_T("0x%02x"), *data_p);
out += val;
if (total_bytes_written != (total_data_size - 1))
{
out += ", ";
}
data_p++;
total_bytes_written++;
}
out += CString("\n");
FileWrite(out);
}
// add the padding
if (total_bytes_written < total_data_size)
{
out = CString(" ");
for(int i = total_bytes_written; i < total_data_size; i++)
{
val.Format(_T("0x%02x"), 0);
out += val;
if (i != (total_data_size - 1))
{
out += ", ";
}
}
out += CString("\n");
FileWrite(out);
}
out = CString("\n};\n");
FileWrite(out);
fclose(file);
// create a temp GX_PIXELMAP structure with updated fields, write the structure,
// then restore the orginal pixelmap structure pointer.
GX_PIXELMAP temp_map;
GX_PIXELMAP *old_map = m_map;
temp_map = (*old_map);
temp_map.gx_pixelmap_aux_data = GX_NULL;
temp_map.gx_pixelmap_aux_data_size = 0;
temp_map.gx_pixelmap_data_size = total_data_size;
temp_map.gx_pixelmap_flags |= GX_PIXELMAP_RAW_FORMAT;
m_map = &temp_map;
WritePixelmapStructure(pixinfo, frame_id);
}
GX_UBYTE* resource_gen::RotateUIntData(GX_CONST GX_UBYTE* data, INT width, INT height)
{
int data_size = width * height;
UINT* out_data = new UINT[data_size];
UINT* put_row = out_data;
UINT* put;
int putsign;
GX_CONST UINT* get_row = (GX_CONST UINT*)data;
GX_CONST UINT* get;
if (m_project->mDisplays[m_display].rotation_angle == GX_SCREEN_ROTATION_CW)
{
put_row += (width - 1) * height;
putsign = 1;
}
else
{
put_row += (height - 1);
putsign = -1;
}
for (int row = 0; row < height; row++)
{
get = get_row;
put = put_row;
for (int col = 0; col < width; col++)
{
*put = *get;
get++;
put -= height * putsign;
}
get_row += width;
put_row += putsign;
}
return (GX_UBYTE*)out_data;
}
GX_UBYTE* resource_gen::RotateUShortData(GX_CONST GX_UBYTE* data, INT width, INT height)
{
int data_size = width * height;
USHORT* out_data = new USHORT[data_size];
USHORT* put_row = out_data;
USHORT* put;
int putsign;
GX_CONST USHORT* get_row = (GX_CONST USHORT*)data;
GX_CONST USHORT* get;
if (m_project->mDisplays[m_display].rotation_angle == GX_SCREEN_ROTATION_CW)
{
put_row += (width - 1) * height;
putsign = 1;
}
else
{
put_row += (height - 1);
putsign = -1;
}
for (int row = 0; row < height; row++)
{
get = get_row;
put = put_row;
for (int col = 0; col < width; col++)
{
*put = *get;
get++;
put -= height * putsign;
}
get_row += width;
put_row += putsign;
}
return (GX_UBYTE*)out_data;
}
GX_UBYTE* resource_gen::RotateUCharData(GX_CONST GX_UBYTE* data, INT width, INT height)
{
int data_size = width * height;
GX_UBYTE* out_data = new GX_UBYTE[data_size];
GX_UBYTE* put_row = out_data;
GX_UBYTE* put;
int putsign;
GX_CONST GX_UBYTE* get_row = data;
GX_CONST GX_UBYTE* get;
if (m_project->mDisplays[m_display].rotation_angle == GX_SCREEN_ROTATION_CW)
{
put_row += (width - 1) * height;
putsign = 1;
}
else
{
put_row += (height - 1);
putsign = -1;
}
for (int row = 0; row < height; row++)
{
get = get_row;
put = put_row;
for (int col = 0; col < width; col++)
{
*put = *get;
get++;
put -= height * putsign;
}
get_row += width;
put_row += putsign;
}
return out_data;
}
VOID resource_gen::RotatePixelmap(GX_PIXELMAP* map)
{
GX_UBYTE* data;
GX_UBYTE* auxdata;
if (!map->gx_pixelmap_data)
{
return;
}
switch (map->gx_pixelmap_format)
{
case GX_COLOR_FORMAT_24XRGB:
case GX_COLOR_FORMAT_24BGRX:
case GX_COLOR_FORMAT_32ARGB:
case GX_COLOR_FORMAT_32RGBA:
case GX_COLOR_FORMAT_32ABGR:
case GX_COLOR_FORMAT_32BGRA:
data = RotateUIntData(map->gx_pixelmap_data, map->gx_pixelmap_width, map->gx_pixelmap_height);
break;
case GX_COLOR_FORMAT_565RGB:
case GX_COLOR_FORMAT_565BGR:
case GX_COLOR_FORMAT_4444ARGB:
case GX_COLOR_FORMAT_4444BGRA:
case GX_COLOR_FORMAT_5551BGRX:
case GX_COLOR_FORMAT_1555XRGB:
data = RotateUShortData(map->gx_pixelmap_data, map->gx_pixelmap_width, map->gx_pixelmap_height);
if (map->gx_pixelmap_aux_data)
{
auxdata = RotateUCharData(map->gx_pixelmap_aux_data, map->gx_pixelmap_width, map->gx_pixelmap_height);
delete map->gx_pixelmap_aux_data;
map->gx_pixelmap_aux_data = auxdata;
}
break;
default:
data = RotateUCharData(map->gx_pixelmap_data, map->gx_pixelmap_width, map->gx_pixelmap_height);
break;
}
delete map->gx_pixelmap_data;
map->gx_pixelmap_data = data;
GX_SWAP_VALS(map->gx_pixelmap_width, map->gx_pixelmap_height);
}
GX_PIXELMAP* resource_gen::RotatePixelmap(res_info* info, int theme_id, GX_PIXELMAP *map, int frame_id)
{
GX_PIXELMAP* rotated_map = NULL;
image_reader *pReader = NULL;
CString abspath;
IMAGE_INFO* default_image_info = NULL;
int frame_count = 1;
if (info->is_default && info->pathinfo.pathname.IsEmpty())
{
// Read image from internally linked system png data.
PIXELMAP_RECORD* record = studiox_project::GetDefaultPixelmapRecord(info->name);
if (record)
{
default_image_info = record->image_info;
pReader = image_reader::CreateProperReader(default_image_info->data, default_image_info->data_len);
}
}
else
{
abspath = MakeAbsolutePathname(info->pathinfo);
pReader = image_reader::CreateProperReader(abspath);
frame_count = image_reader::GetFrameCount(abspath);
}
if (pReader)
{
pReader->SetDither(info->dither);
if (info->keep_alpha)
{
pReader->SetSaveAlphaVal(TRUE);
}
else
{
pReader->SetSaveAlphaVal(FALSE);
}
pReader->SetOutputColorFormat(map->gx_pixelmap_format, m_project->GetDisplayColorFormat(info));
if (map->gx_pixelmap_format == GX_COLOR_FORMAT_8BIT_PALETTE)
{
switch (info->palette_type)
{
case PALETTE_TYPE_SHARED:
case PALETTE_TYPE_PRIVATE:
if (m_project->mDisplays[m_display].colorformat == GX_COLOR_FORMAT_8BIT_PALETTE)
{
theme_info *info = &m_project->mDisplays[m_display].themes[theme_id];
if (info->palette)
{
pReader->SetPalette(info->palette, info->palette_total_size, info->palette_total_size);
}
}
else
{
palette_info private_palette;
private_palette.total_size = map->gx_pixelmap_aux_data_size / sizeof(GX_COLOR);
private_palette.palette = new GX_COLOR[private_palette.total_size];
memcpy(private_palette.palette, (GX_COLOR*)map->gx_pixelmap_aux_data, map->gx_pixelmap_aux_data_size); /* Use case of memcpy is verified. */
pReader->SetPalette(private_palette.palette, private_palette.total_size, private_palette.total_size);
}
break;
default:
ErrorMsg("Internal Error: Invalid image palette type");
delete pReader;
return FALSE;
}
}
BOOL result;
if (default_image_info)
{
result = pReader->ReadImage(default_image_info->data, default_image_info->data_len);
}
else
{
result = pReader->ReadImage(abspath, frame_id);
}
if (result)
{
rotated_map = pReader->GetPixelmap();
RotatePixelmap(rotated_map);
}
if (rotated_map)
{
// now compress the image
if (info->compress)
{
int result;
pReader->DoCompress(TRUE);
if (IsRenesasDave2D(m_project))
{
result = pReader->RleEncode(rotated_map, TRUE);
}
else
{
result = pReader->RleEncode(rotated_map);
}
if (result == FALSE)
{
info->compress = FALSE;
}
}
if (m_project->mDisplays[m_display].rotation_angle == GX_SCREEN_ROTATION_CW)
{
rotated_map->gx_pixelmap_flags |= GX_PIXELMAP_ROTATED_CW;
}
else
{
rotated_map->gx_pixelmap_flags |= GX_PIXELMAP_ROTATED_CCW;
}
GX_SWAP_VALS(rotated_map->gx_pixelmap_width, rotated_map->gx_pixelmap_height);
delete pReader;
}
}
return rotated_map;
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WritePixelmapData(res_info *pixinfo, int theme_id, int frame_id)
{
// CString out;
// m_map should be intialized by caller, and might not be same image pointed to by
// info if output format does not match display format.
if (!m_map)
{
return;
}
GX_PIXELMAP* rotated_map = GX_NULL;
if (IsRotatedResourceSupported(m_project, m_display))
{
rotated_map = RotatePixelmap(pixinfo, theme_id, m_map, frame_id);
m_map = rotated_map;
}
if (m_map->gx_pixelmap_flags & GX_PIXELMAP_COMPRESSED &&
m_map->gx_pixelmap_flags & GX_PIXELMAP_TARGA)
{
if (IsRenesasDave2D(m_project) &&
(m_project->mHeader.target_tools == TOOLS_CCRX))
{
WriteCCRXCompatibleTargaStream(pixinfo, frame_id);
}
else
{
// All targa formats are just byte streams, use UCHAR
WriteUcharData(pixinfo, frame_id);
}
}
else
{
switch(m_map->gx_pixelmap_format)
{
case GX_COLOR_FORMAT_24XRGB:
case GX_COLOR_FORMAT_24BGRX:
case GX_COLOR_FORMAT_32ARGB:
case GX_COLOR_FORMAT_32RGBA:
case GX_COLOR_FORMAT_32ABGR:
case GX_COLOR_FORMAT_32BGRA:
WriteUintData(pixinfo, frame_id);
break;
case GX_COLOR_FORMAT_565RGB:
case GX_COLOR_FORMAT_565BGR:
case GX_COLOR_FORMAT_4444ARGB:
case GX_COLOR_FORMAT_4444BGRA:
case GX_COLOR_FORMAT_5551BGRX:
case GX_COLOR_FORMAT_1555XRGB:
if (m_big_endian &&
(m_map->gx_pixelmap_flags & GX_PIXELMAP_COMPRESSED) &&
(m_map->gx_pixelmap_flags & GX_PIXELMAP_ALPHA))
{
WriteBigEndianCompressedUshortData(pixinfo, frame_id);
}
else
{
WriteUshortData(pixinfo, frame_id);
}
break;
case GX_COLOR_FORMAT_8BIT_PACKED_PIXEL:
if ((m_map->gx_pixelmap_flags & GX_PIXELMAP_COMPRESSED) &&
(m_map->gx_pixelmap_flags & GX_PIXELMAP_ALPHA))
{
WriteUshortData(pixinfo, frame_id);
}
else
{
WriteUcharData(pixinfo, frame_id);
}
break;
default:
WriteUcharData(pixinfo, frame_id);
break;
}
}
if(m_map->gx_pixelmap_aux_data)
{
if (pixinfo->output_color_format == GX_COLOR_FORMAT_8BIT_PALETTE)
{
if (pixinfo->palette_type == PALETTE_TYPE_PRIVATE)
{
if (!mPrivatePaletteWritten)
{
WritePalette(m_map->gx_pixelmap_aux_data_size / 4,
(GX_COLOR*)m_map->gx_pixelmap_aux_data, pixinfo->name);
mPrivatePaletteWritten = TRUE;
}
}
else
{
if (!mDefaultPaletteWritten)
{
WritePalette(m_map->gx_pixelmap_aux_data_size / 4,
(GX_COLOR*)m_map->gx_pixelmap_aux_data, CString("shared"));
mDefaultPaletteWritten = TRUE;
}
}
}
else
{
WriteUcharAuxData(pixinfo, frame_id);
}
}
WritePixelmapStructure(pixinfo, frame_id);
if (rotated_map)
{
pixelmap_destroy(rotated_map);
}
}
#ifndef COLWIDTH
#define COLWIDTH 80
#endif
////////////////////////////////////////////////////////////////////////////////////////////////
BOOL resource_gen::CheckLineFeed(CString &out)
{
if(out.GetLength() >= COLWIDTH)
{
out += CString("\n");
FileWrite(out);
out = CString(" ");
return TRUE;
}
return FALSE;
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteUintData(res_info *info, int res_index)
{
CString out;
CString val;
unsigned int *data_p;
CString name = MakePixelmapName(info, res_index);
out.Format(_T("\n/* %s_%s pixelmap data */\n\n"), m_ThemeName.MakeUpper(), name);
FileWrite(out);
//if (!info->qualifier.IsEmpty())
//{
// out.Format("%s\n", info->qualifier);
// FileWrite(out);
//}
out.Format(_T("static GX_CONST UINT %s_%s_%s_pixelmap_data[%d] =\n{\n"),
UpperDisplayName(), m_ThemeName.MakeUpper(), name, m_map->gx_pixelmap_data_size / 4);
FileWrite(out);
out = CString(" ");
data_p = (unsigned int*) m_map->gx_pixelmap_data;
BOOL written = TRUE;
for(unsigned int i = 0; i < m_map->gx_pixelmap_data_size / 4; i++)
{
val.Format(_T("0x%08x"), *data_p);
out += val;
if (i != ((m_map->gx_pixelmap_data_size / 4) - 1))
{
out += ", ";
}
written = CheckLineFeed(out);
data_p++;
}
if (!written)
{
FileWrite(out);
}
out = CString("\n};\n");
FileWrite(out);
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteCCRXCompatibleTargaStream(res_info* info, int res_index)
{
/* Targa stream is bytes, but Dave2D requires 4 byte data alignment. CCRX doesn't
support any type of alignment pragma, so we write the byte data out as Ulongs.
*/
CString out;
CString val;
UCHAR *pData;
ULONG dataval;
unsigned int loop;
unsigned int bytes_left;
unsigned int bytes_written;
CString name = MakePixelmapName(info, res_index);
out.Format(_T("\n/* %s_%s pixelmap data */\n\n"), m_ThemeName.MakeUpper(), name);
FileWrite(out);
out.Format(_T("static GX_CONST UINT %s_%s_%s_pixelmap_data[%d] =\n{\n"),
UpperDisplayName(), m_ThemeName.MakeUpper(), name, (m_map->gx_pixelmap_data_size + 3) / 4);
FileWrite(out);
out = CString(" ");
pData = (UCHAR *) m_map->gx_pixelmap_data;
BOOL written = TRUE;
bytes_written = 0;
for (loop = 0; loop < m_map->gx_pixelmap_data_size / 4; loop++)
{
dataval = *pData++;
dataval |= (*pData++) << 8;
dataval |= (*pData++) << 16;
dataval |= (*pData++) << 24;
bytes_written += 4;
val.Format(_T("0x%08x"), dataval);
out += val;
if (bytes_written != (m_map->gx_pixelmap_data_size))
{
out += ", ";
}
written = CheckLineFeed(out);
}
bytes_left = m_map->gx_pixelmap_data_size - bytes_written;
if (bytes_left)
{
written = FALSE;
dataval = 0;
switch (bytes_left)
{
case 1:
dataval = *pData++;
break;
case 2:
dataval = *pData++;
dataval |= (*pData++) << 8;
break;
case 3:
dataval = *pData++;
dataval |= (*pData++) << 8;
dataval |= (*pData++) << 16;
break;
}
val.Format(_T("0x%08x"), dataval);
out += val;
}
if (!written)
{
FileWrite(out);
}
out = CString("\n};\n");
FileWrite(out);
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteUshortData(res_info *info, int frame_id)
{
CString out;
CString val;
unsigned short *data_p;
unsigned short data;
CString name = MakePixelmapName(info, frame_id);
out.Format(_T("\n/* %s_%s pixelmap data */\n\n"), m_ThemeName.MakeUpper(), name);
FileWrite(out);
out.Format(_T("static GX_CONST USHORT %s_%s_%s_pixelmap_data[%d] =\n{\n"),
UpperDisplayName(), m_ThemeName.MakeUpper(), name, m_map->gx_pixelmap_data_size / 2);
FileWrite(out);
out = CString(" ");
data_p = (unsigned short*) m_map -> gx_pixelmap_data;
GX_UBYTE format = m_map ->gx_pixelmap_format;
BOOL written = TRUE;
for(unsigned int i = 0; i < m_map->gx_pixelmap_data_size / 2; i++)
{
data = *data_p;
val.Format(_T("0x%04x"), data);
out += val;
if (i != ((m_map->gx_pixelmap_data_size / 2) - 1))
{
out += ", ";
}
written = CheckLineFeed(out);
data_p++;
}
if (!written)
{
FileWrite(out);
}
out = CString("\n};\n");
FileWrite(out);
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteBigEndianCompressedUshortData(res_info *info, int frame_id)
{
CString out;
CString val;
unsigned short *pShort;
unsigned char *pByte;
unsigned short data;
unsigned char bcount;
unsigned char alpha;
int pixels_to_write;
ULONG bytes_written = 0;
CString name = MakePixelmapName(info, frame_id);
out.Format(_T("\n/* %s_%s pixelmap data */\n\n"), m_ThemeName.MakeUpper(), name);
FileWrite(out);
out.Format(_T("static GX_CONST USHORT %s_%s_%s_pixelmap_data[%d] =\n{\n"),
UpperDisplayName(), m_ThemeName.MakeUpper(), name, m_map->gx_pixelmap_data_size / 2);
FileWrite(out);
out = CString(" ");
pShort = (unsigned short*) m_map -> gx_pixelmap_data;
GX_UBYTE format = m_map ->gx_pixelmap_format;
BOOL written = TRUE;
while(bytes_written < m_map->gx_pixelmap_data_size)
{
pByte = (unsigned char *) pShort;
bcount = *pByte;
if (bcount & 0x80)
{
pixels_to_write = 1;
}
else
{
pixels_to_write = bcount + 1;
}
for (int i = 0; i < pixels_to_write; i++)
{
pByte = (unsigned char *) pShort;
bcount = *pByte++;
alpha = *pByte++;
pShort++;
data = bcount;
data <<= 8;
data |= alpha;
val.Format(_T("0x%04x"), data);
out += val;
out += ", ";
data = *pShort++;
val.Format(_T("0x%04x"), data);
out += val;
bytes_written += 4;
if (bytes_written <= m_map->gx_pixelmap_data_size)
{
out += ", ";
}
written = CheckLineFeed(out);
}
}
if (!written)
{
FileWrite(out);
}
out = CString("\n};\n");
FileWrite(out);
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteUcharData(res_info *info, int frame_id)
{
CString out;
CString val;
unsigned char *data_p;
CString name = MakePixelmapName(info, frame_id);
out.Format(_T("\n/* %s_%s pixelmap data */\n\n"), m_ThemeName.MakeUpper(), name);
FileWrite(out);
if (IsRenesasDave2D(m_project))
{
out.Format(_T("#ifdef WIN32\nstatic GX_CONST GX_UBYTE %s_%s_%s_pixelmap_data[%d] =\n#else\n"),
UpperDisplayName(), m_ThemeName.MakeUpper(), name, m_map->gx_pixelmap_data_size);
switch (m_project->mHeader.target_tools)
{
case TOOLS_GNU:
FileWrite(out);
out.Format(_T("static GX_CONST GX_UBYTE %s_%s_%s_pixelmap_data[%d] __attribute__((aligned(4))) ="),
UpperDisplayName(), m_ThemeName.MakeUpper(), name, m_map->gx_pixelmap_data_size);
out += "\n#endif\n{\n";
break;
case TOOLS_IAR:
FileWrite(out);
out.Format(_T("#pragma data_alignment=4\nstatic GX_CONST GX_UBYTE %s_%s_%s_pixelmap_data[%d] ="),
UpperDisplayName(), m_ThemeName.MakeUpper(), name, m_map->gx_pixelmap_data_size);
out += "\n#endif\n{\n";
break;
default:
out.Format(_T("static GX_CONST GX_UBYTE %s_%s_%s_pixelmap_data[%d] =\n{\n"),
UpperDisplayName(), m_ThemeName.MakeUpper(), name, m_map->gx_pixelmap_data_size);
break;
}
}
else
{
out.Format(_T("static GX_CONST GX_UBYTE %s_%s_%s_pixelmap_data[%d] =\n{\n"),
UpperDisplayName(), m_ThemeName.MakeUpper(), name, m_map->gx_pixelmap_data_size);
}
FileWrite(out);
out = CString(" ");
data_p = (unsigned char*) m_map->gx_pixelmap_data;
BOOL written = TRUE;
for(unsigned int i = 0; i < m_map->gx_pixelmap_data_size; i++)
{
val.Format(_T("0x%02x"), *data_p);
out += val;
if (i != (m_map->gx_pixelmap_data_size - 1))
{
out += ", ";
}
written = CheckLineFeed(out);
data_p++;
}
if (!written)
{
FileWrite(out);
}
out = CString("\n};\n");
FileWrite(out);
}
////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteUcharAuxData(res_info *info, int frame_id)
{
CString out;
CString val;
unsigned char *data_p;
CString name = MakePixelmapName(info, frame_id);
out.Format(_T("\n/* %s_%s auxiliary data */\n\n"), m_ThemeName.MakeUpper(), name);
FileWrite(out);
out.Format(_T("static GX_CONST GX_UBYTE %s_%s_%s_pixelmap_aux_data[%d] =\n{\n"),
UpperDisplayName(), m_ThemeName.MakeUpper(), name, m_map->gx_pixelmap_aux_data_size);
FileWrite(out);
out = CString(" ");
data_p = (unsigned char*) m_map->gx_pixelmap_aux_data;
BOOL written = TRUE;
for(unsigned int i = 0; i < m_map->gx_pixelmap_aux_data_size; i++)
{
val.Format(_T("0x%02x"), *data_p);
out += val;
if (i != (m_map->gx_pixelmap_aux_data_size - 1))
{
out += ", ";
}
written = CheckLineFeed(out);
data_p++;
}
if (!written)
{
FileWrite(out);
}
out = CString("\n};\n");
FileWrite(out);
}
/////////////////////////////////////////////////////////////////////////////////////////////////
void resource_gen::WriteUintAuxData(res_info *info, int frame_id)
{
CString out;
CString val;
unsigned int *data_p;
CString name = MakePixelmapName(info, frame_id);
out.Format(_T("\n/* %s_%s auxiliary data */\n\n"), m_ThemeName.MakeUpper(), name);
FileWrite(out);
out.Format(_T("static GX_CONST GX_COLOR %s_%s_%s_pixelmap_aux_data[%d] =\n{\n"),
UpperDisplayName(), m_ThemeName.MakeUpper(), name, m_map->gx_pixelmap_aux_data_size / 4);
FileWrite(out);
out = CString(" ");
data_p = (unsigned int*) m_map->gx_pixelmap_aux_data;
BOOL written = TRUE;
for(unsigned int i = 0; i < (m_map->gx_pixelmap_aux_data_size / 4); i++)
{
val.Format(_T("0x%08x"), *data_p);
out += val;
if (i != (m_map->gx_pixelmap_aux_data_size - 1))
{
out += ", ";
}
written = CheckLineFeed(out);
data_p++;
}
if (!written)
{
FileWrite(out);
}
out = CString("\n};\n");
FileWrite(out);
}
////////////////////////////////////////////////////////////////////////////////////////////////
CString resource_gen::GetResourceFileName()
{
CString name;
CCommandInfo *pCmdInfo = GetCmdInfo();
if (pCmdInfo->GetResourceFileName().IsEmpty())
{
if (m_project->mHeader.custom_resource_enabled && (!m_project->mHeader.custom_resource_file_name.IsEmpty()))
{
name = m_project->mHeader.custom_resource_file_name;
if (m_project->CountEnabledDisplays() > 1)
{
name += "_";
name += m_project->mDisplays[m_display].name;
}
}
else
{
name = m_project->mHeader.project_name;
if (m_num_displays > 1)
{
name += "_";
name += m_project->mDisplays[m_display].name;
}
name += "_resources";
}
}
else
{
name = pCmdInfo->GetResourceFileName();
if (m_project->CountEnabledDisplays() > 1)
{
name += "_";
name += m_project->mDisplays[m_display].name;
}
}
return name;
}
////////////////////////////////////////////////////////////////////////////////////////////////
BOOL resource_gen::FontPageCompare(res_info *info_1, res_info *info_2)
{
if (info_1->font_support_extended_unicode != info_2->font_support_extended_unicode)
{
//Font range is not equal
return FALSE;
}
int page_count = NUM_FONT_CHAR_RANGES;
if (info_1->font_support_extended_unicode)
{
page_count += NUM_FONT_EXTENDED_CHAR_RANGES;
}
for (int index = 0; index < page_count; index++)
{
if((info_1->font_pages[index].enabled != info_2->font_pages[index].enabled) ||
(info_1->font_pages[index].first_char != info_2->font_pages[index].first_char) ||
(info_1->font_pages[index].last_char != info_2->font_pages[index].last_char))
{
//Font range is not equal
return FALSE;
}
}
//Font range is equal
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////////////////////
int resource_gen::FindResourceReferenceTheme(res_info *info, int theme)
{
// Check if the resource is equal to what in theme 0
int refer_theme = -1;
res_info *refer_info = NULL;
CString abspath;
CString refer_abspath;
int index;
int res_id;
CCommandInfo *pCmdInfo = GetCmdInfo();
GX_BOOL enabled;
switch (info->type)
{
case RES_TYPE_FONT:
for (index = 0; index < theme; index++)
{
if (pCmdInfo->IsNoGui())
{
enabled = pCmdInfo->IsThemeEnabled(m_project->mDisplays[m_display].themes[index].theme_name);
}
else
{
enabled = m_project->mDisplays[m_display].themes[index].gen_font_table;
}
if (enabled)
{
res_id = m_project->GetResourceId(m_display, info);
refer_info = m_project->FindResource(m_display, index, info->type, res_id);
if (refer_info)
{
abspath = MakeAbsolutePathname(info->pathinfo);
refer_abspath = MakeAbsolutePathname(refer_info->pathinfo);
if ((abspath == refer_abspath) &&
(info->font_bits == refer_info->font_bits) &&
(info->font_height == refer_info->font_height) &&
FontPageCompare(info, refer_info))
{
refer_theme = index;
}
}
break;
}
}
break;
case RES_TYPE_PIXELMAP:
for (index = 0; index < theme; index++)
{
if (pCmdInfo->IsNoGui())
{
enabled = pCmdInfo->IsThemeEnabled(m_project->mDisplays[m_display].themes[index].theme_name);
}
else
{
enabled = m_project->mDisplays[m_display].themes[index].gen_pixelmap_table;
}
if (enabled)
{
theme_info *ti = &m_project->mDisplays[m_display].themes[index];
theme_info *refer_ti = &m_project->mDisplays[m_display].themes[theme];
if ((info->palette_type == PALETTE_TYPE_SHARED) &&
((ti->palette_predefined != refer_ti->palette_predefined) ||
(ti->palette_total_size != refer_ti->palette_total_size) ||
(memcmp(ti->palette, refer_ti->palette, sizeof(GX_COLOR) * ti->palette_total_size) != 0)))
{
break;
}
res_id = m_project->GetResourceId(m_display, info);
refer_info = m_project->FindResource(m_display, index, info->type, res_id);
if (refer_info)
{
abspath = MakeAbsolutePathname(info->pathinfo);
refer_abspath = MakeAbsolutePathname(refer_info->pathinfo);
if ((abspath == refer_abspath) &&
(info->output_color_format == refer_info->output_color_format) &&
(info->keep_alpha == refer_info->keep_alpha) &&
(info->dither == refer_info->dither))
{
refer_theme = index;
}
}
break;
}
}
break;
}
return refer_theme;
}
///////////////////////////////////////////////////////////////////////////////
BOOL resource_gen::IsSystemPixelmap(INT pixelmap_id)
{
CCommandInfo* pCmdInfo = GetCmdInfo();
if (pCmdInfo->IsXmlMode())
{
return FALSE;
}
switch (pixelmap_id)
{
case GX_PIXELMAP_RADIO_ON_ID:
case GX_PIXELMAP_RADIO_OFF_ID:
case GX_PIXELMAP_CHECKBOX_ON_ID:
case GX_PIXELMAP_CHECKBOX_OFF_ID:
return TRUE;
}
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////
BOOL resource_gen::IsResEnabled(res_info* info)
{
if (info && info->enabled)
{
if ((!info->parent) || (info->parent->enabled))
{
return TRUE;
}
}
return FALSE;
}