/*
* Seven Kingdoms: Ancient Adversaries
*
* Copyright 1997,1998 Enlight Software Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
//Filename : OFONT.CPP
//Description : Font Object
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//--------------------------------------------------------//
// A font resource file is composed of three parts :
//
// one FontHeader;
// one FontInfo for each character;
// Bitmap data.
//--------------------------------------------------------//
//-------- Define struct FontHeader -------//
#pragma pack(1)
struct FontHeader
{
unsigned short max_width;
unsigned short max_height;
unsigned short std_height;
unsigned short first_char; // ascii code of the first character
unsigned short last_char; // ascii code of the last character
};
#pragma pack()
//-------- Define struct FontInfo -------//
#pragma pack(1)
struct FontInfo // info for each character
{
char offset_y;
unsigned char width;
unsigned char height;
long bitmap_offset; // file offset relative to bitmap data
};
#pragma pack()
//--------- Define macro constant ------------//
#define HYPER_FIELD_COLOR V_LIGHT_BLUE
//--------- German character table -------//
//#ifdef GERMAN
//#define GERMAN_CHAR_COUNT 7
// their DOS ascii characters: ü ä ß ö Ä Ü Ö
//static short german_ascii_array[] = { 252, 228, 223, 246, 196, 220, 214 };
//static short german_bmp_id_array[] = { 121, 100, 95, 116, 128, 151, 145 };
//#endif
//------- Define static member variable --------//
short Font::hyper_field_count;
HyperField Font::hyper_field_array[MAX_HYPER_FIELD];
static int text_line_count; // used by text_width() & text_height() only
//----------- Begin of function Font Constructor -------//
Font::Font(char* fontName)
{
memset( this, 0, sizeof(Font) );
if( fontName )
init(fontName);
}
//------------- End of function Font Constructor -------//
//----------- Begin of function Font Destructor -------//
Font::~Font()
{
deinit();
}
//------------- End of function Font Destructor -------//
//-------- Begin of function Font::init -----------//
//
// fontName = name of the font type.
// (e.g. "STD" will load "FNT_STD.RES" )
//
// [int] interCharSpace = inter-character space
// (default:1)
//
// [int] italicShift = horzontal back shifting for italic font
// (default:0)
//
// Return : 1 - succeed;
// 0 - reading palette file error
//
void Font::init(char* fontName, int interCharSpace, int italicShift)
{
if( init_flag )
deinit();
inter_char_space = interCharSpace;
//---------- open the font file -----------//
File fontFile;
String str;
str = DIR_RES;
str += "FNT_";
str += fontName;
str += ".RES";
fontFile.file_open(str);
//-------- read in the font header ---------//
FontHeader fontHeader;
fontFile.file_read( &fontHeader, sizeof(FontHeader) );
max_font_width = fontHeader.max_width;
max_font_height = fontHeader.max_height;
std_font_height = fontHeader.std_height;
font_height = std_font_height; // its default is std_font_height, but can be set to max_font_height
first_char = fontHeader.first_char;
last_char = fontHeader.last_char;
//----------- read in font info ------------//
int infoArraySize = sizeof(FontInfo) * (last_char-first_char+1);
font_info_array = (FontInfo*) mem_add( infoArraySize );
fontFile.file_read( font_info_array, infoArraySize );
//------- process italic shift --------//
if( italicShift )
{
for( int i=0 ; i lastX, the x coordination of the last pixel of last font
//
int Font::put(int x,int y,char* textPtr, char clearBack, int x2 )
{
err_when( x<0 || y<0 );
if( !init_flag )
return x;
//-------- process translation ---------//
short textChar;
textPtr = translate.process(textPtr);
//-------------------------------------//
int textPtrLen = strlen(textPtr);
if( x2 < 0 ) // default
x2 = x+max_font_width*textPtrLen;
x2 = min( x2, VGA_WIDTH-1 );
if( !Vga::use_back_buf )
mouse.hide_area( x, y, x2, y+font_height );
int y2 = y+font_height-1;
//-------------------------------------//
FontInfo* fontInfo;
for( int lenCount=1 ; *textPtr && lenCount<=textPtrLen ; textPtr++, lenCount++ )
{
textChar = *((unsigned char*)textPtr); // textChar is
//#ifdef GERMAN
// textChar = translate_german_char(textChar);
//#endif
//--------------- space character ------------------//
if( textChar == ' ' )
{
if( x+space_width > x2 )
break;
if( clearBack && !Vga::use_back_buf ) // copy texture from the back buffer as the background color
vga.blt_buf( x, y, x+space_width-1, y+font_height-1, 0 );
x += space_width;
}
//####### patch begin Gilbert 28/2 ########//
// --------- control char: FIRST_NATION_COLOR_CODE_IN_TEXT -----------//
else if( textChar >= FIRST_NATION_COLOR_CODE_IN_TEXT && textChar <= LAST_NATION_COLOR_CODE_IN_TEXT ) // display nation color bar in text
{
if( x2 >= 0 && x+NATION_COLOR_BAR_WIDTH-1 > x2 ) // exceed right border x2
break;
char colorCode = game.color_remap_array[textChar-FIRST_NATION_COLOR_CODE_IN_TEXT].main_color;
nation_array.disp_nation_color(x, y+2, colorCode);
x += NATION_COLOR_BAR_WIDTH;
}
//####### end begin Gilbert 28/2 ########//
//------------- normal character ----------------//
else if( textChar >= first_char && textChar <= last_char )
{
fontInfo = font_info_array+textChar-first_char;
if( x+fontInfo->width > x2 )
break;
if( fontInfo->width > 0 )
{
if( clearBack && !Vga::use_back_buf )
{
if( fontInfo->offset_y > 0 ) // clear the upper space areas of the character
IMGcopy( vga_front.buf_ptr(), vga_front.buf_pitch(), vga_back.buf_ptr(), vga_back.buf_pitch(),
x, y, x+fontInfo->width-1, y+fontInfo->offset_y-1 );
IMGjoinTrans( vga_front.buf_ptr(), vga_front.buf_pitch(),
vga_back.buf_ptr(), vga_back.buf_pitch(), x, y+fontInfo->offset_y,
font_bitmap_buf + fontInfo->bitmap_offset );
int ty = y+fontInfo->offset_y+fontInfo->height-1;
if( ty < y2 ) // clear the lower space areas of the character
IMGcopy( vga_front.buf_ptr(), vga_front.buf_pitch(),
vga_back.buf_ptr(), vga_back.buf_pitch(), x, ty+1, x+fontInfo->width-1, y2 );
}
else
{
IMGbltTrans( Vga::active_buf->buf_ptr(), Vga::active_buf->buf_pitch(),
x, y+fontInfo->offset_y, font_bitmap_buf + fontInfo->bitmap_offset );
}
x += fontInfo->width; // inter-character space
}
}
else
{
//------ tab or unknown character -------//
if( textChar == '\t' ) // Tab
x += space_width*8; // one tab = 8 space chars
else
x += space_width;
}
//--------- inter-character space ---------//
if( clearBack && !Vga::use_back_buf ) // copy texture from the back buffer as the background color
vga.blt_buf( x, y, x+inter_char_space-1, y+font_height-1, 0 );
x+=inter_char_space;
}
//------ clear remaining area -------//
if( clearBack && !Vga::use_back_buf ) // copy texture from the back buffer as the background color
vga.blt_buf( x, y, x2, y+font_height-1, 0 );
if( !Vga::use_back_buf )
mouse.show_area();
return x-1;
}
//----------- End of function Font::put ---------//
//#ifdef GERMAN
//--------- Start of function Font::translate_german_char ---------//
//
// textChar = the character to be translated
//
//short Font::translate_german_char(short textChar)
//{
// for( int i=0 ; i x, y = the position of the character
// textChar = the character
//
void Font::put_char(int x, int y, unsigned short textChar)
{
if( textChar >= first_char && textChar <= last_char )
{
FontInfo* fontInfo = font_info_array+textChar-first_char;
IMGbltTrans( Vga::active_buf->buf_ptr(), Vga::active_buf->buf_pitch(),
x, y + fontInfo->offset_y, font_bitmap_buf + fontInfo->bitmap_offset );
}
}
//----------- End of function Font::put_char ---------//
//--------- Start of function Font::right_put ---------//
//
// Display a string in right-justified format.
//
// x, y = the right end position of displaying the string
// textPtr = the character
//
void Font::right_put(int x, int y, char* textPtr)
{
int textWidth = text_width(textPtr);
put( x-textWidth, y, textPtr );
}
//----------- End of function Font::right_put ---------//
//--------- Begin of function Font::text_width ----//
//
// Given the textPtr string, then calculate the width (unit:pixel).
//
// char* textPtr = the textPtr to be put on screen
// [int] textPtrLen = the length of the textPtr to be put
// (default : -1, until NULL character)
// [int] maxDispWidth = the maximum width can be displayed
// the textPtr width cannot > maxDispWidth
//
// Note : static var text_line_count is used to pass value to text_height()
//
// Return : the screen width of the textPtr display using this font
//
int Font::text_width(char* textPtr, int textPtrLen, int maxDispWidth)
{
int charWidth, x=0, lenCount, maxLen=0, wordWidth=0;
short textChar;
if( !init_flag )
return x;
textPtr = translate.process(textPtr);
if( textPtrLen < 0 )
textPtrLen = strlen(textPtr);
text_line_count=1;
//-------------------------------------//
for( lenCount=1 ; *textPtr && lenCount<=textPtrLen ; textPtr++, lenCount++, x+=inter_char_space )
{
textChar = *((unsigned char*)textPtr);
//#ifdef GERMAN
// textChar = translate_german_char(textChar);
//#endif
//-- if the line exceed the given max width, advance to next line --//
if( maxDispWidth && x > maxDispWidth )
{
maxLen = maxDispWidth;
x = wordWidth; // the last word of the prev line wraps to next line
text_line_count++;
}
//--- if the textPtr has more than 1 line, get the longest line ---//
if( textChar == '\n' )
{
if( x>maxLen )
maxLen=x;
x=0;
wordWidth=0;
text_line_count++;
continue; // next character
}
//-------- control char: FIRST_NATION_COLOR_CODE_IN_TEXT -----------//
else if( textChar >= FIRST_NATION_COLOR_CODE_IN_TEXT && textChar <= LAST_NATION_COLOR_CODE_IN_TEXT ) // display nation color bar in text
{
x += NATION_COLOR_BAR_WIDTH;
wordWidth = 0;
}
//--- add the width of the character to the total line width ---//
else if( textChar == ' ' )
{
x += space_width;
wordWidth = 0;
}
else if( textChar >= first_char && textChar <= last_char )
{
charWidth = font_info_array[textChar-first_char].width;
x += charWidth;
wordWidth += charWidth;
}
else
{
x += space_width;
wordWidth += space_width;
}
if( maxDispWidth && wordWidth > maxDispWidth )
{
x -= wordWidth - maxDispWidth;
wordWidth = maxDispWidth;
}
}
//-------------------------------------------//
if( maxDispWidth && x > maxDispWidth )
text_line_count++;
if( textPtr[-1] == '\n' ) // if last character is line feed, don't count double
text_line_count--;
return max(maxLen,x);
}
//----------- End of function Font::text_width ----//
//--------- Begin of function Font::text_height ----//
//
// text_width() must first be called, this function use the result
// from text_width() to calc the textPtr height.
//
// [int] lineSpace = space between lines
// ( default : DEFAULT_LINE_SPACE )
//
// Return : the screen height of the textPtr display using this font
//
int Font::text_height(int lineSpace)
{
return font_height * text_line_count +
lineSpace * (text_line_count-1);
}
//----------- End of function Font::text_height ----//
//--------- Begin of function Font::put_paragraph ------//
//
// Put a paragraph of textPtr on screen
// Given the area of the paragraph
// Automatical word wrap is available
//
// If the background color of the font is set, the area of the paragraph
// will be filled with the background color first.
//
// int x1,y1,x2,y2 = area of the textPtr
//
// char* textPtr = the textPtr to be put on screen
//
// [int lineSpace] = no. of pixel space between lines
// ( default : 2 )
//
// [int] startLine = start display at which line
// ( default : 1, first line)
//
// [float wordPause] = time pause between words
// ( default : 0 )
//
// [char dispFlag] = display the textPtr or not, if called by count_line(),
// this would be 0.
// ( default : 1 )
//
//-------------------------------------------------------//
//
// It will store resulting paramteres :
//
// next_text_ptr = point to the textPtr just after this paragraph
// which has been put to the screen.
//
// next_textPtr_y = the endding y position of the paragraph and which
// is the y position which next paragraph can be put
//
// line_count = the no. of lines has been displayed in current
// put_paragraph() session.
//
// hyper_field_array[] = an array of hyper-textPtred field
//
//-------------------------------------------------------//
void Font::put_paragraph(int x1, int y1, int x2, int y2, char *textPtr,
int lineSpace, int startLine, char dispFlag)
{
if( !init_flag || y1+font_height-1 > y2 )
return;
textPtr = translate.process(textPtr);
//--------- define vars ---------------//
int x,y,wordX;
int newWord;
short textChar;
char *wordPtr;
char flag_under_line=0; // attribute control flags
char flag_hyper_field=0;
int under_line_x1; // parameters for drawing under line
HyperField* hyper_field_ptr = hyper_field_array;
FontInfo* fontInfo;
//--------- initialize vars ---------------//
x = x1;
y = y1;
wordX = x1; // the x of the start of the word
wordPtr = textPtr;
newWord = 0;
line_count=0;
hyper_field_count = 0;
//---------- prepare for display font ----------//
if( dispFlag )
{
err_when( x1>x2 || y1>y2 || x1<0 || y1<0 || x2>=VGA_WIDTH || y2>=VGA_HEIGHT );
if( !Vga::use_back_buf ) // if not say word by word, turn off mouse one time, otherwise turn off mouse one word at a time
mouse.hide_area( x1,y1,x2,y2 ); // if the mouse cursor is in that area, hide it
}
//--------- loop for displaying textPtr ----------//
while(1)
{
//------ space appear, process the previous word ------//
if ( newWord )
{
if( x-1 > x2 ) // it is still okay if x-1==x2 because x is the next pixel, not the last displayed pixel
{
if( line_count >= startLine-1 ) // startLine start from 1
{
y += font_height + lineSpace;
if ( y + font_height - 1 > y2 ) // no further space for printing textPtr, end
break;
}
x = x1;
line_count++;
}
else
{
x = wordX;
}
//--------- Process current word ----------//
for( ; wordPtr < textPtr && *wordPtr ; wordPtr++, x+=inter_char_space ) // wordPtr point to the current word which will be printed
{
textChar = *((unsigned char*)wordPtr); // textChar is
//#ifdef GERMAN
// textChar = translate_german_char(textChar);
//#endif
//---------- control char: '_' -------------//
if( textChar == '_' ) // e.g. _Title_, a line will be drawn under the word "Title"
{
if( flag_under_line ) // current '_' is the closing one, the open '_' has appeared previously
{
if( dispFlag && line_count >= startLine-1 ) // startLine start from 1
IMGbar(Vga::active_buf->buf_ptr(), Vga::active_buf->buf_pitch(),
under_line_x1, y+font_height, x, y+font_height, HYPER_FIELD_COLOR );
}
else
under_line_x1 = x;
flag_under_line = !flag_under_line;
continue;
}
//-------- control char: '~' -----------//
else if( textChar == '~' ) // e.g. ~Captial~, the word "Capital" is a hyper-textPtred field, pressing on it will link to the topic "Capital"
{
if( !flag_hyper_field ) // current '~' is the opening one
{
hyper_field_ptr->x1 = x;
hyper_field_ptr->y1 = y;
hyper_field_ptr->text_ptr = (wordPtr+1); // skip current '~'
}
else // current '~' is the closing one
{
hyper_field_ptr->x2 = x;
hyper_field_ptr->y2 = y+font_height;
hyper_field_ptr->text_len = wordPtr - hyper_field_ptr->text_ptr;
hyper_field_count++;
hyper_field_ptr++;
err_when( hyper_field_count >= MAX_HYPER_FIELD );
}
flag_hyper_field = !flag_hyper_field;
continue;
}
//-------- control char: FIRST_NATION_COLOR_CODE_IN_TEXT -----------//
else if( textChar >= FIRST_NATION_COLOR_CODE_IN_TEXT && textChar <= LAST_NATION_COLOR_CODE_IN_TEXT ) // display nation color bar in text
{
if( x2 >= 0 && x+NATION_COLOR_BAR_WIDTH-1 > x2 ) // exceed right border x2
break;
char colorCode = game.color_remap_array[textChar-FIRST_NATION_COLOR_CODE_IN_TEXT].main_color;
nation_array.disp_nation_color(x, y+2, colorCode);
x += NATION_COLOR_BAR_WIDTH;
}
//--------------- space character ------------------//
else if( textChar == ' ' )
{
if( x+space_width > x2 )
break;
x += space_width;
}
//----------- display char ------------//
else if( textChar >= first_char && textChar <= last_char )
{
fontInfo = font_info_array+textChar-first_char;
// character width = offset of next character - current offset
if( x2 >= 0 && x+fontInfo->width-1 > x2 ) // exceed right border x2
break;
if( fontInfo->width > 0 )
{
if( dispFlag && line_count >= startLine-1 ) // startLine start from 1
{
// if( flag_hyper_field )
// mainColor = HYPER_FIELD_COLOR;
IMGbltTrans( Vga::active_buf->buf_ptr(), Vga::active_buf->buf_pitch(),
x, y+fontInfo->offset_y, font_bitmap_buf + fontInfo->bitmap_offset );
}
x += fontInfo->width;
}
}
}
//--------- next line ----------------------//
if( *textPtr == '\n' ) // next line
{
if( line_count >= startLine-1 ) // startLine start from 1
{
y += font_height + lineSpace;
if ( y + font_height - 1 > y2 ) // no further space for printing textPtr, end
break;
}
x = x1;
textPtr++;
line_count++;
}
if( *textPtr == NULL ) // all paragraph has been printed
break;
wordPtr = textPtr;
wordX = x;
newWord = 0;
}
//------------ process spacing -------------//
if( *textPtr == ' ' || *textPtr == '\n' || *textPtr == NULL ) // not space
newWord = 1;
else
{
textChar = *((unsigned char*)textPtr); // textChar is
//#ifdef GERMAN
// textChar = translate_german_char(textChar);
//#endif
if( textChar >= first_char && textChar <= last_char )
{
fontInfo = font_info_array+textChar-first_char;
if( textChar >= FIRST_NATION_COLOR_CODE_IN_TEXT && textChar <= LAST_NATION_COLOR_CODE_IN_TEXT ) // display nation color bar in text
x += NATION_COLOR_BAR_WIDTH;
else if( textChar == ' ' )
x+=space_width;
else if( fontInfo->width > 0 ) // current font width
x+=fontInfo->width;
else
x+=space_width;
}
else
{
x+=space_width;
}
x+=inter_char_space;
}
if( *textPtr && *textPtr != '\n' ) // when finished, remain as NULL for next cycle to detect
textPtr++;
}
//------------ finish displaying ----------------//
if( dispFlag )
{
if( !Vga::use_back_buf )
mouse.show_area();
}
// while( *textPtr == '\n' || *textPtr == '\r' )
// textPtr++;
next_text_ptr = textPtr; // the current pointer in the textPtr
next_text_y = y + font_height + lineSpace;
line_count++;
}
//---------- End of function Font::put_paragraph ------//
//--------- Begin of function Font::count_line ------//
//
// Count the no. of lines of textPtr can be displayed on the given area.
//
// int x1,y1,x2,y2 = area of the textPtr
// char* textPtr = the textPtr to be put on screen
//
// = no. of pixel space between lines
// ( default : 0 )
//
// = no. of lines can be displayed in the textPtr area
// = total no. of lines of the textPtr
//
void Font::count_line(int x1, int y1, int x2, int y2, char *textPtr,
int lineSpace , int& dispLines, int& totalLines)
{
dispLines =0;
totalLines=0;
while( *textPtr ) // if *textPtr==NULL means EOF
{
put_paragraph(x1, y1, x2, y2, textPtr, lineSpace, 1, 0); // last 0-means don't display the textPtr, only returning the parameters for our calculating of line counts
if( !dispLines ) // only set once at the first time
dispLines = line_count;
totalLines += line_count;
textPtr = next_text_ptr;
}
}
//---------- End of function Font::count_line ------//
//-------- Begin of function Font::d3_put --------//
//
// Display field description and field value
//
// x1,y1 = the coordination of the spinner description
// desStr = the spinner description
//
// Return : lastX, the x coordination of the last pixel of last font
//
int Font::d3_put(int x1, int y1, char* desStr )
{
int marginSpace = font_height/5;
int x2 = x1+text_width(desStr)+marginSpace*2-1;
vga.d3_panel_up( x1, y1, x2, y1+font_height+marginSpace*2-1 );
put( x1+marginSpace, y1+marginSpace, desStr);
return x2;
}
//--------- End of function Font::d3_put ---------//
//-------- Begin of function Font::d3_put --------//
//
// Display field description and field value.
// It will display the description on the center of the panel
//
// x1,y1 = the coordination of the panel
// x2,y2 =
// desStr = the spinner description
//
void Font::d3_put(int x1, int y1, int x2, int y2, char* desStr)
{
int tx = x1 + ((x2-x1+1) - text_width(desStr))/2;
int ty = y1 + ((y2-y1+1) - font_height)/2+1;
vga.d3_panel_up( x1, y1, x2, y2);
if( tx x1,y1 = the coordination of the panel
// x2,y2 =
// desStr = the spinner description
// [char] clearBack = clear background with back_color or not
// (default : 0)
//
// Return : lastX, the x coordination of the last pixel of last font
//
int Font::center_put(int x1, int y1, int x2, int y2, char* desStr, char clearBack)
{
int tx = x1 + ((x2-x1+1) - text_width(desStr))/2;
int ty = y1 + ((y2-y1+1) - font_height)/2;
if( tx<0 )
tx=0;
if( clearBack && !Vga::use_back_buf && tx>x1 ) // copy texture from the back buffer as the background color
vga.blt_buf( x1, y1, tx-1, y2, 0 );
return put( tx, ty, desStr, clearBack, x2 );
}
//--------- End of function Font::center_put ---------//
//-------- Begin of function Font::put_field --------//
//
// Display field description and field value
//
// format - "Field : 999999" e.g. "List price : $92,232"
//
// x1,y1 = the coordination of the spinner description
// desStr = the spinner description
// x2 = the coordination of the spinner variable
// value = value
//
// [int] format = 1 - 1,000,000 normal, with thousand separator
// 2 - $1,000,000 add dollar sign, with thousand separator
// 3 - 100% percentage
// (default : 1 )
//
void Font::put_field(int x1, int y1, char* desStr, int x2, int value, int format )
{
vga.d3_panel_up( x1, y1, x2, y1+font_height+3 );
put( x1+2, y1+2, desStr);
put( x2+4, y1+2, m.format(value,format) );
}
//--------- End of function Font::put_field ---------//
//-------- Begin of function Font::update_field --------//
//
// Update the value of the field which is previously displayed by
// Font::put_field()
//
// x1,y1 = the coordination of the field variable
// value = value
//
// format = 1 - 1,000,000 normal, with thousand separator
// 2 - $1,000,000 add dollar sign, with thousand separator
// 3 - 100% percentage
// (default : 1 )
//
// x2 = the x2 (right border) of the field
//
void Font::update_field(int x1, int y1, int value, int format, int x2)
{
if( x2<0 )
x2 = x1+80;
put( x1+4, y1+2, m.format(value,format), 1, x2 );
}
//--------- End of function Font::update_field ---------//
//-------- Begin of function Font::field --------//
//
// Combine the function of put_field() and update_field()
// depending on the refreshFlag passed
//
// format - "Field : 999999" e.g. "List price : $92,232"
//
// x1,y1 = the coordination of the spinner description
// desStr = the spinner description
// x2 = the coordination of the spinner variable
// value = value
//
// format = 1 - 1,000,000 normal, with thousand separator
// 2 - $1,000,000 add dollar sign, with thousand separator
// 3 - 100% percentage
//
// x2 = the x2 (right border) of the field
// refreshFlag = refresh flag, either INFO_REPAINT or INFO_UPDATE
// [char*] helpCode = help code
//
void Font::field(int xDes, int y1, char* desStr, int xValue, int value,
int format, int xEnd, int refreshFlag, char* helpCode)
{
int x2;
if( refreshFlag == INFO_REPAINT )
{
vga.d3_panel_up( xDes, y1, xValue, y1+font_height+3 );
put( xDes+2 , y1+2, desStr);
x2 = put( xValue+4, y1+2, m.format(value,format) );
}
else
{
x2 = put( xValue+4, y1+2, m.format(value,format), 1, xEnd );
}
if( helpCode )
help.set_help(xDes, y1, x2, y1+font_height+3, helpCode );
}
//--------- End of function Font::field ---------//
//-------- Begin of function Font::put_field --------//
//
// Display field description and field value
//
// format - "Field : 999999" e.g. "List price : $92,232"
//
// x1,y1 = the coordination of the spinner description
// desStr = the spinner description
// x2 = the coordination of the spinner variable
// value = value
//
// [int] format = 1 - 1,000,000 normal, with thousand separator
// 2 - $1,000,000 add dollar sign, with thousand separator
// 3 - 100% percentage
// (default : 1 )
//
void Font::put_field(int x1, int y1, char* desStr, int x2, double value, int format)
{
vga.d3_panel_up( x1, y1, x2, y1+font_height+3 );
put( x1+2, y1+2, desStr);
put( x2+4, y1+2, m.format(value,format) );
}
//--------- End of function Font::put_field ---------//
//-------- Begin of function Font::update_field --------//
//
// Update the value of the field which is previously displayed by
// Font::put_field()
//
// x1,y1 = the coordination of the field variable
// value = value
//
// format = 1 - 1,000,000 normal, with thousand separator
// 2 - $1,000,000 add dollar sign, with thousand separator
// 3 - 100% percentage
// (default : 1 )
//
// x2 = the x2 (right border) of the field
//
void Font::update_field(int x1, int y1, double value, int format, int x2)
{
if( x2<0 )
x2 = x1+80;
put( x1+4, y1+2, m.format(value,format), 1, x2 );
}
//--------- End of function Font::update_field ---------//
//-------- Begin of function Font::field --------//
//
// Combine the function of put_field() and update_field()
// depending on the refreshFlag passed
//
// format - "Field : 999999" e.g. "List price : $92,232"
//
// x1,y1 = the coordination of the spinner description
// desStr = the spinner description
// x2 = the coordination of the spinner variable
// value = value
//
// format = 1 - 1,000,000 normal, with thousand separator
// 2 - $1,000,000 add dollar sign, with thousand separator
// 3 - 100% percentage
//
// x2 = the x2 (right border) of the field
// refreshFlag = refresh flag, either INFO_REPAINT or INFO_UPDATE
// [char*] helpCode = help code
//
void Font::field(int xDes, int y1, char* desStr, int xValue, double value,
int format, int xEnd, int refreshFlag, char* helpCode )
{
int x2;
if( refreshFlag == INFO_REPAINT )
{
vga.d3_panel_up( xDes, y1, xValue, y1+font_height+3 );
put( xDes+2 , y1+2, desStr);
x2 = put( xValue+4, y1+2, m.format(value,format) );
}
else
{
x2 = put( xValue+4, y1+2, m.format(value,format), 1, xEnd );
}
if( helpCode )
help.set_help(xDes, y1, x2, y1+font_height+3, helpCode );
}
//--------- End of function Font::field ---------//
//-------- Begin of function Font::put_field --------//
//
// Display field description and field value
//
// format - "Field : 999999" e.g. "List price : $92,232"
//
// x1,y1 = the coordination of the spinner description
// desStr = the spinner description
// x2 = the coordination of the spinner variable
// value = value
//
void Font::put_field(int x1, int y1, char* desStr, int x2, char* value)
{
vga.d3_panel_up( x1, y1, x2, y1+font_height+3 );
put( x1+2, y1+2, desStr);
put( x2+4, y1+2, value);
}
//--------- End of function Font::put_field ---------//
//-------- Begin of function Font::update_field --------//
//
// Update the value of the field which is previously displayed by
// Font::put_field()
//
// x1,y1 = the coordination of the field variable
// value = value
// x2 = the x2 (right border) of the field
//
void Font::update_field(int x1, int y1, char* value, int x2)
{
if( x2<0 )
x2 = x1+80;
put( x1+4, y1+2, value, 1, x2 );
}
//--------- End of function Font::update_field ---------//
//-------- Begin of function Font::field --------//
//
// Combine the function of put_field() and update_field()
// depending on the refreshFlag passed
//
// format - "Field : 999999" e.g. "List price : $92,232"
//
// x1,y1 = the coordination of the spinner description
// desStr = the spinner description
// x2 = the coordination of the spinner variable
// value = value
//
// x3 = the x3 (right border) of the field
// refreshFlag = refresh flag, either INFO_REPAINT or INFO_UPDATE
// [char*] helpCode = help code
//
void Font::field(int xDes, int y1, char* desStr, int xValue, char* value,
int xEnd, int refreshFlag, char* helpCode )
{
int x2;
if( refreshFlag == INFO_REPAINT )
{
vga.d3_panel_up( xDes, y1, xValue, y1+font_height+3 );
put( xDes+2 , y1+2, desStr);
x2 = put( xValue+4, y1+2, value );
}
else
{
x2 = put( xValue+4, y1+2, value, 1, xEnd );
}
if( helpCode )
help.set_help(xDes, y1, x2, y1+font_height+3, helpCode );
}
//--------- End of function Font::field ---------//
//-------- Begin of function Font::disp --------//
//
// Display a value and clear the background
//
// x1,y1 = the coordination of the field variable
// value = value
//
// format = 1 - 1,000,000 normal, with thousand separator
// 2 - $1,000,000 add dollar sign, with thousand separator
// 3 - 100% percentage
// (default : 1 )
//
// x2 = the x2 (right border) of the field
//
// Return : lastX, the x coordination of the last pixel of last font
//
int Font::disp(int x1, int y1, int value, int format, int x2)
{
if( x2<0 )
x2 = x1+80;
int lastX = put( x1, y1, m.format(value,format), 1, x2 );
return lastX;
}
//--------- End of function Font::disp ---------//
//-------- Begin of function Font::disp --------//
//
// Display a value and clear the background
//
// x1,y1 = the coordination of the field variable
// value = value
//
// format = 1 - 1,000,000 normal, with thousand separator
// 2 - $1,000,000 add dollar sign, with thousand separator
// 3 - 100% percentage
// (default : 1 )
//
// x2 = the x2 (right border) of the field
//
// Return : lastX, the x coordination of the last pixel of last font
//
int Font::disp(int x1, int y1, double value, int format, int x2)
{
if( x2<0 )
x2 = x1+80;
int lastX = put( x1, y1, m.format(value,format), 1, x2 );
return lastX;
}
//--------- End of function Font::disp ---------//
//-------- Begin of function Font::disp --------//
//
// Display a value and clear the background
//
// x1,y1 = the coordination of the field variable
// textPtr = pointer to the textPtr
// x2 = the x2 (right border) of the field
//
// Return : lastX, the x coordination of the last pixel of last font
//
int Font::disp(int x1, int y1, char* textPtr, int x2)
{
if( x2<0 )
x2 = x1+80;
int lastX = put( x1, y1, textPtr, 1, x2 );
return lastX;
}
//--------- End of function Font::disp ---------//
//--------- Begin of function Font::put_char_to_buffer ---------//
void Font::put_char_to_buffer(char* dest, int destPitch, int x, int y, unsigned short textChar)
{
if( textChar >= first_char && textChar <= last_char )
{
FontInfo* fontInfo = font_info_array+textChar-first_char;
char *fontBitmap = font_bitmap_buf + fontInfo->bitmap_offset;
IMGbltTrans( dest, destPitch, x, y + fontInfo->offset_y, fontBitmap );
}
}
//--------- End of function Font::put_char_to_buffer ---------//
//--------- Begin of function Font::put_to_buffer ---------//
void Font::put_to_buffer(char* dest, int destPitch, int x1, int y1, char *text)
{
int x2 = destPitch; // width of buffer
while( *text != '\0' && x1 < x2)
{
int charSize = sizeof(unsigned char); // 1 for byte character, 2 for word character
unsigned short textChar = *(unsigned char *)text;
//#ifdef GERMAN
// textChar = translate_german_char(textChar);
//#endif
//if( // unicode or a word character )
//{
// textChar = *(unsigned short *)buffer; // unicode
// textChar = *(unsigned char *)text << 8 + *(1+(unsigned char *)text); // big-5...
// charSize = sizeof(unsigned short);
//}
// --------- advance to next character------------//
int charWidth = textChar == ' ' ? space_width :
(font_info_array+textChar-first_char)->width;
if( x1 + charWidth <= x2 )
put_char_to_buffer( dest, destPitch, x1, y1, textChar);
x1 += charWidth;
text += charSize;
}
}
//--------- End of function Font::put_to_buffer ---------//
//--------- Begin of function Font::center_put_to_buffer ---------//
void Font::center_put_to_buffer(char* dest, int destPitch, int x1, int y1, int x2, int y2, char *desStr)
{
int tx = x1 + ((x2-x1) - text_width(desStr))/2;
int ty = y1 + ((y2-y1) - font_height)/2;
if( tx<0 )
tx=0;
put_to_buffer( dest, destPitch, tx, ty, desStr);
}
//--------- End of function Font::center_put_to_buffer ---------//