package domain;
import static core.Script.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
/// The VERGE 3 Project is originally by Ben Eirich and is made available via
/// the BSD License.
///
/// Please see LICENSE in the project's root directory for the text of the
/// licensing agreement. The CREDITS file in the same directory enumerates the
/// folks involved in this public build.
///
/// If you have altered this source file, please log your name, date, and what
/// changes you made below this line.
/****************************************************************
xerxes engine
g_font.cpp
****************************************************************/
public class VFont {
VImage rawdata[];
public int width, height;
int subsets, selected;
int totalframes;
int fwidth[] = new int[100];
boolean incolor;
public VFont(URL url, int xsize, int ysize)
{
width = xsize;
height = ysize;
readFont(url, xsize, ysize);
}
public VFont(URL url)
{
int w, h;
// this constructor autodetected cell dimensions, B
VImage workingimage = new VImage(url);
// Analyze image and guess cell dimensions.
int bgcolor = workingimage.readPixel(0, 0); // This is the image bg color;
for (w=1; w<workingimage.width; w++)
{
int z = workingimage.readPixel(w, 1);
if (z == bgcolor)
break;
}
for (h=1; h<workingimage.height; h++)
{
int z = workingimage.readPixel(1, h);
if (z == bgcolor)
break;
}
width = w-1;
height = h-1;
readFont(url, width, height);
}
private void readFont(URL url, int xsize, int ysize) {
VImage workingimage = new VImage(url);
subsets = workingimage.width / ((ysize*5)+4);
selected = 0;
incolor = false;
rawdata = new VImage[100*subsets];
int imageindex = 0;
for (int yl = 0; yl<5 * subsets; yl++)
for (int xl = 0; xl<20; xl++) {
rawdata[imageindex] = new VImage(xsize, ysize);
rawdata[imageindex++].grabRegion(1+(xl*(xsize+1)), 1+(yl*(ysize+1)), width+1+(xl*(xsize+1)), height+1+(yl*(ysize+1)),
0, 0, workingimage);
}
for (int i=0; i<100; i++)
fwidth[i] = xsize; // + 1 (commented by [Rafael, the Esper])
}
boolean ColumnEmpty(int cell, int column, int tcolor)
{
//container.data = ((int) rawdata.data + ((cell)*width*height*vid_bytesperpixel));
for (int y=0; y<rawdata[cell].height; y++)
if (rawdata[cell].readPixel(column, y) != tcolor)
return false;
return true;
}
public void EnableVariableWidth()
{
fwidth[0] = width * 60 / 100;
int tcolor = rawdata[0].readPixel(0, 0);
for (int i=1; i<100; i++)
{
fwidth[i] = -1;
for (int x=width-1; x>=0; x--)
{
if (!ColumnEmpty(i, x, tcolor))
{
fwidth[i] = x + 1;
break;
}
}
if (fwidth[i]==-1)
fwidth[i] = width * 60 / 100;
//System.out.println(((char)(i+32)) + " " + fwidth[i]);
}
}
void SetCharacterWidth(int character, int width)
{
fwidth[character] = width;
}
public void PrintChar(char c, int x, int y, VImage dest)
{
if (c<32 || c>=128)
return;
dest.tblit(x, y, rawdata[c-32].image);
//dest.g.drawImage(rawdata[c-32].image, x, y, null);
//TBlit(x, y, container, dest);
}
// print a chunk of a string; doesn't care about newlines
// called from PrintString, PrintCenter, and PrintRight, which DO care about newlines
public void PrintLine(String s, int x, int y, VImage dest)
{
for (int pos=0; pos < s.length(); pos++)
{
if (s.charAt(pos) == '\f')
{
/*
// what's wrong with just using \f0?
if (incolor)
{
selected = 0;
incolor = false;
continue;
}
*/
selected = s.charAt(pos) - '0';
if (selected >= subsets || selected < 0)
selected = 0;
else
incolor = true;
continue;
}
PrintChar(s.charAt(pos), x, y, dest);
if (s.charAt(pos) < 32) continue;
x += fwidth[s.charAt(pos) - 32]+1;
}
}
public void PrintString(String msg, int x, int y, VImage dest)
{
int start = 0, end = 0;
for (end = 0; end < msg.length(); end++)
{
if (msg.charAt(end) == '\n' || msg.charAt(end) == '\r')
{
PrintLine(msg.substring(0, end),x,y,dest);
// Check for \r\n so they aren't parsed as two separate line breaks.
if (msg.charAt(end) == '\r' && msg.length() > end+1 && msg.charAt(end+1) == '\n')
end++;
start = end + 1;
y += height;
}
}
PrintLine(msg.substring(start, end),x,y,dest);
}
public void PrintRight(String msg, int x, int y, VImage dest)
{
int xsize = 0;
int start = 0, end = 0;
if(msg==null)
return;
for (end = 0; end < msg.length(); end++)
{
if (msg.charAt(end) == '\n' || msg.charAt(end) == '\r')
{
xsize = Pixels(msg.substring(0, end));
PrintLine(msg.substring(0, end),x - (xsize),y,dest);
// Check for \r\n so they aren't parsed as two separate line breaks.
if (msg.charAt(end) == '\r' && msg.length() > end+1 && msg.charAt(end+1) == '\n')
end++;
start = end + 1;
y += height;
}
}
xsize = Pixels(msg.substring(start, end));
PrintLine(msg.substring(start, end),x - xsize,y,dest);
selected=0;
incolor = false;
}
public void PrintCenter(String msg, int x, int y, VImage dest)
{
int xsize = 0;
int start = 0, end = 0;
for (end = 0; end < msg.length(); end++)
{
if (msg.charAt(end) == '\n' || msg.charAt(end) == '\r')
{
xsize = Pixels(msg.substring(0, end));
PrintLine(msg.substring(0, end),x - (xsize/2),y,dest);
// Check for \r\n so they aren't parsed as two separate line breaks.
if (msg.charAt(end) == '\r' && msg.length() > end+1 && msg.charAt(end+1) == '\n')
end++;
start = end + 1;
y += height;
}
}
xsize = Pixels(msg.substring(start, end));
PrintLine(msg.substring(start, end),x - (xsize/2),y,dest);
selected=0;
incolor = false;
}
public int Pixels(String str)
{
int xsize = 0;
boolean ic = incolor;
for (int i=0; i<str.length(); i++)
{
if (str.charAt(i) == '\f')
{
/*
// what's wrong with just using \f0?
if (incolor)
{
incolor = false;
continue;
}
*/
if (i+1 > str.length()) break;
incolor = true;
continue;
}
else
{
if (str.charAt(i) < 32) continue;
xsize += fwidth[str.charAt(i) - 32]+1;
}
}
incolor = ic; // reset the incolor flag
return xsize;
}
//VI.i. Font Functions
public void enablevariablewidth() {
this.EnableVariableWidth();
}
public int fontheight() {
//if (this==null) return 7;
return this.height;
}
public void printcenter(int x, int y, VImage d, String text) {
this.PrintCenter(text, x, y, d);
}
public void printright(int x, int y, VImage d, String text) {
this.PrintRight(text, x, y, d);
}
public void printstring(int x, int y, VImage dest, String text) {
this.PrintString(text, x, y, dest);
}
public int textwidth(String text) {
return this.Pixels(text);
}
// Overkill: 2005-12-28
// Helper function for WrapText.
int textwidth(String text, int pos, int len) {
return this.Pixels(text.substring(pos, pos+len));
}
// Rafael: changed the implementation
// Split list of words into rows
public List<String> wraptext(String wt_s, int wt_linelen) {
List<String> words = splitTextIntoWords(wt_s);
List<String> rows = new ArrayList<String>();
int i = 0;
String str;
while (i < words.size()) {
str = words.get(i);
while (i < words.size()-1 && this.textwidth(str) + this.textwidth(words.get(i+1)) <= wt_linelen) {
str = str.concat(" " + words.get(i+1));
i += 1;
}
rows.add(str); //System.out.println(str);
str = "";i+=1;
}
return rows;
}
}