int Font::PrintInitial(int x, int y, const Region &rgn, unsigned char currChar) const { Video *video = core->GetVideoDriver(); video->BlitSpriteRegion( sprBuffer, size[currChar], x + rgn.x, y + rgn.y - yPos[currChar], true, &rgn ); x += size[currChar].w; return x; }
int Font::PrintInitial(int x, int y, const Region &rgn, unsigned char currChar) const { Video *video = core->GetVideoDriver(); video->BlitSpriteRegion( sprBuffer, getInfo(currChar).size, x + rgn.x, y + rgn.y - getInfo(currChar).yPos, true, &rgn ); x += getInfo(currChar).size.w; return x; }
void Font::Print(Region cliprgn, Region rgn, const unsigned char* string, Palette* hicolor, unsigned char Alignment, bool anchor, Font* initials, Sprite2D* cursor, unsigned int curpos, bool NoColor) const { bool enablecap=false; int capital = 0; if (initials) { capital=1; enablecap=true; } (void)enablecap; //HACK: shut up unused-but-set warnings, until the var is reused unsigned int psx = PARAGRAPH_START_X; Palette* pal = hicolor; if (!pal) { pal = palette; } if (initials==this) { initials = NULL; } sprBuffer->SetPalette( pal ); size_t len = strlen( ( char* ) string ); char* tmp = ( char* ) malloc( len + 1 ); memcpy( tmp, ( char * ) string, len + 1 ); while (len > 0 && (tmp[len - 1] == '\n' || tmp[len - 1] == '\r')) { // ignore trailing newlines tmp[len - 1] = 0; len--; } SetupString( tmp, rgn.w, NoColor, initials, capital ); int ystep = 0; if (Alignment & IE_FONT_SINGLE_LINE) { for (size_t i = 0; i < len; i++) { if (tmp[i] == 0) continue; int height = yPos[( unsigned char ) tmp[i] - 1]; if (ystep < height) ystep = height; } } else { ystep = size[1].h; } if (!ystep) ystep = maxHeight; int x = psx, y = ystep; Video* video = core->GetVideoDriver(); if (Alignment & IE_FONT_ALIGN_CENTER) { int w = CalcStringWidth( tmp, NoColor ); x = ( rgn.w - w ) / 2; } else if (Alignment & IE_FONT_ALIGN_RIGHT) { int w = CalcStringWidth( tmp, NoColor ); x = ( rgn.w - w ); } if (Alignment & IE_FONT_ALIGN_MIDDLE) { int h = 0; for (size_t i = 0; i <= len; i++) { if (tmp[i] == 0) h++; } h = h * ystep; y += ( rgn.h - h ) / 2; } else if (Alignment & IE_FONT_ALIGN_BOTTOM) { int h = 1; for (size_t i = 0; i <= len; i++) { if (tmp[i] == 0) h++; } h = h * ystep; y += ( rgn.h - h ); } else if (Alignment & IE_FONT_ALIGN_TOP) { y += 5; } for (size_t i = 0; i < len; i++) { if (( ( unsigned char ) tmp[i] ) == '[' && !NoColor) { i++; char tag[256]; tag[0]=0; for (int k = 0; k < 256 && i<len; k++) { if (tmp[i] == ']') { tag[k] = 0; break; } tag[k] = tmp[i++]; } if (strnicmp( tag, "capital=",8)==0) { sscanf( tag, "capital=%d", &capital); if (capital) { enablecap=true; } continue; } if (strnicmp( tag, "color=", 6 ) == 0) { unsigned int r,g,b; if (sscanf( tag, "color=%02X%02X%02X", &r, &g, &b ) != 3) continue; const Color c = {(unsigned char) r,(unsigned char) g,(unsigned char) b, 0}; Palette* newPal = core->CreatePalette( c, palette->back ); sprBuffer->SetPalette( newPal ); gamedata->FreePalette( newPal ); continue; } if (stricmp( tag, "/color" ) == 0) { sprBuffer->SetPalette( pal ); continue; } if (stricmp( "p", tag ) == 0) { psx = x; continue; } if (stricmp( "/p", tag ) == 0) { psx = PARAGRAPH_START_X; continue; } continue; } if (tmp[i] == 0) { y += ystep; x = psx; int w = CalcStringWidth( &tmp[i + 1], NoColor ); if (Alignment & IE_FONT_ALIGN_CENTER) { x = ( rgn.w - w ) / 2; } else if (Alignment & IE_FONT_ALIGN_RIGHT) { x = ( rgn.w - w ); } continue; } unsigned char currChar = ( unsigned char ) tmp[i] - 1; if (initials && capital) { x = initials->PrintInitial( x, y, rgn, currChar ); enablecap=false; continue; } video->BlitSpriteRegion( sprBuffer, size[currChar], x + rgn.x, y + rgn.y - yPos[currChar], anchor, &cliprgn ); if (cursor && ( curpos == i )) video->BlitSprite( cursor, x + rgn.x, y + rgn.y, anchor, &cliprgn ); x += size[currChar].w; } if (cursor && ( curpos == len )) { video->BlitSprite( cursor, x + rgn.x, y + rgn.y, anchor, &cliprgn ); } free( tmp ); }
void Font::PrintFromLine(int startrow, Region rgn, const unsigned char* string, Palette* hicolor, unsigned char Alignment, Font* initials, Sprite2D* cursor, unsigned int curpos, bool NoColor) const { bool enablecap=false; int capital = 0; int initials_rows = 0; int last_initial_row = 0; int initials_x = 0; int initials_row = 0; unsigned char currCap = 0; size_t len = strlen( ( char* ) string ); int num_empty_rows = 0; if (initials) { capital=1; enablecap=true; initials_rows = ((initials->maxHeight - 1) / maxHeight) - (startrow - 1); currCap = string[0] - 1; if ((startrow > 0 && initials_rows > 0) || (len > 0 && isspace(currCap))) { // we need to look back to get the cap while(isspace(currCap) && num_empty_rows < (int)len) { //we cant cap whitespace so keep looking currCap = string[++num_empty_rows] - 1; // WARNING: this assumes all preceeding whitespace is an empty line } last_initial_row = (startrow - 1); initials_rows--; } } unsigned int psx = PARAGRAPH_START_X; Palette *pal = hicolor; if (!pal) { pal = palette; } if (initials==this) { enablecap=false; } sprBuffer->SetPalette( pal ); char* tmp = ( char* ) malloc( len + 1 ); memcpy( tmp, ( char * ) string, len + 1 ); SetupString( tmp, rgn.w, NoColor, initials, enablecap ); if (startrow) enablecap=false; int ystep = 0; if (Alignment & IE_FONT_SINGLE_LINE) { for (size_t i = 0; i < len; i++) { int height = yPos[( unsigned char ) tmp[i] - 1]; if (ystep < height) ystep = height; } } else { ystep = size[1].h; } if (!ystep) ystep = maxHeight; int x = psx, y = ystep; int w = CalcStringWidth( tmp, NoColor ); if (Alignment & IE_FONT_ALIGN_CENTER) { x = ( rgn.w - w) / 2; } else if (Alignment & IE_FONT_ALIGN_RIGHT) { x = ( rgn.w - w ); } if (Alignment & IE_FONT_ALIGN_MIDDLE) { int h = 0; for (size_t i = 0; i <= len; i++) { if (( tmp[i] == 0 ) || ( tmp[i] == '\n' )) h++; } h = h * ystep; y += ( rgn.h - h ) / 2; } else if (Alignment & IE_FONT_ALIGN_BOTTOM) { int h = 1; for (size_t i = 0; i <= len; i++) { if (( tmp[i] == 0 ) || ( tmp[i] == '\n' )) h++; } h = h * ystep; y += ( rgn.h - h ); } else if (Alignment & IE_FONT_ALIGN_TOP) { y += 5; } Video* video = core->GetVideoDriver(); int row = 0; for (size_t i = 0; i < len; i++) { if (( ( unsigned char ) tmp[i] ) == '[' && !NoColor) { i++; char tag[256]; tag[0]=0; for (int k = 0; k < 256 && i<len; k++) { if (tmp[i] == ']') { tag[k] = 0; break; } tag[k] = tmp[i++]; } if (strnicmp( tag, "capital=",8)==0) { sscanf( tag, "capital=%d", &capital); if (capital && (row>=startrow) ) { enablecap=true; } continue; } if (strnicmp( tag, "color=", 6 ) == 0) { unsigned int r,g,b; if (sscanf( tag, "color=%02X%02X%02X", &r, &g, &b ) != 3) continue; const Color c = {(unsigned char) r,(unsigned char)g, (unsigned char)b, 0}; Palette* newPal = core->CreatePalette( c, palette->back ); sprBuffer->SetPalette( newPal ); gamedata->FreePalette( newPal ); continue; } if (stricmp( tag, "/color" ) == 0) { sprBuffer->SetPalette( pal ); continue; } if (stricmp( "p", tag ) == 0) { psx = x; continue; } if (stricmp( "/p", tag ) == 0) { psx = PARAGRAPH_START_X; } continue; } if (row < startrow) { if (tmp[i] == 0) { row++; } continue; } if (( tmp[i] == 0 ) || ( tmp[i] == '\n' )) { y += ystep; x = psx; int w = CalcStringWidth( &tmp[i + 1], NoColor ); if (initials_rows > 0) { initials_rows--; x += initials_x; w += initials_x; } if (Alignment & IE_FONT_ALIGN_CENTER) { x = ( rgn.w - w ) / 2; } else if (Alignment & IE_FONT_ALIGN_RIGHT) { x = ( rgn.w - w ); } continue; } unsigned char currChar = ( unsigned char ) tmp[i] - 1; if (initials && capital && enablecap) { currCap = currChar; x = initials->PrintInitial( x, y, rgn, currChar ); initials_x = x; //how many more lines to be indented (one was already indented) initials_rows = (initials->maxHeight-1)/maxHeight; initials_row = row; last_initial_row = initials_row; enablecap = false; continue; } else if(initials && currCap && row > last_initial_row && (row - num_empty_rows - initials_row) <= ((initials->maxHeight-1)/maxHeight)) { // means this row doesnt have a cap, but a preceeding one did and its overlapping this row int initY = y; if (!num_empty_rows) {// num_empty_rows is for scrolling text areas initY = (y - (maxHeight * (row - initials_row))); } x = initials->PrintInitial( x, initY, rgn, currCap ); initials_x = x; x += psx; last_initial_row++; } video->BlitSpriteRegion( sprBuffer, size[currChar], x + rgn.x, y + rgn.y - yPos[currChar], true, &rgn ); if (cursor && ( i == curpos )) { video->BlitSprite( cursor, x + rgn.x, y + rgn.y, true, &rgn ); } x += size[currChar].w; } if (cursor && ( curpos == len )) { video->BlitSprite( cursor, x + rgn.x, y + rgn.y, true, &rgn ); } free( tmp ); }
void Font::PrintFromLine(int startrow, Region rgn, const unsigned char* string, Palette* hicolor, unsigned char Alignment, Font* initials, Sprite2D* cursor, unsigned int curpos, bool NoColor) const { bool enablecap=false; int capital = 0; if (initials) { capital=1; enablecap=true; } int initials_rows = 0; int initials_x = 0; unsigned int psx = PARAGRAPH_START_X; Palette *pal = hicolor; if (!pal) { pal = palette; } if (startrow) enablecap=false; if (initials==this) { enablecap=false; } sprBuffer->SetPalette( pal ); size_t len = strlen( ( char* ) string ); char* tmp = ( char* ) malloc( len + 1 ); memcpy( tmp, ( char * ) string, len + 1 ); SetupString( tmp, rgn.w, NoColor, initials, enablecap ); int ystep = 0; if (Alignment & IE_FONT_SINGLE_LINE) { for (size_t i = 0; i < len; i++) { int height = yPos[( unsigned char ) tmp[i] - 1]; if (ystep < height) ystep = height; } } else { ystep = size[1].h; } if (!ystep) ystep = maxHeight; int x = psx, y = ystep; int w = CalcStringWidth( tmp, NoColor ); if (Alignment & IE_FONT_ALIGN_CENTER) { x = ( rgn.w - w) / 2; } else if (Alignment & IE_FONT_ALIGN_RIGHT) { x = ( rgn.w - w ); } if (Alignment & IE_FONT_ALIGN_MIDDLE) { int h = 0; for (size_t i = 0; i <= len; i++) { if (( tmp[i] == 0 ) || ( tmp[i] == '\n' )) h++; } h = h * ystep; y += ( rgn.h - h ) / 2; } else if (Alignment & IE_FONT_ALIGN_BOTTOM) { int h = 1; for (size_t i = 0; i <= len; i++) { if (( tmp[i] == 0 ) || ( tmp[i] == '\n' )) h++; } h = h * ystep; y += ( rgn.h - h ); } else if (Alignment & IE_FONT_ALIGN_TOP) { y += 5; } Video* video = core->GetVideoDriver(); int row = 0; for (size_t i = 0; i < len; i++) { if (( ( unsigned char ) tmp[i] ) == '[' && !NoColor) { i++; char tag[256]; tag[0]=0; for (int k = 0; k < 256 && i<len; k++) { if (tmp[i] == ']') { tag[k] = 0; break; } tag[k] = tmp[i++]; } if (strnicmp( tag, "capital=",8)==0) { sscanf( tag, "capital=%d", &capital); if (capital && (row>=startrow) ) { enablecap=true; } continue; } if (strnicmp( tag, "color=", 6 ) == 0) { unsigned int r,g,b; if (sscanf( tag, "color=%02X%02X%02X", &r, &g, &b ) != 3) continue; const Color c = {(unsigned char) r,(unsigned char)g, (unsigned char)b, 0}; Palette* newPal = core->CreatePalette( c, palette->back ); sprBuffer->SetPalette( newPal ); gamedata->FreePalette( newPal ); continue; } if (stricmp( tag, "/color" ) == 0) { sprBuffer->SetPalette( pal ); continue; } if (stricmp( "p", tag ) == 0) { psx = x; continue; } if (stricmp( "/p", tag ) == 0) { psx = PARAGRAPH_START_X; } continue; } if (row < startrow) { if (tmp[i] == 0) { row++; } continue; } if (( tmp[i] == 0 ) || ( tmp[i] == '\n' )) { y += ystep; x = psx; int w = CalcStringWidth( &tmp[i + 1], NoColor ); if (initials_rows > 0) { initials_rows--; x += initials_x; w += initials_x; } if (Alignment & IE_FONT_ALIGN_CENTER) { x = ( rgn.w - w ) / 2; } else if (Alignment & IE_FONT_ALIGN_RIGHT) { x = ( rgn.w - w ); } continue; } unsigned char currChar = ( unsigned char ) tmp[i] - 1; if (initials && capital && enablecap) { x = initials->PrintInitial( x, y, rgn, currChar ); initials_x = x; //how many more lines to be indented (one was already indented) initials_rows = (initials->maxHeight-1)/maxHeight; enablecap = false; continue; } video->BlitSpriteRegion( sprBuffer, size[currChar], x + rgn.x, y + rgn.y - yPos[currChar], true, &rgn ); if (cursor && ( i == curpos )) { video->BlitSprite( cursor, x + rgn.x, y + rgn.y, true, &rgn ); } x += size[currChar].w; } if (cursor && ( curpos == len )) { video->BlitSprite( cursor, x + rgn.x, y + rgn.y, true, &rgn ); } free( tmp ); }