include "font.s7i";
include "pixmapfont.s7i";
include "pixmap_file.s7i";
const type: charVectorType is new struct
var integer: width is 0;
var array pointList: points is 0 times pointList.value;
end struct;
const type: fontVectorType is hash [char] charVectorType;
const type: vectorFont is sub fontProperties struct
var fontVectorType: fontVectors is fontVectorType.value;
end struct;
type_implements_interface(vectorFont, font);
const func integer: width (in vectorFont: vecFont, in string: stri) is func
result
var integer: width is 0;
local
var char: ch is ' ';
begin
for ch range stri do
if ch in vecFont.fontVectors then
width +:= vecFont.fontVectors[ch].width;
else
width +:= vecFont.fontVectors[' '].width;
end if;
end for;
width +:= vecFont.characterSpacing * length(stri);
end func;
const func integer: numOfCharsInWidth (in vectorFont: vecFont,
in string: stri, in integer: allowedWidth) is func
result
var integer: numOfChars is 0;
local
var integer: index is 1;
var integer: totalWidth is 0;
begin
while index <= length(stri) and totalWidth <= allowedWidth do
if stri[index] in vecFont.fontVectors then
totalWidth +:= vecFont.fontVectors[stri[index]].width;
else
totalWidth +:= vecFont.fontVectors[' '].width;
end if;
totalWidth +:= vecFont.characterSpacing;
if totalWidth <= allowedWidth then
incr(index);
end if;
end while;
numOfChars := pred(index);
end func;
const func PRIMITIVE_WINDOW: genPixmap (in vectorFont: vecFont, in charVectorType: charVectors,
in color: foreground, in color: background, in integer: scale) is func
result
var PRIMITIVE_WINDOW: pixmap is PRIMITIVE_WINDOW.value;
local
var integer: height is 0;
var integer: width is 0;
var integer: index is 0;
begin
height := lineHeight(vecFont);
width := charVectors.width;
pixmap := newPixmap(width * scale, height * scale);
clear(pixmap, background);
if scale = 1 then
for index range 1 to length(charVectors.points) do
fpolyLine(pixmap, 0, 0, charVectors.points[index], foreground);
end for;
else
for index range 1 to length(charVectors.points) do
fpolyLine(pixmap, 0, 0, scale(charVectors.points[index], scale), foreground);
end for;
end if;
end func;
const func pixmapFontType: genPixmapFont (in vectorFont: vecFont,
in integer: fontSize, in integer: scale,
in color: foreground, in color: background) is func
result
var pixmapFontType: pixmapFont is pixmapFontType.value;
begin
if ' ' in vecFont.fontVectors then
incl(pixmapFont.pixmap, ' ', genPixmap(vecFont, vecFont.fontVectors[' '],
foreground, background, scale));
end if;
pixmapFont.baseFont := vecFont;
pixmapFont.fontSize := fontSize;
pixmapFont.scale := scale;
pixmapFont.foreground := foreground;
pixmapFont.background := background;
pixmapFont.baseLineDelta := baseLineDelta(vecFont) * scale;
pixmapFont.line_delta := lineHeight(vecFont) * scale;
pixmapFont.column_delta := columnWidth(vecFont) * scale;
pixmapFont.characterSpacing := characterSpacing(vecFont) * scale;
end func;
const func PRIMITIVE_WINDOW: getFontCharPixmap (in vectorFont: vecFont,
inout pixmapFontType: pixmapFont, in char: ch) is func
result
var PRIMITIVE_WINDOW: charPixmap is PRIMITIVE_WINDOW.value;
begin
if ch in vecFont.fontVectors then
charPixmap := genPixmap(vecFont, vecFont.fontVectors[ch],
pixmapFont.foreground, pixmapFont.background, pixmapFont.scale);
incl(pixmapFont.pixmap, ch, charPixmap);
else
charPixmap := pixmapFont.pixmap[' '];
end if;
end func;
const proc: setFont (inout pixmapFontFile: fontFile, in vectorFont: aFont) is func
begin
fontFile.font := getFont(aFont, fontSize(fontFile.font),
scale(fontFile.font), foreground(fontFile.font), background(fontFile.font));
end func;
const func pointList: pline (in array integer: points) is
return genPointList(points);
const func pointList: fillp (in array integer: points) is
return genPointList(points);
const proc: incl (inout fontVectorType: fontVectors, in char: ch, in integer: width,
in array pointList: points) is func
local
var charVectorType: charDescription is charVectorType.value;
begin
charDescription.width := width;
charDescription.points := points;
incl(fontVectors, ch, charDescription);
end func;
const func integer: columnWidth (in fontVectorType: fontVectors) is func
result
var integer: maxWidth is 0;
local
var char: ch is ' ';
begin
for key ch range fontVectors do
if fontVectors[ch].width > maxWidth then
maxWidth := fontVectors[ch].width;
end if;
end for;
end func;