Skip to content

Commit

Permalink
Getting ETML support done
Browse files Browse the repository at this point in the history
  • Loading branch information
ZILtoid1991 committed Aug 27, 2023
1 parent dd4724b commit 7beb278
Show file tree
Hide file tree
Showing 25 changed files with 720 additions and 56 deletions.
14 changes: 14 additions & 0 deletions assets/test5.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ETML>
<etml>
<text id="example1">
Hello world! <br />
This is an examle of a <i>multiline</i> text done in ETML.
</text>
<text id="example2">
This even supports Unicode characters as long as the target system is capable of displaying them. <br />
árvíztűrő tükörfúrógép ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP <br />
おはよう世界、これは日本語だよねー。または、カタカナも使える! <br />
ハルフウィットカタカナ
</text>
</etml>
4 changes: 2 additions & 2 deletions docs/formats/ETML.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ other tags. The `id` attribute is mandatory.
# Example document

```xml
<!xml version = "1.0" encoding = "utf8">
<?DOCTYPE ETML?>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ETML>
<etml>
<text id="example1">
Hello world! <br />
Expand Down
9 changes: 9 additions & 0 deletions dub.sdl
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,15 @@ subPackage {
sourcePaths "./test3/"
importPaths "./test3/"
}
subPackage {
name "test5"
dependency "pixelperfectengine" version="*"
targetType "executable"
targetPath "./bin-$ARCH-$PLATFORM/"
lflags "/PDB:.\\bin-$ARCH-$PLATFORM\\pixelperfectengine_test5.pdb" platform="windows"
sourcePaths "./test5/"
importPaths "./test5/"
}
subPackage {
name "wmfc"
dependency "pixelperfectengine" version="*"
Expand Down
32 changes: 24 additions & 8 deletions pixelperfectengine/src/pixelperfectengine/graphics/draw.d
Original file line number Diff line number Diff line change
Expand Up @@ -242,15 +242,29 @@ public class BitmapDrawer{
* lineOffset specifies how much lines in pixels are skipped on the top.
* Return value contains state flags on wheter certain portions of the text were out of bound.
*/
public uint drawMultiLineText(Coordinate pos, Text text, int offset = 0, int lineOffset = 0) pure {
int lineCount = lineOffset;
public uint drawMultiLineText(Box pos, Text text, int offset = 0, int lineOffset = 0) {
Text[] lineChunks = text.breakTextIntoMultipleLines(pos.width);
assert (lineChunks.length);
return drawMultiLineText(pos, lineChunks, offset, lineOffset);
}
/**
* Draws fully formatted text within a given prelimiter specified by pos.
* Offset specifies how much of the text is being obscured from the left hand side.
* lineOffset specifies how much lines in pixels are skipped on the top.
* Return value contains state flags on wheter certain portions of the text were out of bound.
*/
public uint drawMultiLineText(Box pos, Text[] lineChunks, int offset = 0, int lineOffset = 0) {
//Text[] lineChunks = text.breakTextIntoMultipleLines(pos.width);
int lineNum;
const int maxLines = pos.height + lineOffset;
if(lineCount >= lineOffset) { //draw if linecount is greater or equal than offset
//special
}
do {

} while(lineCount < maxLines);
/* if(lineCount >= lineOffset) { //draw if linecount is greater or equal than offset
//special
} */
while (lineOffset > (maxLines * -1) && lineNum < lineChunks.length) {
drawSingleLineText(pos, lineChunks[lineNum], offset, lineOffset);
lineOffset -= lineChunks[lineNum].getHeight;
lineNum++;
}
return 0;
}
/**
Expand All @@ -266,6 +280,7 @@ public class BitmapDrawer{

const int textWidth = text.getWidth(); //Total with of the text
if (textWidth < offset) return TextDrawStatus.TooMuchOffset;
if (text.font.size < lineOffset) return TextDrawStatus.TooMuchLineOffset;
int pX = text.frontTab; //The current position, where the first letter will be drawn

//Currently it was chosen to use a workpad to make things simpler
Expand Down Expand Up @@ -418,4 +433,5 @@ enum TextDrawStatus : uint {
TPOutOfBound = 0x00_04, ///Top portion out of bound
BPOutOfBound = 0x00_08, ///Bottom portion out of bound
TooMuchOffset = 0x1_00_00,
TooMuchLineOffset = 0x1_00_01,
}
52 changes: 31 additions & 21 deletions pixelperfectengine/src/pixelperfectengine/graphics/fontsets.d
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,18 @@ static import std.stdio;
public class Fontset(T)
if(T.stringof == Bitmap8Bit.stringof || T.stringof == Bitmap16Bit.stringof || T.stringof == Bitmap32Bit.stringof) {
//If the kerning map will cost too much memory etc, this will be used instead.
/+protected struct KerningInfo {
protected struct KerningInfo {
align(2):
dchar a;
dchar b;
short amount;
}+/
}
//public Font fontinfo; ///BMFont information on drawing the letters (might be removed later on)
alias CharMap = TreeMap!(dchar, Font.Char, true);
alias KerningMapB = TreeMap!(dchar, short, true);
alias KerningMap = TreeMap!(dchar, KerningMapB, true);
//alias CharMap = TreeMap!(dchar, Font.Char, true);
alias CharMap = Font.Char[];
/* alias KerningMapB = TreeMap!(dchar, short, true);
alias KerningMap = TreeMap!(dchar, KerningMapB, true); */
alias KerningMap = KerningInfo[];
protected CharMap _chars; ///Contains character information in a fast lookup form
protected KerningMap _kerning; ///Contains kerning information
public T[] pages; ///Character pages
Expand All @@ -49,18 +51,20 @@ public class Fontset(T)
buffer.length = cast(size_t)file.size;
file.rawRead(buffer);
Font fontinfo = parseFnt(buffer);
foreach(ch; fontinfo.chars){
/* foreach(ch; fontinfo.chars){
_chars[ch.id] = ch;
}
} */
_chars = fontinfo.chars;
foreach(krn; fontinfo.kernings){
KerningMapB* mapB = _kerning.ptrOf(krn.first);
_kerning ~= KerningInfo(krn.first, krn.second, krn.amount);
/* KerningMapB* mapB = _kerning.ptrOf(krn.first);
if (mapB !is null) {
(*mapB)[krn.second] = krn.amount;
} else {
KerningMapB newMap;
newMap[krn.second] = krn.amount;
_kerning[krn.first] = newMap;
}
} */
//_kerning[krn.first][krn.second] = krn.amount;
}
_size = fontinfo.info.fontSize;
Expand Down Expand Up @@ -120,11 +124,11 @@ public class Fontset(T)
public string getName() @nogc @safe nothrow pure @property const {
return name;
}
///Returns the height of the font.
/* ///Returns the height of the font.
///WILL BE DEPRECATED!
public deprecated int getSize() @nogc @safe nothrow pure const {
return _size;
}
} */
///returns the height of the font.
public int size() @nogc @safe nothrow pure @property const {
return _size;
Expand All @@ -141,23 +145,29 @@ public class Fontset(T)
* Returns the character info if present, or a substitute from either a fallback font if it found in them or
* the default substitute character (0xFFFD)
*/
public Font.Char chars(dchar i) @nogc @trusted nothrow pure {
Font.Char result = _chars[i];
if(result.id != dchar.init) return result;
else {
foreach(fntSt ; fallbacks) {
result = fntSt.chars(i);
if(result.id != dchar.init) return result;
}
public Font.Char chars(dchar c) @nogc @trusted nothrow pure {
foreach (key; _chars) {
if (key.id == c)
return key;
}
assert(c != 0xFFFD);
foreach(fntSt ; fallbacks) {
Font.Char result = fntSt.chars(c);
if(result.id != dchar.init) return result;
}
return _chars[0xFFFD];

return chars(0xFFFD);
}
/**
* Returns the kerning for the given character pair if there's any, or 0.
* Should be called through CharacterFormattingInfo, which can bypass it if formatting flag is enabled.
*/
public final short getKerning(const dchar first, const dchar second) @nogc @safe pure nothrow {
return _kerning[first][second];
foreach (KerningInfo key ; _kerning) {
if (key.a == first && key.b == second)
return key.amount;
}
return 0;
}
/**
* Breaks the input text into multiple lines according to the parameters.
Expand Down
11 changes: 0 additions & 11 deletions pixelperfectengine/src/pixelperfectengine/graphics/raster.d
Original file line number Diff line number Diff line change
Expand Up @@ -195,21 +195,10 @@ public class Raster : IRaster, PaletteContainer{
public void addRefreshListener(RefreshListener r){
rL ~= r;
}
///Edits the given color index.
///Will be set deprecated in 0.10.0
public void editColor(ushort c, Color val){
_palette[c] = val;
}
///Sets the number of colors.
///Will be set deprecated in 0.10.0
public void setupPalette(int i) {
_palette.length = i;
}
///Replaces the layer at the given number.
///Deprecated!
public deprecated void replaceLayer(Layer l, int i){
addLayer(l, i);
}
///Adds a layer at the given priority.
public void addLayer(Layer l, int i) @safe pure nothrow {
l.setRasterizer(rX, rY);
Expand Down
31 changes: 23 additions & 8 deletions pixelperfectengine/src/pixelperfectengine/graphics/text.d
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,9 @@ public class TextTempl(BitmapType = Bitmap8Bit) {
if (next && end > 0) return localWidth + next.getWidth(begin, end);
else return localWidth;
}
public int getHeight() @safe pure {
return formatting.rowHeight;
}
/**
* Returns the number of characters fully offset by the amount of pixel.
*/
Expand Down Expand Up @@ -271,31 +274,43 @@ public class TextTempl(BitmapType = Bitmap8Bit) {
if (currentLineLength + currentWordLength <= width) { //Check if there's enough space in the line for the current word, if no, then start new word.
currentLineLength += currentWordLength;
currentLine._text ~= currentWord ~ ch;
currentWord.length = 0;
currentWordLength = 0;
} else {
result ~= currentLine;
currentLine = new TextTempl!(BitmapType)(null, curr.formatting, null, 0, null);
currentChunk = currentLine;
currentWord.length = 0;
currentWordLength = 0;
currentLineLength = 0;
}
} else {
if (currentWordLength > width) { //Break word to avoid going out of the line
result ~= currentLine;
result ~= new TextTempl!(BitmapType)(currentWord.idup, curr.formatting, null, 0, null);
currentWord.length = 0;
currentWordLength = curr.formatting.font.chars(ch).xadvance;
currentLine = new TextTempl!(BitmapType)(null, curr.formatting, null, curr.frontTab, curr.icon);
currentChunk = currentLine;
currentWord.length = 0;
currentWordLength = 0;
}
currentWord ~= ch;
}
}
curr = curr.next;
if (curr.flags.newLine || curr.flags.newParagraph) { //Force text breakage, put text chunk into the array.
if (currentLine._text.length) {
result ~= currentLine;
currentLine = new TextTempl!(BitmapType)(null, curr.formatting, null, curr.frontTab, curr.icon);
currentChunk = currentLine;
} else {
currentChunk = new TextTempl!(BitmapType)(null, curr.formatting, null, curr.frontTab, curr.icon);
currentLine.addToEnd(currentChunk);
currentLine = new Text(null, curr.formatting, null, curr.frontTab, curr.icon);
}
curr = curr.next;
if (curr) {
if (curr.flags.newLine || curr.flags.newParagraph) { //Force text breakage, put text chunk into the array.
result ~= currentLine;
currentLine = new TextTempl!(BitmapType)(null, curr.formatting, null, curr.frontTab, curr.icon);
currentChunk = currentLine;
} else {
currentChunk = new TextTempl!(BitmapType)(null, curr.formatting, null, curr.frontTab, curr.icon);
currentLine.addToEnd(currentChunk);
}
}
}
return result;
Expand Down
14 changes: 10 additions & 4 deletions pixelperfectengine/src/pixelperfectengine/system/lang/textparser.d
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,12 @@ public class TextParserTempl(BitmapType = Bitmap8Bit)
private bool inTextChunk;///Set to true if currently in a text chunk to allow detection of cascading

///Creates a new instance with a select string input.
public this(dstring _input, CharacterFormattingInfo!BitmapType val) @safe pure nothrow {
///Params:
/// _input = the input text containing the xml file.
/// _defFrmt = the default character formatting
public this(dstring _input, CharacterFormattingInfo!BitmapType _defFrmt) @safe pure nothrow {
this._input = _input;
chrFrmt = [val];
chrFrmt = [_defFrmt];
}
///Gets the default formatting
public CharacterFormattingInfo!BitmapType defaultFormatting() @property @safe pure nothrow @nogc {
Expand All @@ -65,12 +68,15 @@ public class TextParserTempl(BitmapType = Bitmap8Bit)
parser.setSource(_input);
parser.onElementStart = &onElementStart;
parser.onElementEnd = &onElementEnd;
parser.onText = &onText;
try {
parser.processDocument();
} catch (XMLException e) { //XML formatting issue
throw new XMLTextParsingException("XML file is badly formatted!", e);
} catch (RangeError e) { //Missing mandatory attributes
throw new XMLTextParsingException("Missing mandatory attribute found!", e);
} finally {
_input.length = 0;
}
}
protected void onText(dstring content) @safe {
Expand Down Expand Up @@ -269,8 +275,8 @@ public class TextParserTempl(BitmapType = Bitmap8Bit)
currTextBlock.formatting = namedFormats[toUTF8(attributes["id"])];
}
protected void onFormatDefElement(dstring[dstring] attributes) @safe {
bool checkBoolean(dstring val) @safe {
if (val == "true" || val == "yes")
bool checkBoolean(dstring defFrmt) @safe {
if (defFrmt == "true" || defFrmt == "yes")
return true;
else
return false;
Expand Down
Binary file added system/unifont-15.0.01-0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added system/unifont-15.0.01-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added system/unifont-15.0.01-10.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added system/unifont-15.0.01-11.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added system/unifont-15.0.01-12.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added system/unifont-15.0.01-13.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added system/unifont-15.0.01-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added system/unifont-15.0.01-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added system/unifont-15.0.01-4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added system/unifont-15.0.01-5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added system/unifont-15.0.01-6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added system/unifont-15.0.01-7.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added system/unifont-15.0.01-8.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added system/unifont-15.0.01-9.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added system/unifont-15.0.01.fnt
Binary file not shown.
Loading

0 comments on commit 7beb278

Please sign in to comment.