summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 6cb7125)
raw | patch | inline | side by side (parent: 6cb7125)
author | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Tue, 3 Oct 2017 09:10:24 +0000 (12:10 +0300) | ||
committer | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Tue, 3 Oct 2017 09:22:53 +0000 (12:22 +0300) |
proper horizontal wrapping with size calculations/constraints is not
that easy; it makes the code way more complex, it never really worked,
and i never used it. althrough it is a great feature to have (for
proper windows resizing), it is better served by something like Yoga
(huge and complex). but i want to have a simplistic layouter, suitable
for common UI tasks, and not-so-complex layouts.
maybe i'll add that wrapping feature later, but i'm not sure. it looks
like i need a full-blown constraints solver for this feature, and i am
not ready to migrate to Cassowary yet. ;-)
tl;dr: removing horizontal wrapping allowed me to unify distribution
code, made code smaller (by ~1/3), and more readable. the price
is acceptable (for now).
that easy; it makes the code way more complex, it never really worked,
and i never used it. althrough it is a great feature to have (for
proper windows resizing), it is better served by something like Yoga
(huge and complex). but i want to have a simplistic layouter, suitable
for common UI tasks, and not-so-complex layouts.
maybe i'll add that wrapping feature later, but i'm not sure. it looks
like i need a full-blown constraints solver for this feature, and i am
not ready to migrate to Cassowary yet. ;-)
tl;dr: removing horizontal wrapping allowed me to unify distribution
code, made code smaller (by ~1/3), and more readable. the price
is acceptable (for now).
index 744ddff1bd71de3c59974e8e70b34aac3e263c92..0c809154051de215431d58616bb2a8d4bcf77b1e 100644 (file)
function isOpaque (): Boolean; inline;
function isTransparent (): Boolean; inline;
+ function toString (): AnsiString;
+
// WARNING! This function does blending in RGB space, and RGB space is not linear!
// alpha value of `self` doesn't matter
// `aa` means: 255 for replace color, 0 for keep `self`
function empty (): Boolean; inline; // invalid rects are empty too
function valid (): Boolean; inline;
+ function toString (): AnsiString;
+
// modifies this rect, so it won't be bigger than `r`
// returns `false` if this rect becomes empty
function intersect (constref r: TGxRect): Boolean; inline;
result.a := a;
end;
+function TGxRGBA.toString (): AnsiString; begin result := formatstrf('rgba(%s,%s,%s,%s)', [r, g, b, a]); end;
+
+
// ////////////////////////////////////////////////////////////////////////// //
constructor TGxRect.Create (ax, ay, aw, ah: Integer); begin x := ax; y := ay; w := aw; h := ah; end;
result := intersectRect(x, y, w, h, r.x, r.y, r.w, r.h);
end;
+function TGxRect.toString (): AnsiString; begin result := formatstrf('(%s,%s;%sx%s)', [x, y, w, h]); end;
+
// ////////////////////////////////////////////////////////////////////////// //
constructor TGxOfs.Create (axofs, ayofs: Integer); begin xofs := axofs; yofs := ayofs; end;
index 7969a2617ef52edbaeb113583ae4888d72052413..7f722fea97090a79a967d319758fefc3e020ea09 100644 (file)
--- a/src/flexui/fui_ctls.pas
+++ b/src/flexui/fui_ctls.pas
procedure calcFullClientSize ();
+ procedure drawFrame (gx, gy, resx, thalign: Integer; const text: AnsiString; dbl: Boolean);
+
protected
var savedClip: TGxRect; // valid only in `draw*()` calls
//WARNING! do not call scissor functions outside `.draw*()` API!
mMaxSize: TLaySize; // maximum size
mFlex: Integer;
mHoriz: Boolean;
- mCanWrap: Boolean;
- mLineStart: Boolean;
mHGroup: AnsiString;
mVGroup: AnsiString;
mAlign: Integer;
//procedure setMaxSize (const sz: TLaySize); inline; // max size; <0: set to some huge value
function getFlex (): Integer; inline; // <=0: not flexible
function isHorizBox (): Boolean; inline; // horizontal layout for children?
- function canWrap (): Boolean; inline; // for horizontal boxes: can wrap children? for child: `false` means 'nonbreakable at *next* ctl'
function noPad (): Boolean; inline; // ignore padding in box direction for this control
- function isLineStart (): Boolean; inline; // `true` if this ctl should start a new line; ignored for vertical boxes
function getAlign (): Integer; inline; // aligning in non-main direction: <0: left/up; 0: center; >0: right/down
function getExpand (): Boolean; inline; // expanding in non-main direction: `true` will ignore align and eat all available space
function getHGroup (): AnsiString; inline; // empty: not grouped
property flMaxSize: TLaySize read mMaxSize write mMaxSize;
property flPadding: TLaySize read mPadding write mPadding;
property flHoriz: Boolean read mHoriz write mHoriz;
- property flCanWrap: Boolean read mCanWrap write mCanWrap;
- property flLineStart: Boolean read mLineStart write mLineStart;
property flAlign: Integer read mAlign write mAlign;
property flExpand: Boolean read mExpand write mExpand;
property flHGroup: AnsiString read mHGroup write mHGroup;
function parseProperty (const prname: AnsiString; par: TTextParser): Boolean; override;
- procedure drawControl (gx, gy: Integer); override;
- end;
-
- TUIHLine = class(TUILine)
- public
- procedure AfterConstruction (); override; // so it will be correctly initialized when created from parser
- end;
+ procedure layPrepare (); override; // called before registering control in layouter
- TUIVLine = class(TUILine)
- public
- procedure AfterConstruction (); override; // so it will be correctly initialized when created from parser
+ procedure drawControl (gx, gy: Integer); override;
end;
// ////////////////////////////////////////////////////////////////////// //
actionCB := nil;
// layouter interface
//mDefSize := TLaySize.Create(64, uiContext.charHeight(' ')); // default size
- mDefSize := TLaySize.Create(0, 0); // default size
+ mDefSize := TLaySize.Create(0, 0); // default size: hidden control
mMaxSize := TLaySize.Create(-1, -1); // maximum size
mPadding := TLaySize.Create(0, 0);
mNoPad := false;
mFlex := 0;
mHoriz := true;
- mCanWrap := false;
- mLineStart := false;
mHGroup := '';
mVGroup := '';
mStyleId := '';
@@ -1000,9 +986,7 @@ function TUIControl.getMaxSize (): TLaySize; inline; begin result := mLayMaxSize
function TUIControl.getPadding (): TLaySize; inline; begin result := mPadding; end;
function TUIControl.getFlex (): Integer; inline; begin result := mFlex; end;
function TUIControl.isHorizBox (): Boolean; inline; begin result := mHoriz; end;
-function TUIControl.canWrap (): Boolean; inline; begin result := mCanWrap; end;
function TUIControl.noPad (): Boolean; inline; begin result := mNoPad; end;
-function TUIControl.isLineStart (): Boolean; inline; begin result := mLineStart; end;
function TUIControl.getAlign (): Integer; inline; begin result := mAlign; end;
function TUIControl.getExpand (): Boolean; inline; begin result := mExpand; end;
function TUIControl.getHGroup (): AnsiString; inline; begin result := mHGroup; end;
end;
mWidth := asize.w;
mHeight := asize.h;
+ if (mLayMaxSize.w >= 0) then mWidth := nmin(mWidth, mLayMaxSize.w);
+ if (mLayMaxSize.h >= 0) then mHeight := nmin(mHeight, mLayMaxSize.h);
end;
procedure TUIControl.layPrepare ();
begin
mLayDefSize := mDefSize;
- mLayMaxSize := mMaxSize;
- if (mLayMaxSize.w >= 0) then mLayMaxSize.w += mFrameWidth*2;
- if (mLayMaxSize.h >= 0) then mLayMaxSize.h += mFrameHeight*2;
+ if (mLayDefSize.w <> 0) and (mLayDefSize.h <> 0) then
+ begin
+ mLayMaxSize := mMaxSize;
+ if (mLayMaxSize.w >= 0) then begin mLayDefSize.w += mFrameWidth*2; mLayMaxSize.w += mFrameWidth*2; end;
+ if (mLayMaxSize.h >= 0) then begin mLayDefSize.h += mFrameHeight*2; mLayMaxSize.h += mFrameHeight*2; end;
+ end
+ else
+ begin
+ mLayMaxSize := TLaySize.Create(0, 0);
+ end;
end;
if (strEquCI1251(prname, 'padding')) then begin mPadding := parsePadding(par); exit; end;
if (strEquCI1251(prname, 'nopad')) then begin mNoPad := true; exit; end;
// flags
- if (strEquCI1251(prname, 'wrap')) then begin mCanWrap := parseBool(par); exit; end;
- if (strEquCI1251(prname, 'linestart')) then begin mLineStart := parseBool(par); exit; end;
if (strEquCI1251(prname, 'expand')) then begin mExpand := parseBool(par); exit; end;
// align
if (strEquCI1251(prname, 'align')) then begin mAlign := parseAnyAlign(par); exit; end;
mParent.getDrawRect(gx, gy, wdt, hgt);
if (wdt > 0) and (hgt > 0) then
begin
- if not intersectRect(gx, gy, wdt, hgt, cgx, cgy, mWidth, mHeight) then
+ if (not intersectRect(gx, gy, wdt, hgt, cgx, cgy, mWidth, mHeight)) then
begin
wdt := 0;
hgt := 0;
// ////////////////////////////////////////////////////////////////////////// //
+procedure TUIControl.drawFrame (gx, gy, resx, thalign: Integer; const text: AnsiString; dbl: Boolean);
+var
+ cidx, tx, tw: Integer;
+begin
+ if (mFrameWidth < 1) or (mFrameHeight < 1) then exit;
+ cidx := getColorIndex;
+ uiContext.color := mFrameColor[cidx];
+ case mFrameHeight of
+ 8:
+ begin
+ if dbl then
+ begin
+ uiContext.rect(gx+3, gy+3, mWidth-6, mHeight-6);
+ uiContext.rect(gx+5, gy+5, mWidth-10, mHeight-10);
+ end
+ else
+ begin
+ uiContext.rect(gx+4, gy+4, mWidth-8, mHeight-8);
+ end;
+ end;
+ 14:
+ begin
+ if dbl then
+ begin
+ uiContext.rect(gx+3, gy+3+3, mWidth-6, mHeight-6-6);
+ uiContext.rect(gx+5, gy+5+3, mWidth-10, mHeight-10-6);
+ end
+ else
+ begin
+ uiContext.rect(gx+4, gy+4+3, mWidth-8, mHeight-8-6);
+ end;
+ end;
+ 16:
+ begin
+ if dbl then
+ begin
+ uiContext.rect(gx+3, gy+3+4, mWidth-6, mHeight-6-8);
+ uiContext.rect(gx+5, gy+5+4, mWidth-10, mHeight-10-8);
+ end
+ else
+ begin
+ uiContext.rect(gx+4, gy+4+4, mWidth-8, mHeight-8-8);
+ end;
+ end;
+ else
+ begin
+ //TODO!
+ if dbl then
+ begin
+ end
+ else
+ begin
+ end;
+ end;
+ end;
+
+ // title
+ if (Length(text) > 0) then
+ begin
+ if (resx < 0) then resx := 0;
+ tw := uiContext.textWidth(text);
+ setScissor(mFrameWidth+resx, 0, mWidth-mFrameWidth*2-resx, mFrameHeight);
+ if (thalign < 0) then tx := gx+resx+mFrameWidth+2
+ else if (thalign > 0) then tx := gx+mWidth-mFrameWidth-1-tw
+ else tx := (gx+resx+mFrameWidth)+(mWidth-mFrameWidth*2-resx-tw) div 2;
+ uiContext.color := mBackColor[cidx];
+ uiContext.fillRect(tx-2, gy, tw+4, mFrameHeight);
+ uiContext.color := mFrameTextColor[cidx];
+ uiContext.drawText(tx, gy, text);
+ end;
+end;
+
+
procedure TUIControl.draw ();
var
f: Integer;
procedure resetScissor (fullArea: Boolean); inline;
begin
uiContext.clip := savedClip;
- if (fullArea) then
+ if (fullArea) or ((mFrameWidth = 0) and (mFrameHeight = 0)) then
begin
setScissor(0, 0, mWidth, mHeight);
end
else
begin
+ //writeln('frm: (', mFrameWidth, 'x', mFrameHeight, ')');
setScissor(mFrameWidth, mFrameHeight, mWidth-mFrameWidth*2, mHeight-mFrameHeight*2);
end;
end;
resetScissor(false); // client area
for f := 0 to High(mChildren) do mChildren[f].draw();
resetScissor(true); // full area
+ if (self is TUISwitchBox) then
+ begin
+ uiContext.color := TGxRGBA.Create(255, 0, 0, 255);
+ //uiContext.fillRect(gx, gy, mWidth, mHeight);
+ //writeln('frm: (', mFrameWidth, 'x', mFrameHeight, '); sz=(', mWidth, 'x', mHeight, '); clip=', uiContext.clip.toString);
+ end;
+ if false and (mId = 'cbtest') then
+ begin
+ uiContext.color := TGxRGBA.Create(255, 127, 0, 96);
+ uiContext.fillRect(gx, gy, mWidth, mHeight);
+ if (mFrameWidth > 0) and (mFrameHeight > 0) then
+ begin
+ uiContext.color := TGxRGBA.Create(255, 255, 0, 96);
+ uiContext.fillRect(gx+mFrameWidth, gy+mFrameHeight, mWidth-mFrameWidth*2, mHeight-mFrameHeight*2);
+ end;
+ end
+ else if false and (self is TUISwitchBox) then
+ begin
+ uiContext.color := TGxRGBA.Create(255, 0, 0, 255);
+ uiContext.fillRect(gx, gy, mWidth, mHeight);
+ //writeln('frm: (', mFrameWidth, 'x', mFrameHeight, ')');
+ end;
drawControlPost(gx, gy);
finally
uiContext.clip := savedClip;
inherited;
mFitToScreen := true;
mFrameWidth := 8;
- mFrameHeight := 8;
+ mFrameHeight := uiContext.charHeight(#184);
if (mWidth < mFrameWidth*2+uiContext.iconWinWidth(TGxContext.TWinIcon.Close)) then mWidth := mFrameWidth*2+uiContext.iconWinWidth(TGxContext.TWinIcon.Close);
if (mHeight < mFrameHeight*2) then mHeight := mFrameHeight*2;
if (Length(mTitle) > 0) then
mInClose := false;
closeCB := nil;
mCtl4Style := 'window';
+ mDefSize.w := nmax(1, mDefSize.w);
+ mDefSize.h := nmax(1, mDefSize.h);
end;
uiContext.fillRect(gx, gy, mWidth, mHeight);
end;
-
procedure TUITopWindow.drawControlPost (gx, gy: Integer);
var
cidx: Integer;
- tx, hgt, sbhgt, iwdt: Integer;
+ hgt, sbhgt, iwdt, ihgt: Integer;
begin
cidx := getColorIndex;
+ iwdt := uiContext.iconWinWidth(TGxContext.TWinIcon.Close);
if (mDragScroll = TXMode.Drag) then
begin
- uiContext.color := mFrameColor[cidx];
- uiContext.rect(gx+4, gy+4, mWidth-8, mHeight-8);
+ //uiContext.color := mFrameColor[cidx];
+ drawFrame(gx, gy, iwdt, 0, mTitle, false);
end
else
begin
- uiContext.color := mFrameColor[cidx];
- uiContext.rect(gx+3, gy+3, mWidth-6, mHeight-6);
- uiContext.rect(gx+5, gy+5, mWidth-10, mHeight-10);
+ ihgt := uiContext.iconWinHeight(TGxContext.TWinIcon.Close);
+ //uiContext.color := mFrameColor[cidx];
+ drawFrame(gx, gy, iwdt, 0, mTitle, true);
// vertical scroll bar
hgt := mHeight-mFrameHeight*2;
if (hgt > 0) and (mFullSize.h > hgt) then
begin
//writeln(mTitle, ': height=', mHeight-mFrameHeight*2, '; fullsize=', mFullSize.toString);
sbhgt := mHeight-mFrameHeight*2+2;
- uiContext.fillRect(gx+mWidth-mFrameWidth+1, gy+7, mFrameWidth-3, sbhgt);
+ uiContext.fillRect(gx+mWidth-mFrameWidth+1, gy+mFrameHeight-1, mFrameWidth-3, sbhgt);
hgt += mScrollY;
if (hgt > mFullSize.h) then hgt := mFullSize.h;
hgt := sbhgt*hgt div mFullSize.h;
if (hgt > 0) then
begin
- setScissor(mWidth-mFrameWidth+1, 7, mFrameWidth-3, sbhgt);
- uiContext.darkenRect(gx+mWidth-mFrameWidth+1, gy+7+hgt, mFrameWidth-3, sbhgt, 128);
+ setScissor(mWidth-mFrameWidth+1, mFrameHeight-1, mFrameWidth-3, sbhgt);
+ uiContext.darkenRect(gx+mWidth-mFrameWidth+1, gy+mFrameHeight-1+hgt, mFrameWidth-3, sbhgt, 128);
end;
end;
// frame icon
- iwdt := uiContext.iconWinWidth(TGxContext.TWinIcon.Close);
- setScissor(mFrameWidth, 0, iwdt, 8);
+ setScissor(mFrameWidth, 0, iwdt, ihgt);
uiContext.color := mBackColor[cidx];
- uiContext.fillRect(gx+mFrameWidth, gy, iwdt, 8);
+ uiContext.fillRect(gx+mFrameWidth, gy, iwdt, ihgt);
uiContext.color := mFrameIconColor[cidx];
uiContext.drawIconWin(TGxContext.TWinIcon.Close, gx+mFrameWidth, gy, mInClose);
end;
- // title
- if (Length(mTitle) > 0) then
- begin
- iwdt := uiContext.iconWinWidth(TGxContext.TWinIcon.Close);
- setScissor(mFrameWidth+iwdt, 0, mWidth-mFrameWidth*2-iwdt, 8);
- tx := (gx+iwdt)+((mWidth-iwdt)-uiContext.textWidth(mTitle)) div 2;
- uiContext.color := mBackColor[cidx];
- uiContext.fillRect(tx-3, gy, uiContext.textWidth(mTitle)+3+2, 8);
- uiContext.color := mFrameTextColor[cidx];
- uiContext.drawText(tx, gy, mTitle);
- end;
// shadow
inherited drawControlPost(gx, gy);
end;
begin
if (ev.press) then
begin
- if (ly < 8) then
+ if (ly < mFrameHeight) then
begin
uiGrabCtl := self;
if (lx >= mFrameWidth) and (lx < mFrameWidth+uiContext.iconWinWidth(TGxContext.TWinIcon.Close)) then
mCanFocus := false;
mHAlign := -1; // left
mCtl4Style := 'box';
+ mDefSize := TLaySize.Create(-1, -1);
end;
procedure TUIBox.setHasFrame (v: Boolean);
begin
mHasFrame := v;
- if (mHasFrame) then begin mFrameWidth := 8; mFrameHeight := 8; end else begin mFrameWidth := 0; mFrameHeight := 0; end;
+ if (mHasFrame) then begin mFrameWidth := 8; mFrameHeight := uiContext.charHeight(#184); end else begin mFrameWidth := 0; mFrameHeight := 0; end;
if (mHasFrame) then mNoPad := true;
end;
cidx := getColorIndex;
uiContext.color := mBackColor[cidx];
uiContext.fillRect(gx, gy, mWidth, mHeight);
- if mHasFrame then
+ if (mHasFrame) then
begin
// draw frame
- uiContext.color := mFrameColor[cidx];
- uiContext.rect(gx+3, gy+3, mWidth-6, mHeight-6);
- end;
- // draw caption
- if (Length(mCaption) > 0) then
+ drawFrame(gx, gy, 0, -1, mCaption, false);
+ //uiContext.color := mFrameColor[cidx];
+ //uiContext.rect(gx+3, gy+3, mWidth-6, mHeight-6);
+ end
+ else if (Length(mCaption) > 0) then
begin
+ // draw caption
if (mHAlign < 0) then xpos := 3
else if (mHAlign > 0) then xpos := mWidth-mFrameWidth*2-uiContext.textWidth(mCaption)
else xpos := (mWidth-mFrameWidth*2-uiContext.textWidth(mCaption)) div 2;
xpos += gx+mFrameWidth;
- setScissor(mFrameWidth+1, 0, mWidth-mFrameWidth-2, 8);
- if mHasFrame then
+ setScissor(mFrameWidth+1, 0, mWidth-mFrameWidth-2, uiContext.textHeight(mCaption));
+ {
+ if (mHasFrame) then
begin
uiContext.color := mBackColor[cidx];
uiContext.fillRect(xpos-3, gy, uiContext.textWidth(mCaption)+4, 8);
end;
+ }
uiContext.color := mFrameTextColor[cidx];
uiContext.drawText(xpos, gy, mCaption);
end;
mCanFocus := false;
mNoPad := true;
mCtl4Style := 'span';
+ mDefSize := TLaySize.Create(-1, -1);
end;
mExpand := true;
mCanFocus := false;
mCtl4Style := 'line';
+ mDefSize := TLaySize.Create(-1, -1);
end;
end;
+procedure TUILine.layPrepare ();
+begin
+ inherited layPrepare();
+ if (mParent <> nil) then mHoriz := not mParent.mHoriz;
+ if (mHoriz) then
+ begin
+ if (mLayDefSize.w < 0) then mLayDefSize.w := 1;
+ if (mLayDefSize.h < 0) then mLayDefSize.h := 7;
+ end
+ else
+ begin
+ if (mLayDefSize.w < 0) then mLayDefSize.w := 7;
+ if (mLayDefSize.h < 0) then mLayDefSize.h := 1;
+ end;
+end;
+
+
procedure TUILine.drawControl (gx, gy: Integer);
var
cidx: Integer;
end;
-// ////////////////////////////////////////////////////////////////////////// //
-procedure TUIHLine.AfterConstruction ();
-begin
- inherited;
- mHoriz := true;
- mDefSize.h := 7;
-end;
-
-
-// ////////////////////////////////////////////////////////////////////////// //
-procedure TUIVLine.AfterConstruction ();
-begin
- inherited;
- mHoriz := false;
- mDefSize.w := 7;
-end;
-
-
// ////////////////////////////////////////////////////////////////////////// //
procedure TUIStaticText.AfterConstruction ();
begin
mHoriz := true; // nobody cares
mHeader := false;
mLine := false;
- mDefSize.h := uiContext.charHeight(' ');
mCtl4Style := 'static';
end;
mHAlign := -1;
mVAlign := 0;
mCanFocus := false;
- mDefSize := TLaySize.Create(uiContext.textWidth(mText), uiContext.textHeight(mText));
mCtl4Style := 'label';
mLinkId := '';
end;
mVAlign := 0;
mCanFocus := true;
mIcon := TGxContext.TMarkIcon.Checkbox;
- mDefSize := TLaySize.Create(uiContext.textWidth(mText)+3+uiContext.iconMarkWidth(mIcon), uiContext.iconMarkHeight(mIcon));
+ mDefSize := TLaySize.Create(uiContext.textWidth(mText)+3+uiContext.iconMarkWidth(mIcon), nmax(uiContext.iconMarkHeight(mIcon), uiContext.textHeight(mText)));
mCtl4Style := 'switchbox';
mChecked := false;
mBoolVar := @mChecked;
procedure TUISwitchBox.setText (const s: AnsiString);
begin
inherited setText(s);
- mDefSize := TLaySize.Create(uiContext.textWidth(mText)+3+uiContext.iconMarkWidth(mIcon), uiContext.iconMarkHeight(mIcon));
+ mDefSize := TLaySize.Create(uiContext.textWidth(mText)+3+uiContext.iconMarkWidth(mIcon), nmax(uiContext.iconMarkHeight(mIcon), uiContext.textHeight(mText)));
end;
procedure TUISwitchBox.drawControl (gx, gy: Integer);
var
- xpos, ypos: Integer;
+ xpos, ypos, iwdt, dy: Integer;
cidx: Integer;
begin
cidx := getColorIndex;
+ iwdt := uiContext.iconMarkWidth(mIcon);
if (mHAlign < 0) then xpos := 0
- else if (mHAlign > 0) then xpos := mWidth-(uiContext.textWidth(mText)+3+uiContext.iconMarkWidth(mIcon))
- else xpos := (mWidth-(uiContext.textWidth(mText)+3+uiContext.iconMarkWidth(mIcon))) div 2;
+ else if (mHAlign > 0) then xpos := mWidth-(uiContext.textWidth(mText)+3+iwdt)
+ else xpos := (mWidth-(uiContext.textWidth(mText)+3+iwdt)) div 2;
if (mVAlign < 0) then ypos := 0
- else if (mVAlign > 0) then ypos := mHeight-uiContext.iconMarkHeight(mIcon)
- else ypos := (mHeight-uiContext.iconMarkHeight(mIcon)) div 2;
+ else if (mVAlign > 0) then ypos := mHeight-uiContext.textHeight(mText)
+ else ypos := (mHeight-uiContext.textHeight(mText)) div 2;
uiContext.color := mBackColor[cidx];
uiContext.fillRect(gx, gy, mWidth, mHeight);
uiContext.color := mSwitchColor[cidx];
- uiContext.drawIconMark(mIcon, gx, gy, checked);
-
- if (mVAlign < 0) then ypos := 0
- else if (mVAlign > 0) then ypos := mHeight-uiContext.textHeight(mText)
- else ypos := (mHeight-uiContext.textHeight(mText)) div 2;
+ if (uiContext.iconMarkHeight(mIcon) < uiContext.textHeight(mText)) then
+ begin
+ case uiContext.textHeight(mText) of
+ 14: dy := 2;
+ 16: dy := 3;
+ else dy := 1;
+ end;
+ uiContext.drawIconMark(mIcon, gx, gy+ypos+uiContext.textHeight(mText)-uiContext.iconMarkHeight(mIcon)-dy, checked);
+ end
+ else
+ begin
+ uiContext.drawIconMark(mIcon, gx, gy, checked);
+ end;
uiContext.color := mTextColor[cidx];
- uiContext.drawText(gx+xpos+3+uiContext.iconMarkWidth(mIcon), gy+ypos, mText);
+ uiContext.drawText(gx+xpos+3+iwdt, gy+ypos, mText);
if (mHotChar <> #0) and (mHotChar <> ' ') then
begin
uiContext.color := mHotColor[cidx];
- uiContext.drawChar(gx+xpos+3+uiContext.iconMarkWidth(mIcon)+mHotOfs, gy+ypos, mHotChar);
+ uiContext.drawChar(gx+xpos+3+iwdt+mHotOfs, gy+ypos, mHotChar);
end;
end;
registerCtlClass(TUIHBox, 'hbox');
registerCtlClass(TUIVBox, 'vbox');
registerCtlClass(TUISpan, 'span');
- registerCtlClass(TUIHLine, 'hline');
- registerCtlClass(TUIVLine, 'vline');
+ registerCtlClass(TUILine, 'line');
registerCtlClass(TUITextLabel, 'label');
registerCtlClass(TUIStaticText, 'static');
registerCtlClass(TUIButton, 'button');
index fb470c4fee5a71a41fd198e1b251b8466841ea3a..a941f554dda7c9a76fe95319c90721b4113ebcb3 100644 (file)
function getMaxSize (): TLaySize; // max size; <0: set to some huge value
function getFlex (): Integer; // <=0: not flexible
function isHorizBox (): Boolean; // horizontal layout for children?
- function canWrap (): Boolean; // for horizontal boxes: can wrap children? for child: `false` means 'nonbreakable at *next* ctl'
function noPad (): Boolean; // ignore padding in box direction for this control
- function isLineStart (): Boolean; // `true` if this ctl should start a new line; ignored for vertical boxes
function getAlign (): Integer; // aligning in non-main direction: <0: left/up; 0: center; >0: right/down
function getExpand (): Boolean; // expanding in non-main direction: `true` will ignore align and eat all available space
procedure setActualSizePos (constref apos: TLayPos; constref asize: TLaySize);
// flags
const
FlagHorizBox = LongWord(1) shl 0; // horizontal layout for children
- FlagLineStart = LongWord(1) shl 1;
- FlagLineCanWrap = LongWord(1) shl 2;
- FlagNoPad = LongWord(1) shl 3;
+ FlagNoPad = LongWord(1) shl 1;
+ FlagExpand = LongWord(1) shl 2;
// internal
- FlagLineDidWrap = LongWord(1) shl 8; // will be set when line was wrapped
- FlagInGroup = LongWord(1) shl 9; // set if this control is a member of any group
- FlagExpand = LongWord(1) shl 10;
- FlagLineFirst = LongWord(1) shl 11;
+ FlagInGroup = LongWord(1) shl 8; // set if this control is a member of any group
private
type
tempFlex: Integer;
flags: LongWord; // see above
aligndir: Integer;
- startsize: TLaySize; // current
- desiredsize: TLaySize;
- maxsize: TLaySize;
+ startsize: TLaySize; // original size
+ desiredsize: TLaySize; // current size
+ maxsize: TLaySize; // current maximum size
margins: TLayMargins; // can never be negative
padding: TLaySize;
desiredpos: TLayPos;
firstChild: LayControlIdx; // = -1;
nextSibling: LayControlIdx; // = -1;
- private
- function getDidWrap (): Boolean; inline;
- procedure setDidWrap (v: Boolean); inline;
-
public
procedure initialize (); inline;
function horizBox (): Boolean; inline;
- function lineStart (): Boolean; inline;
- function canWrap (): Boolean; inline;
function inGroup (): Boolean; inline;
- function firstInLine (): Boolean; inline;
function noPad (): Boolean; inline;
function getExpand (): Boolean; inline;
function alignBottom (): Boolean; inline;
function alignCenter (): Boolean; inline;
+ function visible (): Boolean; inline;
+
public
- property didWrap: Boolean read getDidWrap write setDidWrap;
property expand: Boolean read getExpand write setExpand;
end;
private
ctlist: TLayCtlArray;
groups: array[0..1] of TLayGrpArray; // horiz, vert
-
- firstTime: Boolean;
groupElementChanged: Boolean;
- wrappingChanged: Boolean;
private
- procedure fixFlags (cidx: LayControlIdx);
+ procedure firstTimeSetup (cidx: LayControlIdx);
procedure doChildren (parent: LayControlIdx; child: ControlT);
procedure appendToGroup (const gname: AnsiString;cidx: LayControlIdx;gidx: Integer);
procedure setupGroups ();
- // this also sets `tempFlex`
- procedure calcMaxSizeInternal (cidx: LayControlIdx);
-
- procedure fixLine (me: PLayControl; i0, i1: LayControlIdx; ypad: Integer; var cury: Integer; var spaceLeft: Single);
+ procedure distributeChildren (boxidx: LayControlIdx; maindir: Integer);
// do box layouting; call `layBox()` recursively if necessary
procedure layBox (boxidx: LayControlIdx);
procedure firstPass ();
procedure secondPass ();
procedure thirdPass ();
- procedure fourthPass ();
procedure dumpList (cidx: LayControlIdx; indent: Integer);
ctls: TLayCtlArray;
cur: Integer;
first: Boolean;
+ onlyVisible: Boolean;
public
- constructor Create (constref actls: TLayCtlArray; acur: Integer);
+ constructor Create (constref actls: TLayCtlArray; acur: Integer; aonlyvis: Boolean);
function moveNext (): Boolean; inline;
function getCurrent (): PLayControl; inline;
function getEnumerator (): TChildrenEnumerator; inline;
procedure setup (root: ControlT);
function forChildren (cidx: LayControlIdx): TChildrenEnumerator; inline;
+ function forVisibleChildren (cidx: LayControlIdx): TChildrenEnumerator; inline;
procedure layout ();
end;
function TFlexLayouterBase.TLayControl.horizBox (): Boolean; inline; begin result := ((flags and FlagHorizBox) <> 0); end;
-function TFlexLayouterBase.TLayControl.lineStart (): Boolean; inline; begin result := ((flags and FlagLineStart) <> 0); end;
-function TFlexLayouterBase.TLayControl.canWrap (): Boolean; inline; begin result := ((flags and FlagLineCanWrap) <> 0); end;
function TFlexLayouterBase.TLayControl.inGroup (): Boolean; inline; begin result := ((flags and FlagInGroup) <> 0); end;
-function TFlexLayouterBase.TLayControl.firstInLine (): Boolean; inline; begin result := ((flags and FlagLineFirst) <> 0); end;
function TFlexLayouterBase.TLayControl.noPad (): Boolean; inline; begin result := ((flags and FlagNoPad) <> 0); end;
-function TFlexLayouterBase.TLayControl.getDidWrap (): Boolean; inline; begin result := ((flags and FlagLineDidWrap) <> 0); end;
-procedure TFlexLayouterBase.TLayControl.setDidWrap (v: Boolean); inline; begin if (v) then flags := flags or FlagLineDidWrap else flags := flags and (not FlagLineDidWrap); end;
-
function TFlexLayouterBase.TLayControl.getExpand (): Boolean; inline; begin result := ((flags and FlagExpand) <> 0); end;
procedure TFlexLayouterBase.TLayControl.setExpand (v: Boolean); inline; begin if (v) then flags := flags or FlagExpand else flags := flags and (not FlagExpand); end;
@@ -220,27 +197,38 @@ function TFlexLayouterBase.TLayControl.alignRight (): Boolean; inline; begin res
function TFlexLayouterBase.TLayControl.alignBottom (): Boolean; inline; begin result := (aligndir > 0); end;
function TFlexLayouterBase.TLayControl.alignCenter (): Boolean; inline; begin result := (aligndir = 0); end;
+function TFlexLayouterBase.TLayControl.visible (): Boolean; inline;
+begin
+ result := (startsize.w <> 0) or (startsize.h <> 0);
+end;
+
// ////////////////////////////////////////////////////////////////////////// //
-constructor TFlexLayouterBase.TChildrenEnumerator.Create (constref actls: TLayCtlArray; acur: Integer);
+constructor TFlexLayouterBase.TChildrenEnumerator.Create (constref actls: TLayCtlArray; acur: Integer; aonlyvis: Boolean);
begin
ctls := actls;
cur := acur;
first := true;
+ onlyVisible := aonlyvis;
end;
function TFlexLayouterBase.TChildrenEnumerator.moveNext (): Boolean; inline;
begin
- if first then
- begin
- if (cur >= 0) and (cur < Length(ctls)) then cur := ctls[cur].firstChild else cur := -1;
- first := false;
- end
- else
+ while true do
begin
- cur := ctls[cur].nextSibling;
+ if first then
+ begin
+ if (cur >= 0) and (cur < Length(ctls)) then cur := ctls[cur].firstChild else cur := -1;
+ first := false;
+ end
+ else
+ begin
+ cur := ctls[cur].nextSibling;
+ end;
+ result := (cur >= 0);
+ if (not result) or (not onlyVisible) then break;
+ if (ctls[cur].visible) then break;
end;
- result := (cur >= 0);
end;
function TFlexLayouterBase.TChildrenEnumerator.getCurrent (): PLayControl; inline;
ctlist := nil;
groups[0] := nil;
groups[1] := nil;
-
- firstTime := false;
groupElementChanged := false;
- wrappingChanged := false;
end;
function TFlexLayouterBase.forChildren (cidx: LayControlIdx): TChildrenEnumerator; inline;
begin
- result := TChildrenEnumerator.Create(ctlist, cidx);
+ result := TChildrenEnumerator.Create(ctlist, cidx, false);
+end;
+
+function TFlexLayouterBase.forVisibleChildren (cidx: LayControlIdx): TChildrenEnumerator; inline;
+begin
+ result := TChildrenEnumerator.Create(ctlist, cidx, true);
end;
end;
-procedure TFlexLayouterBase.fixFlags (cidx: LayControlIdx);
-var
- lc: PLayControl;
-begin
- assert((cidx >= 0) and (cidx < Length(ctlist)));
- lc := @ctlist[cidx];
- //lc.flags := 0;
- if (lc.ctl.isHorizBox) then lc.flags := lc.flags or FlagHorizBox;
- if (lc.ctl.isLineStart) then lc.flags := lc.flags or FlagLineStart;
- if (lc.ctl.canWrap) then lc.flags := lc.flags or FlagLineCanWrap;
- if (lc.ctl.getExpand) then lc.flags := lc.flags or FlagExpand;
- if (lc.ctl.noPad) then lc.flags := lc.flags or FlagNoPad;
- lc.aligndir := lc.ctl.getAlign;
-end;
-
-
procedure TFlexLayouterBase.doChildren (parent: LayControlIdx; child: ControlT);
var
cidx: LayControlIdx = -1;
while (child <> nil) do
begin
child.layPrepare;
+ //if (msz.w = 0) or (msz.h = 0) then continue; // hidden controls will have zero maxsize, so skip 'em
SetLength(ctlist, Length(ctlist)+1);
lc := @ctlist[High(ctlist)];
lc.initialize();
begin
cidx := LayControlIdx(High(ctlist));
ctlist[parent].firstChild := cidx;
- // first child is always linestart
- lc.flags := lc.flags or FlagLineStart or FlagLineFirst;
end
else
begin
lc.myidx := cidx;
lc.ctl := child;
lc.parent := parent;
- fixFlags(cidx);
doChildren(cidx, child.firstChild);
child := child.nextSibling;
end;
ctlist[0].initialize();
ctlist[0].myidx := 0;
ctlist[0].ctl := root;
- fixFlags(0);
- ctlist[0].flags := ctlist[0].flags or FlagLineStart or FlagLineFirst;
doChildren(0, root.firstChild);
setupGroups();
except
end;
-// this also sets `tempFlex`
-procedure TFlexLayouterBase.calcMaxSizeInternal (cidx: LayControlIdx);
+procedure TFlexLayouterBase.firstTimeSetup (cidx: LayControlIdx);
var
- lc, c: PLayControl;
- msz: TLaySize;
- negw, negh: Boolean;
- zerow: Boolean;
- curwdt, curhgt, totalhgt: Integer;
- doWrap: Boolean;
- xpad, ypad: Integer;
- realpad: Integer;
- dopad: Boolean = false;
+ lc: PLayControl;
begin
- if (cidx < 0) or (cidx >= Length(ctlist)) then exit;
-
+ assert((cidx >= 0) and (cidx < Length(ctlist)));
lc := @ctlist[cidx];
- msz := lc.ctl.getMaxSize;
- negw := (lc.startsize.w < 0);
- negh := (lc.startsize.h < 0);
- zerow := (lc.startsize.w = 0);
-
+ lc.flags := 0;
+ if (lc.ctl.isHorizBox) then lc.flags := lc.flags or FlagHorizBox;
+ if (lc.ctl.getExpand) then lc.flags := lc.flags or FlagExpand;
+ if (lc.ctl.noPad) then lc.flags := lc.flags or FlagNoPad;
+ lc.aligndir := lc.ctl.getAlign;
+ lc.startsize := lc.ctl.getDefSize;
+ //lc.startsize.w := nmax(0, lc.startsize.w);
+ //lc.startsize.h := nmax(0, lc.startsize.h);
+ lc.margins := lc.ctl.getMargins;
+ lc.margins.left := nmax(0, lc.margins.left);
+ lc.margins.top := nmax(0, lc.margins.top);
+ lc.margins.right := nmax(0, lc.margins.right);
+ lc.margins.bottom := nmax(0, lc.margins.bottom);
+ lc.padding := lc.ctl.getPadding;
+ lc.padding.w := nmax(0, lc.padding.w);
+ lc.padding.h := nmax(0, lc.padding.h);
+ lc.maxsize := TLaySize.Create(-1, -1);
+ if (lc.maxsize.w >= 0) then lc.startsize.w := nmin(lc.maxsize.w, lc.startsize.w);
+ if (lc.maxsize.h >= 0) then lc.startsize.h := nmin(lc.maxsize.h, lc.startsize.h);
+ lc.desiredsize := lc.startsize;
lc.tempFlex := lc.ctl.getFlex;
-
- for c in forChildren(cidx) do calcMaxSizeInternal(c.myidx);
-
- if (lc.horizBox) then
- begin
- // horizontal boxes
- if (negw) then lc.tempFlex := 0; // size is negative: don't expand
- curwdt := lc.margins.horiz;
- curhgt := 0;
- totalhgt := lc.margins.vert;
- xpad := nmax(0, lc.padding.w);
- ypad := 0;
- for c in forChildren(cidx) do
- begin
- if (dopad) then realpad := xpad else realpad := 0;
- // new line?
- doWrap := (not c.firstInLine) and (c.lineStart);
- // need to wrap?
- if (not doWrap) and (not zerow) and (not negw) and (lc.canWrap) and (c.canWrap) and (msz.w > 0) and (curwdt+c.startsize.w+realpad > lc.startsize.w) then doWrap := true;
- if (doWrap) then
- begin
- totalhgt += curhgt;
- if (lc.startsize.w < curwdt) then lc.startsize.w := curwdt;
- curwdt := 0;
- curhgt := 0;
- ypad := nmax(0, lc.padding.h);
- realpad := 0;
- end;
- curwdt += c.startsize.w+realpad;
- if (curhgt < c.startsize.h+ypad) then curhgt := c.startsize.h+ypad;
- dopad := (xpad > 0) and (not lc.noPad);
- end;
- //writeln('00: ', cidx, ': totalhgt=', totalhgt);
- totalhgt += curhgt;
- //writeln('01: ', cidx, ': totalhgt=', totalhgt);
- if (lc.startsize.w < curwdt) then lc.startsize.w := curwdt;
- if (lc.startsize.h < totalhgt) then lc.startsize.h := totalhgt;
- end
- else
- begin
- // vertical boxes
- if (negh) then lc.tempFlex := 0; // size is negative: don't expand
- curhgt := lc.margins.vert;
- ypad := nmax(0, lc.padding.h);
- for c in forChildren(cidx) do
- begin
- if (lc.startsize.w < c.startsize.w+lc.margins.horiz) then lc.startsize.w := c.startsize.w+lc.margins.horiz;
- curhgt += c.startsize.h;
- if (dopad) then curhgt += ypad;
- dopad := (not c.noPad);
- end;
- if (lc.startsize.h < curhgt) then lc.startsize.h := curhgt;
- end;
- if (lc.startsize.w < 0) then lc.startsize.w := 0;
- if (lc.startsize.h < 0) then lc.startsize.h := 0;
- {
- lc.maxsize := msz;
- if (lc.maxsize.w < lc.startsize.w) then begin if (lc.maxsize.w >= 0) then lc.maxsize.w := lc.startsize.w; end;
- if (lc.maxsize.h < lc.startsize.h) then begin if (lc.maxsize.h >= 0) then lc.maxsize.h := lc.startsize.h; end;
- }
- if (msz.w < 0) then msz.w := lc.startsize.w;
- if (msz.h < 0) then msz.h := lc.startsize.h;
- lc.maxsize := msz;
end;
procedure TFlexLayouterBase.firstPass ();
var
- f, c: Integer;
- needRecalcMaxSize: Boolean;
+ f: Integer;
gtype: Integer;
- grp: PLayGroup;
- maxsz: Integer;
- cidx: LayControlIdx;
- ct: PLayControl;
begin
- // reset all 'laywrap' flags for controls, set initial 'startsize'
- for f := 0 to High(ctlist) do
- begin
- ctlist[f].didWrap := false;
- ctlist[f].startsize := ctlist[f].ctl.getDefSize;
- ctlist[f].margins := ctlist[f].ctl.getMargins;
- ctlist[f].padding := ctlist[f].ctl.getPadding;
- end;
- // setup sizes
- calcMaxSizeInternal(0); // this also sets `tempFlex`
- //writeln('=== calculated max size (0) ==='); dump();
- // find max size for group, adjust 'startsize' controls to group max size
- needRecalcMaxSize := false;
+ groupElementChanged := false;
+ for f := 0 to High(ctlist) do firstTimeSetup(f);
+ // if we have any groups, set "group element changed" flag, so third pass will fix 'em
for gtype := 0 to 1 do
begin
- for f := 0 to High(groups[gtype]) do
+ if (Length(groups[gtype]) > 0) then
begin
- grp := @groups[gtype][f];
- maxsz := 0;
- for c := 0 to High(grp.ctls) do
- begin
- cidx := grp.ctls[c];
- ct := @ctlist[cidx];
- if (maxsz < ct.startsize[gtype]) then maxsz := ct.startsize[gtype];
- end;
- for c := 0 to High(grp.ctls) do
- begin
- cidx := grp.ctls[c];
- ct := @ctlist[cidx];
- if (maxsz <> ct.startsize[gtype]) then
- begin
- needRecalcMaxSize := true;
- ct.startsize[gtype] := maxsz;
- end;
- end;
+ groupElementChanged := true;
+ break;
end;
end;
- // recalc maxsize if necessary
- if (needRecalcMaxSize) then calcMaxSizeInternal(0);
- // set "desired size" to "start size"
- for f := 0 to High(ctlist) do ctlist[f].desiredsize := ctlist[f].startsize;
- // set flags
- firstTime := true;
- //writeln('=== calculated max size (final) ==='); dump();
end;
-procedure TFlexLayouterBase.fixLine (me: PLayControl; i0, i1: LayControlIdx; ypad: Integer; var cury: Integer; var spaceLeft: Single);
+procedure TFlexLayouterBase.distributeChildren (boxidx: LayControlIdx; maindir: Integer);
var
+ me, lc: PLayControl;
+ suppdir: Integer;
+ marg0, marg1, margtotal: Integer;
+ marg0Op, marg1Op, margtotalOp: Integer;
flexTotal: Integer = 0; // total sum of flex fields
- flexBoxCount: Integer = 0; // number of boxes
- curx: Integer;
- lc: PLayControl;
- osz: TLaySize;
+ spaceLeft: Integer = 0;
+ dopad: Boolean = false;
+ prevpad: Boolean = false;
+ maxdim: Integer = 0;
+ curpos: Integer;
toadd: Integer;
- sti0: Integer;
- lineh: Integer;
- xpad: Integer;
+ pad: Integer;
+ osz: TLaySize;
begin
- if (ypad < 0) then ypad := 0;
- curx := me.margins.left;
- sti0 := i0;
- // calc minimal line height, count flexboxes
- lineh := 0;
- while (i0 <> i1) do
+ assert((boxidx >= 0) and (boxidx < Length(ctlist)));
+ assert((maindir = 0) or (maindir = 1));
+ // cache some parameters
+ me := @ctlist[boxidx];
+ suppdir := 1-maindir;
+ if (maindir = 0) then
begin
- lc := @ctlist[i0];
- lineh := nmax(lineh, lc.startsize.h+ypad);
- if (lc.tempFlex > 0) then begin flexTotal += lc.tempFlex; flexBoxCount += 1; end;
- i0 := lc.nextSibling;
+ marg0 := me.margins.left;
+ marg1 := me.margins.right;
+ marg0Op := me.margins.top;
+ marg1Op := me.margins.bottom;
+ end
+ else
+ begin
+ marg0 := me.margins.top;
+ marg1 := me.margins.bottom;
+ marg0Op := me.margins.left;
+ marg1Op := me.margins.right;
+ end;
+ margtotal := marg0+marg1;
+ margtotalOp := marg0Op+marg1Op;
+ // horizontal boxes
+ pad := nmax(0, me.padding[maindir]);
+ // calc required space, count flexes
+ for lc in forVisibleChildren(boxidx) do
+ begin
+ if (lc.tempFlex > 0) then flexTotal += lc.tempFlex;
+ spaceLeft += nmax(0, lc.desiredsize[maindir]);
+ // insert padding if both current and previous children allow padding
+ dopad := (not lc.noPad);
+ if (prevpad) and (dopad) then spaceLeft += pad;
+ prevpad := dopad;
+ maxdim := nmax(maxdim, lc.desiredsize[suppdir]);
end;
- // distribute space, expand/align
- xpad := nmax(0, me.padding.w);
- i0 := sti0;
- while (i0 <> i1) do
+ // add margins
+ spaceLeft += margtotal;
+ maxdim += margtotalOp;
+ // fix box size
+ me.desiredsize[maindir] := nmax(spaceLeft, me.desiredsize[maindir]);
+ me.desiredsize[suppdir] := nmax(maxdim, me.desiredsize[suppdir]);
+ // calculate free space
+ spaceLeft := me.desiredsize[maindir]-spaceLeft;
+ // distribute children
+ dopad := false;
+ prevpad := false;
+ curpos := marg0;
+ for lc in forVisibleChildren(boxidx) do
begin
- lc := @ctlist[i0];
osz := lc.desiredsize;
- lc.desiredsize := lc.startsize;
- lc.desiredpos.x := curx;
- lc.desiredpos.y := cury;
- curx += lc.desiredsize.w;
- if (xpad > 0) and (not lc.noPad) then curx += xpad;
+ // main direction
+ // insert padding if both current and previous children allow padding
+ dopad := (not lc.noPad);
+ if (prevpad) and (dopad) then curpos += pad;
+ prevpad := dopad;
+ lc.desiredpos[maindir] := curpos;
+ if (lc.desiredsize[maindir] < 0) then lc.desiredsize[maindir] := 0;
+ curpos += lc.desiredsize[maindir];
// fix flexbox size
- if (lc.tempFlex > 0) and (spaceLeft > 0) then
+ //writeln(':lcidx=', lc.myidx, '; tempFlex=', lc.tempFlex, '; spaceLeft=', spaceLeft);
+ if (spaceLeft > 0) and (lc.tempFlex > 0) then
begin
toadd := trunc(spaceLeft*lc.tempFlex/flexTotal+0.5);
if (toadd > 0) then
begin
// size changed
- lc.desiredsize.w += toadd;
- curx += toadd;
// compensate (crudely) rounding errors
- if (curx > me.desiredsize.w-me.margins.horiz) then begin lc.desiredsize.w -= 1; curx -= 1; end;
- // relayout children
- layBox(lc.firstChild);
+ if (curpos+toadd > me.desiredsize[maindir]-margtotal) then toadd -= 1;
+ //writeln('***curpos=', curpos, '; toadd=', toadd, '; spaceLeft=', spaceLeft);
+ // fix size
+ lc.desiredsize[maindir] := lc.desiredsize[maindir]+toadd;
+ curpos += toadd;
end;
end;
- // expand or align
- if (lc.expand) then lc.desiredsize.h := nmax(1, lineh) // expand
- else if (lc.alignBottom) then lc.desiredpos.y := cury+(lineh-lc.desiredsize.h) // bottom align
- else if (lc.alignCenter) then lc.desiredpos.y := cury+(lineh-lc.desiredsize.h) div 2; // center
+ // secondary direction: expand or align
+ if (lc.desiredsize[suppdir] < 0) then lc.desiredsize[suppdir] := 0;
+ lc.desiredpos[suppdir] := marg0Op; // left/top align
+ if (lc.expand) then lc.desiredsize[suppdir] := me.desiredsize[suppdir]-margtotalOp // expand
+ else if (lc.aligndir > 0) then lc.desiredpos[suppdir] := me.desiredsize[suppdir]-marg1Op-lc.desiredsize[suppdir] // right/bottom align
+ else if (lc.aligndir = 0) then lc.desiredpos[suppdir] := (me.desiredsize[suppdir]-lc.desiredsize[suppdir]) div 2; // center
+ lc.desiredsize[suppdir] := nmax(lc.desiredsize[suppdir], osz[suppdir]);
+ // relayout children if size was changed
if (not osz.equals(lc.desiredsize)) then
begin
if (lc.inGroup) then groupElementChanged := true;
- // relayout children
- layBox(lc.firstChild);
+ layBox(lc.myidx);
end;
- i0 := lc.nextSibling;
end;
- flexTotal := 0;
- flexBoxCount := 0;
- spaceLeft := me.desiredsize.w-me.margins.horiz;
- cury += lineh;
end;
procedure TFlexLayouterBase.layBox (boxidx: LayControlIdx);
var
me: PLayControl;
- flexTotal: Integer; // total sum of flex fields
- flexBoxCount: Integer; // number of boxes
- spaceLeft: Single;
- cury: Integer;
- maxwdt: Integer;
- lineStartIdx: LayControlIdx;
lc: PLayControl;
- doWrap: Boolean;
- toadd: Integer;
osz: TLaySize;
- xpad, ypad, realpad: Integer;
- dopad: Boolean = false;
begin
if (boxidx < 0) or (boxidx >= Length(ctlist)) then exit;
me := @ctlist[boxidx];
-
// if we have no children, there's nothing to do
if (me.firstChild <> -1) then
begin
- // first, layout all children
- for lc in forChildren(boxidx) do layBox(lc.myidx);
-
- // second, layout lines, distribute flex data
- if (me.horizBox) then
+ while true do
begin
- // horizontal boxes
- cury := me.margins.top;
- xpad := nmax(0, me.padding.w);
- ypad := 0;
-
- fixLine(me, -1, -1, 0, cury, spaceLeft); //HACK!
-
- lineStartIdx := me.firstChild;
- for lc in forChildren(boxidx) do
- begin
- if (dopad) then realpad := xpad else realpad := 0;
- // new line?
- doWrap := (not lc.firstInLine) and (lc.lineStart);
- // need to wrap?
- if (not doWrap) and (lc.canWrap) and (lc.canWrap) and (lc.desiredsize.w > 0) and (spaceLeft-realpad < lc.desiredsize.w) then doWrap := true;
- if (doWrap) then
- begin
- // new line, fix this one
- if (not lc.didWrap) then begin wrappingChanged := true; lc.didWrap := true; end;
- fixLine(me, lineStartIdx, lc.myidx, ypad, cury, spaceLeft);
- lineStartIdx := lc.myidx;
- ypad := nmax(0, me.padding.h);
- realpad := 0;
- end
- else
- begin
- if (lc.didWrap) then begin wrappingChanged := true; lc.didWrap := false; end;
- end;
- spaceLeft -= lc.desiredsize.w+realpad;
- dopad := (xpad > 0) and (not lc.noPad);
- //if (maxhgt < lc.desiredsize.h) then maxhgt := lc.desiredsize.h;
- //if (lc.tempFlex > 0) then begin flexTotal += lc.tempFlex; flexBoxCount += 1; end;
- end;
- // fix last line
- fixLine(me, lineStartIdx, -1, ypad, cury, spaceLeft);
- end
- else
- begin
- // vertical boxes
- maxwdt := 0;
- flexTotal := 0;
- flexBoxCount := 0;
- spaceLeft := me.desiredsize.h-me.margins.vert;
- ypad := nmax(0, me.padding.h);
-
- // calc flex
- for lc in forChildren(boxidx) do
- begin
- spaceLeft -= lc.desiredsize.h;
- if (maxwdt < lc.desiredsize.w) then maxwdt := lc.desiredsize.w;
- if (lc.tempFlex > 0) then begin flexTotal += lc.tempFlex; flexBoxCount += 1; end;
- end;
-
- // distribute space
- cury := me.margins.top;
- //writeln('me: ', boxidx, '; margins: ', me.margins.toString);
- for lc in forChildren(boxidx) do
- begin
- osz := lc.desiredsize;
- lc.desiredsize := lc.startsize;
- lc.desiredpos.x := me.margins.left;
- lc.desiredpos.y := cury;
- cury += lc.desiredsize.h;
- if (ypad > 0) and (not lc.noPad) then cury += ypad;
- // fix flexbox size
- if (lc.tempFlex > 0) and (spaceLeft > 0) then
- begin
- toadd := trunc(spaceLeft*lc.tempFlex/flexTotal+0.5);
- if (toadd > 0) then
- begin
- // size changed
- lc.desiredsize.h += toadd;
- cury += toadd;
- // compensate (crudely) rounding errors
- if (cury > me.desiredsize.h-me.margins.vert) then begin lc.desiredsize.h -= 1; cury -= 1; end;
- end;
- end;
- // expand or align
- if (lc.expand) then lc.desiredsize.w := nmax(1, me.desiredsize.w-me.margins.vert) // expand
- else if (lc.alignRight) then lc.desiredpos.x := me.desiredsize.w-me.margins.right-lc.desiredsize.w // right align
- else if (lc.alignCenter) then lc.desiredpos.x := (me.desiredsize.w-lc.desiredsize.w) div 2; // center
- if (not osz.equals(lc.desiredsize)) then
- begin
- if (lc.inGroup) then groupElementChanged := true;
- // relayout children
- layBox(lc.firstChild);
- end;
- end;
+ osz := me.desiredsize;
+ // layout all children
+ for lc in forVisibleChildren(boxidx) do layBox(lc.myidx);
+ // distribute children
+ if (me.horizBox) then distributeChildren(me.myidx, 0) else distributeChildren(me.myidx, 1);
+ // relayout children if size was changed
+ if (osz.equals(me.desiredsize)) then break;
+ if (me.inGroup) then groupElementChanged := true;
end;
end;
-
- if (me.maxsize.w >= 0) and (me.desiredsize.w > me.maxsize.w) then me.desiredsize.w := me.maxsize.w;
- if (me.maxsize.h >= 0) and (me.desiredsize.h > me.maxsize.h) then me.desiredsize.h := me.maxsize.h;
end;
procedure TFlexLayouterBase.secondPass ();
-begin
- // reset flags
- groupElementChanged := false;
- wrappingChanged := false;
-
- if (Length(ctlist) > 0) then
- begin
- ctlist[0].desiredpos := TLayPos.Create(0, 0);
- layBox(0);
- end;
-
- // fix 'wrapping-changed' flag
- if (firstTime) then begin wrappingChanged := false; firstTime := false; end;
-end;
-
-
-procedure TFlexLayouterBase.thirdPass ();
var
secondAgain: Boolean;
gtype: Integer;
f, c: Integer;
cidx: LayControlIdx;
ct: PLayControl;
+ loopsLeft: Integer = 64;
begin
- while true do
+ while (loopsLeft > 0) do
begin
- secondPass();
+ Dec(loopsLeft);
+ layBox(0);
secondAgain := false;
if (groupElementChanged) then
begin
secondAgain := true;
- // find max size for group, adjust 'startsize' controls to group max size
+ groupElementChanged := false;
+ // fix group sizes
for gtype := 0 to 1 do
begin
for f := 0 to High(groups[gtype]) do
begin
cidx := grp.ctls[c];
ct := @ctlist[cidx];
- ct.expand := false; // don't expand grouped controls anymore
- if (maxsz < ct.startsize[gtype]) then maxsz := ct.startsize[gtype];
+ maxsz := nmax(maxsz, ct.desiredsize[gtype]);
end;
for c := 0 to High(grp.ctls) do
begin
cidx := grp.ctls[c];
ct := @ctlist[cidx];
- ct.startsize[gtype] := maxsz;
ct.desiredsize[gtype] := maxsz;
- ct.tempFlex := 0; // don't change control size anymore
end;
end;
end;
- end
- else
+ end;
+ // don't change group control sizes anymore
+ for f := 0 to High(ctlist) do
begin
- for f := 0 to High(ctlist) do
+ ct := @ctlist[f];
+ if (ct.inGroup) then
begin
- ct := @ctlist[f];
- if (ct.inGroup) then
- begin
- ct.expand := false; // don't expand grouped controls anymore
- ct.tempFlex := 0; // don't change control size anymore
- end;
- (*
- for c := 0 to 1 do
- begin
- if (ct.maxsize[c] < 0) then continue;
- if (ct.desiredsize[c] > ct.maxsize[c]) then
- begin
- //writeln('ctl #', f, '; dimension #', c, ': desired=', ctlist[f].desiredsize[c], '; max=', ctlist[f].maxsize[c]);
- ct.startsize[c] := ct.maxsize[c];
- ct.desiredsize[c] := ct.maxsize[c];
- ct.tempFlex := 0; // don't change control size anymore
- secondAgain := true;
- end;
- end;
- *)
+ ct.expand := false; // don't expand grouped controls anymore
+ ct.tempFlex := 0; // don't change control size anymore
end;
end;
- if (not secondAgain) and (not wrappingChanged) then break;
- firstTime := false;
+ if (not secondAgain) then break;
end;
end;
-(*
-fourth pass:
- set 'actualsize' and 'actualpos' to 'desiredsize' and 'desiredpos'
- return
-*)
-procedure TFlexLayouterBase.fourthPass ();
+procedure TFlexLayouterBase.thirdPass ();
var
f: Integer;
begin
procedure TFlexLayouterBase.layout ();
begin
+ if (Length(ctlist) = 0) then exit;
+ ctlist[0].desiredpos := TLayPos.Create(0, 0);
firstPass();
+ //writeln('============== AFTER FIRST PASS =============='); dump();
secondPass();
+ //writeln('============== AFTER SECOND PASS =============='); dump();
thirdPass();
- fourthPass();
end;
begin
lc := @ctlist[cidx];
for f := 0 to indent do write(' ');
- writeln(lc.myidx, ': startsize:', lc.startsize.toString, '; desiredsize=', lc.desiredsize.toString, '; maxsize=', lc.maxsize.toString, '; tempFlex=', lc.tempFlex, '; despos=', lc.desiredpos.toString);
+ if (not lc.visible) then write('!');
+ write(lc.myidx, ': ');
+ if (lc.ctl.id <> '') then write('<', lc.ctl.className, '> {', lc.ctl.id, '} ') else write('<', lc.ctl.className, '> ');
+ writeln('startsize:', lc.startsize.toString, '; desiredsize=', lc.desiredsize.toString, '; maxsize=', lc.maxsize.toString, '; tempFlex=', lc.tempFlex, '; despos=', lc.desiredpos.toString);
dumpList(lc.firstChild, indent+2);
cidx := lc.nextSibling;
end;
end;
-// ////////////////////////////////////////////////////////////////////////// //
-(*
-void main () begin
- auto win := new GuiControl();
- (win ~= new GuiControl()).mSize := TLaySize(10, 5);
- (win ~= new GuiControl()).mSize := TLaySize(16, 8);
-
- //win.mSize := TLaySize(40, 20);
-
- auto lay := TFlexLayouterBase!GuiControl();
- lay.setup(win);
-
- writeln('============================');
- lay.dumpFlat();
-
- writeln('=== initial ===');
- lay.dump();
-
- //lay.calcMaxSizeInternal(0);
- /*
- lay.firstPass();
- writeln('=== after first pass ===');
- lay.dump();
-
- lay.secondPass();
- writeln('=== after second pass ===');
- lay.dump();
- */
- lay.layout();
- writeln('=== final ===');
- lay.dump();
-*)
end.
index f70e78967a753b4255e82716058fc49e04123a5d..1f08d3a1c8d72184cfe3ee8c688fe6d1d4b9f579 100644 (file)
procedure TGxBmpFont.oglCreateTexture ();
begin
- mTexId := createFontTexture(mFontBmp, mFontWdt, (mWidth <= 0));
+ mTexId := createFontTexture(mFontBmp, mFontWdt, mHeight, (mWidth <= 0));
end;
for ch in s do
begin
tx := (Integer(ch) mod 16)*8;
- ty := (Integer(ch) div 16)*8;
+ ty := (Integer(ch) div 16)*16;
glBegin(GL_QUADS);
- glTexCoord2f((tx+0)/128.0, (ty+0)/128.0); glVertex2i(x+0, y+0); // top-left
- glTexCoord2f((tx+8)/128.0, (ty+0)/128.0); glVertex2i(x+8, y+0); // top-right
- glTexCoord2f((tx+8)/128.0, (ty+8)/128.0); glVertex2i(x+8, y+8); // bottom-right
- glTexCoord2f((tx+0)/128.0, (ty+8)/128.0); glVertex2i(x+0, y+8); // bottom-left
+ glTexCoord2f((tx+0)/128.0, (ty+0)/256.0); glVertex2i(x+0, y+0); // top-left
+ glTexCoord2f((tx+8)/128.0, (ty+0)/256.0); glVertex2i(x+8, y+0); // top-right
+ glTexCoord2f((tx+8)/128.0, (ty+mHeight)/256.0); glVertex2i(x+8, y+mHeight); // bottom-right
+ glTexCoord2f((tx+0)/128.0, (ty+mHeight)/256.0); glVertex2i(x+0, y+mHeight); // bottom-left
glEnd();
x += (mFontWdt[Byte(ch)] and $0f)+1;
result += (mFontWdt[Byte(ch)] and $0f)+1;
procedure createFonts ();
begin
deleteFonts();
- SetLength(fontList, 4);
+ SetLength(fontList, 10);
fontList[0] := TGxBmpFont.Create('dos', 8, 8, @kgiFont8[0], @kgiFont8PropWidth[0]);
fontList[1] := TGxBmpFont.Create('dos-prop', 0, 8, @kgiFont8[0], @kgiFont8PropWidth[0]);
fontList[2] := TGxBmpFont.Create('msx', 6, 8, @kgiFont6[0], @kgiFont6PropWidth[0]);
fontList[3] := TGxBmpFont.Create('msx-prop', 0, 8, @kgiFont6[0], @kgiFont6PropWidth[0]);
+ fontList[4] := TGxBmpFont.Create('win8', 8, 8, @kgiWFont8[0], @kgiWFont8Wdt[0]);
+ fontList[5] := TGxBmpFont.Create('win8-prop', 0, 8, @kgiWFont8[0], @kgiWFont8Wdt[0]);
+ fontList[6] := TGxBmpFont.Create('win14', 8, 14, @kgiFont14[0], @kgiFont14Wdt[0]);
+ fontList[7] := TGxBmpFont.Create('win14-prop', 9, 14, @kgiFont14[0], @kgiFont14Wdt[0]);
+ fontList[8] := TGxBmpFont.Create('win16', 8, 16, @kgiFont16[0], @kgiFont16Wdt[0]);
+ fontList[9] := TGxBmpFont.Create('win16-prop', 0, 16, @kgiFont16[0], @kgiFont16Wdt[0]);
end;
index c3372e223df2a04803f0fbc3da92ead8b1821d69..b520d471ec918c653749986786e3862da6fa31cf 100644 (file)
$06,$06,$06,$06,$35,$05,$06,$07,$15,$32,$32,$08,$15,$15,$24,$08
);
+const kgiFont14: array[0..256*14-1] of Byte = (
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$7e,$81,$a5,$81,$81,$bd,$99,$81,$7e,$00,$00,$00,
+$00,$00,$7e,$ff,$db,$ff,$ff,$c3,$e7,$ff,$7e,$00,$00,$00,$00,$00,$00,$6c,$fe,$fe,$fe,$fe,$7c,$38,$10,$00,$00,$00,
+$00,$00,$00,$10,$38,$7c,$fe,$7c,$38,$10,$00,$00,$00,$00,$00,$00,$18,$3c,$3c,$e7,$e7,$e7,$99,$18,$3c,$00,$00,$00,
+$00,$00,$18,$3c,$7e,$ff,$ff,$7e,$18,$18,$3c,$00,$00,$00,$00,$00,$00,$00,$00,$18,$3c,$3c,$18,$00,$00,$00,$00,$00,
+$ff,$ff,$ff,$ff,$ff,$e7,$c3,$c3,$e7,$ff,$ff,$ff,$ff,$ff,$00,$00,$00,$00,$3c,$66,$42,$42,$66,$3c,$00,$00,$00,$00,
+$ff,$ff,$ff,$ff,$c3,$99,$bd,$bd,$99,$c3,$ff,$ff,$ff,$ff,$00,$00,$1e,$0e,$1a,$32,$78,$cc,$cc,$cc,$78,$00,$00,$00,
+$00,$00,$3c,$66,$66,$66,$3c,$18,$7e,$18,$18,$00,$00,$00,$00,$00,$3e,$30,$3e,$30,$30,$30,$70,$f0,$e0,$00,$00,$00,
+$00,$00,$7f,$63,$7f,$63,$63,$63,$67,$e7,$e6,$c0,$00,$00,$00,$00,$18,$18,$db,$3c,$e7,$3c,$db,$18,$18,$00,$00,$00,
+$00,$00,$80,$c0,$e0,$f8,$fe,$f8,$e0,$c0,$80,$00,$00,$00,$00,$00,$02,$06,$0e,$3e,$fe,$3e,$0e,$06,$02,$00,$00,$00,
+$00,$00,$18,$3c,$7e,$18,$18,$18,$7e,$3c,$18,$00,$00,$00,$00,$00,$66,$66,$66,$66,$66,$66,$00,$66,$66,$00,$00,$00,
+$00,$00,$7f,$db,$db,$db,$7b,$1b,$1b,$1b,$1b,$00,$00,$00,$00,$7c,$c6,$60,$38,$6c,$c6,$c6,$6c,$38,$0c,$c6,$7c,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$fe,$fe,$fe,$00,$00,$00,$00,$00,$18,$3c,$7e,$18,$18,$18,$7e,$3c,$18,$7e,$00,$00,
+$00,$00,$18,$3c,$7e,$18,$18,$18,$18,$18,$18,$00,$00,$00,$00,$00,$18,$18,$18,$18,$18,$18,$7e,$3c,$18,$00,$00,$00,
+$00,$00,$00,$00,$18,$0c,$fe,$0c,$18,$00,$00,$00,$00,$00,$00,$00,$00,$00,$30,$60,$fe,$60,$30,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$c0,$c0,$fe,$00,$00,$00,$00,$00,$00,$00,$00,$00,$28,$6c,$fe,$6c,$28,$00,$00,$00,$00,$00,
+$00,$00,$00,$10,$38,$38,$7c,$7c,$fe,$fe,$00,$00,$00,$00,$00,$00,$00,$fe,$fe,$7c,$7c,$38,$38,$10,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$18,$3c,$3c,$3c,$18,$18,$00,$18,$18,$00,$00,$00,
+$00,$66,$66,$66,$24,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$6c,$6c,$fe,$6c,$6c,$6c,$fe,$6c,$6c,$00,$00,$00,
+$18,$18,$7c,$c6,$c2,$c0,$7c,$06,$86,$c6,$7c,$18,$18,$00,$00,$00,$00,$00,$c2,$c6,$0c,$18,$30,$66,$c6,$00,$00,$00,
+$00,$00,$38,$6c,$6c,$38,$76,$dc,$cc,$cc,$76,$00,$00,$00,$00,$30,$30,$30,$60,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$0c,$18,$30,$30,$30,$30,$30,$18,$0c,$00,$00,$00,$00,$00,$30,$18,$0c,$0c,$0c,$0c,$0c,$18,$30,$00,$00,$00,
+$00,$00,$00,$00,$66,$3c,$ff,$3c,$66,$00,$00,$00,$00,$00,$00,$00,$00,$00,$18,$18,$7e,$18,$18,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$18,$18,$18,$30,$00,$00,$00,$00,$00,$00,$00,$00,$fe,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$18,$18,$00,$00,$00,$00,$00,$02,$06,$0c,$18,$30,$60,$c0,$80,$00,$00,$00,$00,
+$00,$00,$7c,$c6,$ce,$de,$f6,$e6,$c6,$c6,$7c,$00,$00,$00,$00,$00,$18,$38,$78,$18,$18,$18,$18,$18,$7e,$00,$00,$00,
+$00,$00,$7c,$c6,$06,$0c,$18,$30,$60,$c6,$fe,$00,$00,$00,$00,$00,$7c,$c6,$06,$06,$3c,$06,$06,$c6,$7c,$00,$00,$00,
+$00,$00,$0c,$1c,$3c,$6c,$cc,$fe,$0c,$0c,$1e,$00,$00,$00,$00,$00,$fe,$c0,$c0,$fc,$0e,$06,$06,$c6,$7c,$00,$00,$00,
+$00,$00,$38,$60,$c0,$c0,$fc,$c6,$c6,$c6,$7c,$00,$00,$00,$00,$00,$fe,$c6,$06,$0c,$18,$30,$30,$30,$30,$00,$00,$00,
+$00,$00,$7c,$c6,$c6,$c6,$7c,$c6,$c6,$c6,$7c,$00,$00,$00,$00,$00,$7c,$c6,$c6,$c6,$7e,$06,$06,$0c,$78,$00,$00,$00,
+$00,$00,$00,$18,$18,$00,$00,$00,$18,$18,$00,$00,$00,$00,$00,$00,$00,$18,$18,$00,$00,$00,$18,$18,$30,$00,$00,$00,
+$00,$00,$06,$0c,$18,$30,$60,$30,$18,$0c,$06,$00,$00,$00,$00,$00,$00,$00,$00,$fe,$00,$00,$fe,$00,$00,$00,$00,$00,
+$00,$00,$60,$30,$18,$0c,$06,$0c,$18,$30,$60,$00,$00,$00,$00,$00,$7c,$c6,$c6,$0c,$18,$18,$00,$18,$18,$00,$00,$00,
+$00,$00,$7c,$c6,$c6,$de,$de,$de,$dc,$c0,$7c,$00,$00,$00,$00,$00,$10,$38,$6c,$c6,$c6,$fe,$c6,$c6,$c6,$00,$00,$00,
+$00,$00,$fc,$66,$66,$66,$7c,$66,$66,$66,$fc,$00,$00,$00,$00,$00,$3c,$66,$c2,$c0,$c0,$c0,$c2,$66,$3c,$00,$00,$00,
+$00,$00,$f8,$6c,$66,$66,$66,$66,$66,$6c,$f8,$00,$00,$00,$00,$00,$fe,$66,$62,$68,$78,$68,$62,$66,$fe,$00,$00,$00,
+$00,$00,$fe,$66,$62,$68,$78,$68,$60,$60,$f0,$00,$00,$00,$00,$00,$3c,$66,$c2,$c0,$c0,$de,$c6,$66,$3a,$00,$00,$00,
+$00,$00,$c6,$c6,$c6,$c6,$fe,$c6,$c6,$c6,$c6,$00,$00,$00,$00,$00,$3c,$18,$18,$18,$18,$18,$18,$18,$3c,$00,$00,$00,
+$00,$00,$1e,$0c,$0c,$0c,$0c,$0c,$cc,$cc,$78,$00,$00,$00,$00,$00,$e6,$66,$6c,$6c,$78,$6c,$6c,$66,$e6,$00,$00,$00,
+$00,$00,$f0,$60,$60,$60,$60,$60,$62,$66,$fe,$00,$00,$00,$00,$00,$c6,$ee,$fe,$fe,$d6,$c6,$c6,$c6,$c6,$00,$00,$00,
+$00,$00,$c6,$e6,$f6,$fe,$de,$ce,$c6,$c6,$c6,$00,$00,$00,$00,$00,$38,$6c,$c6,$c6,$c6,$c6,$c6,$6c,$38,$00,$00,$00,
+$00,$00,$fc,$66,$66,$66,$7c,$60,$60,$60,$f0,$00,$00,$00,$00,$00,$7c,$c6,$c6,$c6,$c6,$d6,$de,$7c,$0c,$0e,$00,$00,
+$00,$00,$fc,$66,$66,$66,$7c,$6c,$66,$66,$e6,$00,$00,$00,$00,$00,$7c,$c6,$c6,$60,$38,$0c,$c6,$c6,$7c,$00,$00,$00,
+$00,$00,$7e,$7e,$5a,$18,$18,$18,$18,$18,$3c,$00,$00,$00,$00,$00,$c6,$c6,$c6,$c6,$c6,$c6,$c6,$c6,$7c,$00,$00,$00,
+$00,$00,$c6,$c6,$c6,$c6,$c6,$c6,$6c,$38,$10,$00,$00,$00,$00,$00,$c6,$c6,$c6,$c6,$d6,$d6,$fe,$7c,$6c,$00,$00,$00,
+$00,$00,$c6,$c6,$6c,$38,$38,$38,$6c,$c6,$c6,$00,$00,$00,$00,$00,$66,$66,$66,$66,$3c,$18,$18,$18,$3c,$00,$00,$00,
+$00,$00,$fe,$c6,$8c,$18,$30,$60,$c2,$c6,$fe,$00,$00,$00,$00,$00,$3c,$30,$30,$30,$30,$30,$30,$30,$3c,$00,$00,$00,
+$00,$00,$80,$c0,$e0,$70,$38,$1c,$0e,$06,$02,$00,$00,$00,$00,$00,$3c,$0c,$0c,$0c,$0c,$0c,$0c,$0c,$3c,$00,$00,$00,
+$10,$38,$6c,$c6,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$ff,$00,
+$30,$30,$18,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$78,$0c,$7c,$cc,$cc,$76,$00,$00,$00,
+$00,$00,$e0,$60,$60,$78,$6c,$66,$66,$66,$dc,$00,$00,$00,$00,$00,$00,$00,$00,$7c,$c6,$c0,$c0,$c6,$7c,$00,$00,$00,
+$00,$00,$1c,$0c,$0c,$3c,$6c,$cc,$cc,$cc,$76,$00,$00,$00,$00,$00,$00,$00,$00,$7c,$c6,$fe,$c0,$c6,$7c,$00,$00,$00,
+$00,$00,$38,$6c,$64,$60,$f0,$60,$60,$60,$f0,$00,$00,$00,$00,$00,$00,$00,$00,$76,$cc,$cc,$cc,$7c,$0c,$cc,$78,$00,
+$00,$00,$e0,$60,$60,$6c,$76,$66,$66,$66,$e6,$00,$00,$00,$00,$00,$18,$18,$00,$38,$18,$18,$18,$18,$3c,$00,$00,$00,
+$00,$00,$06,$06,$00,$0e,$06,$06,$06,$06,$66,$66,$3c,$00,$00,$00,$e0,$60,$60,$66,$6c,$78,$6c,$66,$e6,$00,$00,$00,
+$00,$00,$38,$18,$18,$18,$18,$18,$18,$18,$3c,$00,$00,$00,$00,$00,$00,$00,$00,$ec,$fe,$d6,$d6,$d6,$d6,$00,$00,$00,
+$00,$00,$00,$00,$00,$dc,$66,$66,$66,$66,$66,$00,$00,$00,$00,$00,$00,$00,$00,$7c,$c6,$c6,$c6,$c6,$7c,$00,$00,$00,
+$00,$00,$00,$00,$00,$dc,$66,$66,$66,$7c,$60,$60,$f0,$00,$00,$00,$00,$00,$00,$76,$cc,$cc,$cc,$7c,$0c,$0c,$1e,$00,
+$00,$00,$00,$00,$00,$dc,$76,$62,$60,$60,$f0,$00,$00,$00,$00,$00,$00,$00,$00,$7c,$c6,$70,$1c,$c6,$7c,$00,$00,$00,
+$00,$00,$10,$30,$30,$fc,$30,$30,$30,$36,$1c,$00,$00,$00,$00,$00,$00,$00,$00,$cc,$cc,$cc,$cc,$cc,$76,$00,$00,$00,
+$00,$00,$00,$00,$00,$66,$66,$66,$66,$3c,$18,$00,$00,$00,$00,$00,$00,$00,$00,$c6,$c6,$d6,$d6,$fe,$6c,$00,$00,$00,
+$00,$00,$00,$00,$00,$c6,$6c,$38,$38,$6c,$c6,$00,$00,$00,$00,$00,$00,$00,$00,$c6,$c6,$c6,$c6,$7e,$06,$0c,$f8,$00,
+$00,$00,$00,$00,$00,$fe,$cc,$18,$30,$66,$fe,$00,$00,$00,$00,$00,$0e,$18,$18,$18,$70,$18,$18,$18,$0e,$00,$00,$00,
+$00,$00,$18,$18,$18,$18,$00,$18,$18,$18,$18,$00,$00,$00,$00,$00,$70,$18,$18,$18,$0e,$18,$18,$18,$70,$00,$00,$00,
+$00,$00,$76,$dc,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$10,$38,$6c,$c6,$c6,$fe,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$6c,$00,$fe,$66,$62,$68,$78,$68,$60,$62,$66,$fe,$00,$00,$00,$b0,$d8,$d8,$d8,$d8,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$11,$44,$11,$44,$11,$44,$11,$44,$11,$44,$11,$44,$11,$44,$55,$aa,$55,$aa,$55,$aa,$55,$aa,$55,$aa,$55,$aa,$55,$aa,
+$dd,$77,$dd,$77,$dd,$77,$dd,$77,$dd,$77,$dd,$77,$dd,$77,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,
+$18,$18,$18,$18,$18,$18,$18,$f8,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$f8,$18,$f8,$18,$18,$18,$18,$18,$18,
+$36,$36,$36,$36,$36,$36,$36,$f6,$36,$36,$36,$36,$36,$36,$00,$00,$00,$00,$00,$00,$00,$fe,$36,$36,$36,$36,$36,$36,
+$00,$00,$00,$28,$00,$7c,$c6,$fe,$c0,$c0,$c6,$7c,$00,$00,$36,$36,$36,$36,$36,$f6,$06,$f6,$36,$36,$36,$36,$36,$36,
+$36,$36,$36,$36,$36,$36,$36,$36,$36,$36,$36,$36,$36,$36,$00,$00,$00,$00,$00,$fe,$06,$f6,$36,$36,$36,$36,$36,$36,
+$36,$36,$36,$36,$36,$f6,$06,$fe,$00,$00,$00,$00,$00,$00,$36,$36,$36,$36,$36,$36,$36,$fe,$00,$00,$00,$00,$00,$00,
+$18,$18,$18,$18,$18,$f8,$18,$f8,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$f8,$18,$18,$18,$18,$18,$18,
+$00,$00,$1e,$36,$66,$c6,$c6,$fe,$c6,$c6,$c6,$c6,$00,$00,$00,$00,$fe,$62,$62,$60,$7c,$66,$66,$66,$66,$fc,$00,$00,
+$00,$00,$fc,$66,$66,$66,$7c,$66,$66,$66,$66,$fc,$00,$00,$00,$00,$fe,$62,$62,$60,$60,$60,$60,$60,$60,$f0,$00,$00,
+$00,$00,$1e,$36,$66,$66,$66,$66,$66,$66,$66,$ff,$c3,$81,$00,$00,$fe,$66,$62,$68,$78,$68,$60,$62,$66,$fe,$00,$00,
+$00,$00,$d6,$d6,$54,$54,$7c,$7c,$54,$d6,$d6,$d6,$00,$00,$00,$00,$7c,$c6,$06,$06,$3c,$06,$06,$06,$c6,$7c,$00,$00,
+$00,$00,$c6,$c6,$ce,$ce,$d6,$e6,$e6,$c6,$c6,$c6,$00,$00,$38,$38,$c6,$c6,$ce,$ce,$d6,$e6,$e6,$c6,$c6,$c6,$00,$00,
+$00,$00,$e6,$66,$6c,$6c,$78,$78,$6c,$6c,$66,$e6,$00,$00,$00,$00,$1e,$36,$66,$c6,$c6,$c6,$c6,$c6,$c6,$c6,$00,$00,
+$00,$00,$c6,$ee,$fe,$fe,$d6,$c6,$c6,$c6,$c6,$c6,$00,$00,$00,$00,$c6,$c6,$c6,$c6,$fe,$c6,$c6,$c6,$c6,$c6,$00,$00,
+$00,$00,$7c,$c6,$c6,$c6,$c6,$c6,$c6,$c6,$c6,$7c,$00,$00,$00,$00,$fe,$c6,$c6,$c6,$c6,$c6,$c6,$c6,$c6,$c6,$00,$00,
+$00,$00,$fc,$66,$66,$66,$7c,$60,$60,$60,$60,$f0,$00,$00,$00,$00,$3c,$66,$c2,$c0,$c0,$c0,$c0,$c2,$66,$3c,$00,$00,
+$00,$00,$7e,$5a,$18,$18,$18,$18,$18,$18,$18,$3c,$00,$00,$00,$00,$c6,$c6,$c6,$c6,$c6,$7e,$06,$06,$c6,$7c,$00,$00,
+$00,$3c,$18,$7e,$db,$db,$db,$db,$db,$7e,$18,$3c,$00,$00,$00,$00,$c6,$c6,$6c,$7c,$38,$38,$7c,$6c,$c6,$c6,$00,$00,
+$00,$00,$cc,$cc,$cc,$cc,$cc,$cc,$cc,$cc,$cc,$fe,$06,$06,$00,$00,$c6,$c6,$c6,$c6,$c6,$7e,$06,$06,$06,$06,$00,$00,
+$00,$00,$db,$db,$db,$db,$db,$db,$db,$db,$db,$ff,$00,$00,$00,$00,$db,$db,$db,$db,$db,$db,$db,$db,$db,$ff,$03,$03,
+$00,$00,$f8,$b0,$30,$30,$3c,$36,$36,$36,$36,$7c,$00,$00,$00,$00,$c3,$c3,$c3,$c3,$f3,$db,$db,$db,$db,$f3,$00,$00,
+$00,$00,$f0,$60,$60,$60,$7c,$66,$66,$66,$66,$fc,$00,$00,$00,$00,$7c,$c6,$06,$26,$3e,$26,$06,$06,$c6,$7c,$00,$00,
+$00,$00,$ce,$db,$db,$db,$fb,$db,$db,$db,$db,$ce,$00,$00,$00,$00,$3f,$66,$66,$66,$3e,$3e,$66,$66,$66,$e7,$00,$00,
+$00,$00,$00,$00,$00,$78,$0c,$7c,$cc,$cc,$cc,$76,$00,$00,$00,$02,$06,$3c,$60,$60,$7c,$66,$66,$66,$66,$3c,$00,$00,
+$00,$00,$00,$00,$00,$fc,$66,$66,$7c,$66,$66,$fc,$00,$00,$00,$00,$00,$00,$00,$7e,$32,$32,$30,$30,$30,$78,$00,$00,
+$00,$00,$00,$00,$00,$1e,$36,$36,$66,$66,$66,$ff,$c3,$c3,$00,$00,$00,$00,$00,$7c,$c6,$fe,$c0,$c0,$c6,$7c,$00,$00,
+$00,$00,$00,$00,$00,$d6,$d6,$54,$7c,$54,$d6,$d6,$00,$00,$00,$00,$00,$00,$00,$3c,$66,$06,$0c,$06,$66,$3c,$00,$00,
+$00,$00,$00,$00,$00,$c6,$c6,$ce,$d6,$e6,$c6,$c6,$00,$00,$00,$00,$00,$38,$38,$c6,$c6,$ce,$d6,$e6,$c6,$c6,$00,$00,
+$00,$00,$00,$00,$00,$e6,$6c,$78,$78,$6c,$66,$e6,$00,$00,$00,$00,$00,$00,$00,$1e,$36,$66,$66,$66,$66,$66,$00,$00,
+$00,$00,$00,$00,$00,$c6,$ee,$fe,$fe,$d6,$d6,$c6,$00,$00,$00,$00,$00,$00,$00,$c6,$c6,$c6,$fe,$c6,$c6,$c6,$00,$00,
+$00,$00,$00,$00,$00,$7c,$c6,$c6,$c6,$c6,$c6,$7c,$00,$00,$00,$00,$00,$00,$00,$fe,$c6,$c6,$c6,$c6,$c6,$c6,$00,$00,
+$00,$00,$00,$00,$00,$dc,$66,$66,$66,$66,$66,$7c,$60,$f0,$00,$00,$00,$00,$00,$7c,$c6,$c0,$c0,$c0,$c6,$7c,$00,$00,
+$00,$00,$00,$00,$00,$7e,$5a,$18,$18,$18,$18,$3c,$00,$00,$00,$00,$00,$00,$00,$c6,$c6,$c6,$c6,$c6,$7e,$06,$c6,$7c,
+$00,$00,$00,$00,$3c,$18,$7e,$db,$db,$db,$db,$7e,$18,$3c,$00,$00,$00,$00,$00,$c6,$6c,$38,$38,$38,$6c,$c6,$00,$00,
+$00,$00,$00,$00,$00,$cc,$cc,$cc,$cc,$cc,$cc,$fe,$06,$06,$00,$00,$00,$00,$00,$c6,$c6,$c6,$c6,$7e,$06,$06,$00,$00,
+$00,$00,$00,$00,$00,$d6,$d6,$d6,$d6,$d6,$d6,$fe,$00,$00,$00,$00,$00,$00,$00,$d6,$d6,$d6,$d6,$d6,$d6,$fe,$03,$03,
+$00,$00,$00,$00,$00,$f8,$b0,$30,$3e,$33,$33,$7e,$00,$00,$00,$00,$00,$00,$00,$c6,$c6,$c6,$f6,$de,$de,$f6,$00,$00,
+$00,$00,$00,$00,$00,$f0,$60,$60,$7c,$66,$66,$fc,$00,$00,$00,$00,$00,$00,$00,$3c,$66,$06,$1e,$06,$66,$3c,$00,$00,
+$00,$00,$00,$00,$00,$ce,$db,$db,$fb,$db,$db,$ce,$00,$00,$00,$00,$00,$00,$00,$7e,$cc,$cc,$fc,$6c,$cc,$ce,$00,$00);
+const kgiFont14Wdt: array[0..256-1] of Byte = (
+$00,$08,$08,$07,$07,$08,$08,$24,$08,$16,$08,$07,$16,$07,$08,$08,$07,$07,$16,$16,$08,$07,$07,$16,$16,$16,$07,$07,
+$07,$07,$07,$07,$00,$24,$16,$07,$07,$07,$07,$13,$24,$24,$08,$16,$23,$07,$32,$07,$07,$16,$07,$07,$07,$07,$07,$07,
+$07,$07,$32,$23,$16,$07,$16,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$24,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,
+$16,$07,$07,$07,$07,$16,$07,$24,$07,$24,$07,$08,$23,$07,$07,$07,$07,$07,$06,$07,$07,$24,$16,$07,$24,$07,$07,$07,
+$07,$07,$07,$07,$07,$07,$16,$07,$07,$07,$07,$16,$32,$16,$07,$07,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$07,$05,$00,$00,$00,$00,$00,$00,$08,$08,$08,$08,$08,$08,$08,$08,$07,$08,$08,$08,$08,$08,$08,$08,$07,$07,$07,$07,
+$08,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$16,$07,$08,$07,$07,$07,$08,$08,$07,$08,$07,$07,$08,$08,
+$07,$16,$07,$16,$08,$07,$07,$16,$07,$07,$07,$16,$07,$07,$07,$07,$07,$07,$16,$07,$08,$07,$07,$07,$07,$08,$08,$07,
+$07,$16,$08,$07);
-function createFontTexture (const font: PByte; const fontwdt: PByte; prop: Boolean): GLuint;
+const kgiFont16: array[0..256*16-1] of Byte = (
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$7e,$81,$a5,$81,$81,$bd,$99,$81,$81,$7e,
+$00,$00,$00,$00,$00,$00,$7e,$ff,$db,$ff,$ff,$c3,$e7,$ff,$ff,$7e,$00,$00,$00,$00,$00,$00,$00,$00,$6c,$fe,$fe,$fe,
+$fe,$7c,$38,$10,$00,$00,$00,$00,$00,$00,$00,$00,$10,$38,$7c,$fe,$7c,$38,$10,$00,$00,$00,$00,$00,$00,$00,$00,$18,
+$3c,$3c,$e7,$e7,$e7,$99,$18,$3c,$00,$00,$00,$00,$00,$00,$00,$18,$3c,$7e,$ff,$ff,$7e,$18,$18,$3c,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$18,$3c,$3c,$18,$00,$00,$00,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$e7,$c3,$c3,$e7,$ff,$ff,
+$ff,$ff,$ff,$ff,$00,$00,$00,$00,$00,$3c,$66,$42,$42,$66,$3c,$00,$00,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$c3,$99,$bd,
+$bd,$99,$c3,$ff,$ff,$ff,$ff,$ff,$00,$00,$1e,$0e,$1a,$32,$78,$cc,$cc,$cc,$cc,$78,$00,$00,$00,$00,$00,$00,$3c,$66,
+$66,$66,$66,$3c,$18,$7e,$18,$18,$00,$00,$00,$00,$00,$00,$3e,$30,$3e,$30,$30,$30,$30,$70,$f0,$e0,$00,$00,$00,$00,
+$00,$00,$7f,$63,$7f,$63,$63,$63,$63,$67,$e7,$e6,$c0,$00,$00,$00,$00,$00,$00,$18,$18,$db,$3c,$e7,$3c,$db,$18,$18,
+$00,$00,$00,$00,$00,$80,$c0,$e0,$f0,$f8,$fe,$f8,$f0,$e0,$c0,$80,$00,$00,$00,$00,$00,$02,$06,$0e,$1e,$3e,$fe,$3e,
+$1e,$0e,$06,$02,$00,$00,$00,$00,$00,$00,$18,$3c,$7e,$18,$18,$18,$18,$7e,$3c,$18,$00,$00,$00,$00,$00,$00,$66,$66,
+$66,$66,$66,$66,$66,$00,$66,$66,$00,$00,$00,$00,$00,$00,$7f,$db,$db,$db,$7b,$1b,$1b,$1b,$1b,$1b,$00,$00,$00,$00,
+$00,$7c,$c6,$60,$38,$6c,$c6,$c6,$6c,$38,$0c,$c6,$7c,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$fe,$fe,$fe,$fe,
+$00,$00,$00,$00,$00,$00,$18,$3c,$7e,$18,$18,$18,$18,$7e,$3c,$18,$7e,$00,$00,$00,$00,$00,$18,$3c,$7e,$18,$18,$18,
+$18,$18,$18,$18,$00,$00,$00,$00,$00,$00,$18,$18,$18,$18,$18,$18,$18,$7e,$3c,$18,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$18,$0c,$fe,$0c,$18,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$30,$60,$fe,$60,$30,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$c0,$c0,$c0,$c0,$fe,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$28,$6c,$fe,$6c,$28,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$10,$38,$38,$7c,$7c,$fe,$fe,$00,$00,$00,$00,$00,$00,$00,$00,$00,$fe,$fe,$7c,$7c,
+$38,$38,$10,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$18,$3c,
+$3c,$3c,$18,$18,$18,$00,$18,$18,$00,$00,$00,$00,$00,$66,$66,$66,$24,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$6c,$6c,$fe,$6c,$6c,$6c,$fe,$6c,$6c,$00,$00,$00,$00,$18,$18,$7c,$c6,$c2,$c0,$7c,$06,$86,$c6,$7c,$18,
+$18,$00,$00,$00,$00,$00,$00,$00,$c2,$c6,$0c,$18,$30,$60,$c6,$86,$00,$00,$00,$00,$00,$00,$38,$6c,$6c,$38,$76,$dc,
+$cc,$cc,$cc,$76,$00,$00,$00,$00,$00,$30,$30,$30,$60,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$0c,$18,
+$30,$30,$30,$30,$30,$30,$18,$0c,$00,$00,$00,$00,$00,$00,$30,$18,$0c,$0c,$0c,$0c,$0c,$0c,$18,$30,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$66,$3c,$ff,$3c,$66,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$18,$18,$7e,$18,$18,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$18,$18,$18,$30,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$fe,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$18,$18,$00,$00,$00,$00,$00,$00,$00,$00,
+$02,$06,$0c,$18,$30,$60,$c0,$80,$00,$00,$00,$00,$00,$00,$7c,$c6,$c6,$ce,$d6,$d6,$e6,$c6,$c6,$7c,$00,$00,$00,$00,
+$00,$00,$18,$38,$78,$18,$18,$18,$18,$18,$18,$7e,$00,$00,$00,$00,$00,$00,$7c,$c6,$06,$0c,$18,$30,$60,$c0,$c6,$fe,
+$00,$00,$00,$00,$00,$00,$7c,$c6,$06,$06,$3c,$06,$06,$06,$c6,$7c,$00,$00,$00,$00,$00,$00,$0c,$1c,$3c,$6c,$cc,$fe,
+$0c,$0c,$0c,$1e,$00,$00,$00,$00,$00,$00,$fe,$c0,$c0,$c0,$fc,$0e,$06,$06,$c6,$7c,$00,$00,$00,$00,$00,$00,$38,$60,
+$c0,$c0,$fc,$c6,$c6,$c6,$c6,$7c,$00,$00,$00,$00,$00,$00,$fe,$c6,$06,$06,$0c,$18,$30,$30,$30,$30,$00,$00,$00,$00,
+$00,$00,$7c,$c6,$c6,$c6,$7c,$c6,$c6,$c6,$c6,$7c,$00,$00,$00,$00,$00,$00,$7c,$c6,$c6,$c6,$7e,$06,$06,$06,$0c,$78,
+$00,$00,$00,$00,$00,$00,$00,$00,$18,$18,$00,$00,$00,$18,$18,$00,$00,$00,$00,$00,$00,$00,$00,$00,$18,$18,$00,$00,
+$00,$18,$18,$30,$00,$00,$00,$00,$00,$00,$00,$06,$0c,$18,$30,$60,$30,$18,$0c,$06,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$fe,$00,$00,$fe,$00,$00,$00,$00,$00,$00,$00,$00,$00,$60,$30,$18,$0c,$06,$0c,$18,$30,$60,$00,$00,$00,$00,
+$00,$00,$7c,$c6,$c6,$0c,$18,$18,$18,$00,$18,$18,$00,$00,$00,$00,$00,$00,$00,$7c,$c6,$c6,$de,$de,$de,$dc,$c0,$7c,
+$00,$00,$00,$00,$00,$00,$10,$38,$6c,$c6,$c6,$fe,$c6,$c6,$c6,$c6,$00,$00,$00,$00,$00,$00,$fc,$66,$66,$66,$7c,$66,
+$66,$66,$66,$fc,$00,$00,$00,$00,$00,$00,$3c,$66,$c2,$c0,$c0,$c0,$c0,$c2,$66,$3c,$00,$00,$00,$00,$00,$00,$f8,$6c,
+$66,$66,$66,$66,$66,$66,$6c,$f8,$00,$00,$00,$00,$00,$00,$fe,$66,$62,$68,$78,$68,$60,$62,$66,$fe,$00,$00,$00,$00,
+$00,$00,$fe,$66,$62,$68,$78,$68,$60,$60,$60,$f0,$00,$00,$00,$00,$00,$00,$3c,$66,$c2,$c0,$c0,$de,$c6,$c6,$66,$3a,
+$00,$00,$00,$00,$00,$00,$c6,$c6,$c6,$c6,$fe,$c6,$c6,$c6,$c6,$c6,$00,$00,$00,$00,$00,$00,$3c,$18,$18,$18,$18,$18,
+$18,$18,$18,$3c,$00,$00,$00,$00,$00,$00,$1e,$0c,$0c,$0c,$0c,$0c,$cc,$cc,$cc,$78,$00,$00,$00,$00,$00,$00,$e6,$66,
+$6c,$6c,$78,$78,$6c,$66,$66,$e6,$00,$00,$00,$00,$00,$00,$f0,$60,$60,$60,$60,$60,$60,$62,$66,$fe,$00,$00,$00,$00,
+$00,$00,$c6,$ee,$fe,$fe,$d6,$c6,$c6,$c6,$c6,$c6,$00,$00,$00,$00,$00,$00,$c6,$e6,$f6,$fe,$de,$ce,$c6,$c6,$c6,$c6,
+$00,$00,$00,$00,$00,$00,$38,$6c,$c6,$c6,$c6,$c6,$c6,$c6,$6c,$38,$00,$00,$00,$00,$00,$00,$fc,$66,$66,$66,$7c,$60,
+$60,$60,$60,$f0,$00,$00,$00,$00,$00,$00,$7c,$c6,$c6,$c6,$c6,$c6,$c6,$d6,$de,$7c,$0c,$0e,$00,$00,$00,$00,$fc,$66,
+$66,$66,$7c,$6c,$66,$66,$66,$e6,$00,$00,$00,$00,$00,$00,$7c,$c6,$c6,$60,$38,$0c,$06,$c6,$c6,$7c,$00,$00,$00,$00,
+$00,$00,$7e,$7e,$5a,$18,$18,$18,$18,$18,$18,$3c,$00,$00,$00,$00,$00,$00,$c6,$c6,$c6,$c6,$c6,$c6,$c6,$c6,$c6,$7c,
+$00,$00,$00,$00,$00,$00,$c6,$c6,$c6,$c6,$c6,$c6,$c6,$6c,$38,$10,$00,$00,$00,$00,$00,$00,$c6,$c6,$c6,$c6,$c6,$d6,
+$d6,$fe,$6c,$6c,$00,$00,$00,$00,$00,$00,$c6,$c6,$6c,$6c,$38,$38,$6c,$6c,$c6,$c6,$00,$00,$00,$00,$00,$00,$66,$66,
+$66,$66,$3c,$18,$18,$18,$18,$3c,$00,$00,$00,$00,$00,$00,$fe,$c6,$86,$0c,$18,$30,$60,$c2,$c6,$fe,$00,$00,$00,$00,
+$00,$00,$3c,$30,$30,$30,$30,$30,$30,$30,$30,$3c,$00,$00,$00,$00,$00,$00,$00,$80,$c0,$e0,$70,$38,$1c,$0e,$06,$02,
+$00,$00,$00,$00,$00,$00,$3c,$0c,$0c,$0c,$0c,$0c,$0c,$0c,$0c,$3c,$00,$00,$00,$00,$10,$38,$6c,$c6,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$ff,$00,$00,$30,$30,$18,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$78,$0c,$7c,$cc,$cc,$cc,$76,$00,$00,$00,$00,
+$00,$00,$e0,$60,$60,$78,$6c,$66,$66,$66,$66,$dc,$00,$00,$00,$00,$00,$00,$00,$00,$00,$7c,$c6,$c0,$c0,$c0,$c6,$7c,
+$00,$00,$00,$00,$00,$00,$1c,$0c,$0c,$3c,$6c,$cc,$cc,$cc,$cc,$76,$00,$00,$00,$00,$00,$00,$00,$00,$00,$7c,$c6,$fe,
+$c0,$c0,$c6,$7c,$00,$00,$00,$00,$00,$00,$38,$6c,$64,$60,$f0,$60,$60,$60,$60,$f0,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$76,$cc,$cc,$cc,$cc,$cc,$7c,$0c,$cc,$78,$00,$00,$00,$e0,$60,$60,$6c,$76,$66,$66,$66,$66,$e6,$00,$00,$00,$00,
+$00,$00,$18,$18,$00,$38,$18,$18,$18,$18,$18,$3c,$00,$00,$00,$00,$00,$00,$06,$06,$00,$0e,$06,$06,$06,$06,$06,$06,
+$66,$66,$3c,$00,$00,$00,$e0,$60,$60,$66,$6c,$78,$78,$6c,$66,$e6,$00,$00,$00,$00,$00,$00,$38,$18,$18,$18,$18,$18,
+$18,$18,$18,$3c,$00,$00,$00,$00,$00,$00,$00,$00,$00,$ec,$fe,$d6,$d6,$d6,$d6,$d6,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$dc,$66,$66,$66,$66,$66,$66,$00,$00,$00,$00,$00,$00,$00,$00,$00,$7c,$c6,$c6,$c6,$c6,$c6,$7c,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$dc,$66,$66,$66,$66,$66,$7c,$60,$60,$f0,$00,$00,$00,$00,$00,$00,$76,$cc,$cc,$cc,$cc,$cc,$7c,
+$0c,$0c,$1e,$00,$00,$00,$00,$00,$00,$dc,$76,$62,$60,$60,$60,$f0,$00,$00,$00,$00,$00,$00,$00,$00,$00,$7c,$c6,$60,
+$38,$0c,$c6,$7c,$00,$00,$00,$00,$00,$00,$10,$30,$30,$fc,$30,$30,$30,$30,$36,$1c,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$cc,$cc,$cc,$cc,$cc,$cc,$76,$00,$00,$00,$00,$00,$00,$00,$00,$00,$66,$66,$66,$66,$66,$3c,$18,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$c6,$c6,$c6,$d6,$d6,$fe,$6c,$00,$00,$00,$00,$00,$00,$00,$00,$00,$c6,$6c,$38,$38,$38,$6c,$c6,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$c6,$c6,$c6,$c6,$c6,$c6,$7e,$06,$0c,$f8,$00,$00,$00,$00,$00,$00,$fe,$cc,$18,
+$30,$60,$c6,$fe,$00,$00,$00,$00,$00,$00,$0e,$18,$18,$18,$70,$18,$18,$18,$18,$0e,$00,$00,$00,$00,$00,$00,$18,$18,
+$18,$18,$00,$18,$18,$18,$18,$18,$00,$00,$00,$00,$00,$00,$70,$18,$18,$18,$0e,$18,$18,$18,$18,$70,$00,$00,$00,$00,
+$00,$00,$76,$dc,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$10,$38,$6c,$c6,$c6,$c6,$fe,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$6c,$00,$fe,$66,$62,$68,$78,$68,$60,$62,$66,$fe,$00,$00,$00,$00,$00,$b0,$d8,$d8,$d8,$d8,$d8,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$11,$44,$11,$44,$11,$44,$11,$44,$11,$44,$11,$44,
+$11,$44,$11,$44,$55,$aa,$55,$aa,$55,$aa,$55,$aa,$55,$aa,$55,$aa,$55,$aa,$55,$aa,$dd,$77,$dd,$77,$dd,$77,$dd,$77,
+$dd,$77,$dd,$77,$dd,$77,$dd,$77,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,
+$18,$18,$18,$f8,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$f8,$18,$f8,$18,$18,$18,$18,$18,$18,$18,$18,
+$36,$36,$36,$36,$36,$36,$36,$f6,$36,$36,$36,$36,$36,$36,$36,$36,$00,$00,$00,$00,$00,$00,$00,$fe,$36,$36,$36,$36,
+$36,$36,$36,$36,$00,$00,$28,$28,$00,$7c,$c6,$fe,$c0,$c0,$c6,$7c,$00,$00,$00,$00,$36,$36,$36,$36,$36,$f6,$06,$f6,
+$36,$36,$36,$36,$36,$36,$36,$36,$36,$36,$36,$36,$36,$36,$36,$36,$36,$36,$36,$36,$36,$36,$36,$36,$00,$00,$00,$00,
+$00,$fe,$06,$f6,$36,$36,$36,$36,$36,$36,$36,$36,$36,$36,$36,$36,$36,$f6,$06,$fe,$00,$00,$00,$00,$00,$00,$00,$00,
+$36,$36,$36,$36,$36,$36,$36,$fe,$00,$00,$00,$00,$00,$00,$00,$00,$18,$18,$18,$18,$18,$f8,$18,$f8,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$f8,$18,$18,$18,$18,$18,$18,$18,$18,$00,$00,$1e,$36,$66,$c6,$c6,$fe,
+$c6,$c6,$c6,$c6,$00,$00,$00,$00,$00,$00,$fe,$62,$62,$60,$7c,$66,$66,$66,$66,$fc,$00,$00,$00,$00,$00,$00,$fc,$66,
+$66,$66,$7c,$66,$66,$66,$66,$fc,$00,$00,$00,$00,$00,$00,$fe,$62,$62,$60,$60,$60,$60,$60,$60,$f0,$00,$00,$00,$00,
+$00,$00,$1e,$36,$66,$66,$66,$66,$66,$66,$66,$ff,$c3,$81,$00,$00,$00,$00,$fe,$66,$62,$68,$78,$68,$60,$62,$66,$fe,
+$00,$00,$00,$00,$00,$00,$d6,$d6,$54,$54,$7c,$7c,$54,$d6,$d6,$d6,$00,$00,$00,$00,$00,$00,$7c,$c6,$06,$06,$3c,$06,
+$06,$06,$c6,$7c,$00,$00,$00,$00,$00,$00,$c6,$c6,$ce,$ce,$d6,$e6,$e6,$c6,$c6,$c6,$00,$00,$00,$00,$38,$38,$c6,$c6,
+$ce,$ce,$d6,$e6,$e6,$c6,$c6,$c6,$00,$00,$00,$00,$00,$00,$e6,$66,$6c,$6c,$78,$78,$6c,$6c,$66,$e6,$00,$00,$00,$00,
+$00,$00,$1e,$36,$66,$c6,$c6,$c6,$c6,$c6,$c6,$c6,$00,$00,$00,$00,$00,$00,$c6,$ee,$fe,$fe,$d6,$c6,$c6,$c6,$c6,$c6,
+$00,$00,$00,$00,$00,$00,$c6,$c6,$c6,$c6,$fe,$c6,$c6,$c6,$c6,$c6,$00,$00,$00,$00,$00,$00,$7c,$c6,$c6,$c6,$c6,$c6,
+$c6,$c6,$c6,$7c,$00,$00,$00,$00,$00,$00,$fe,$c6,$c6,$c6,$c6,$c6,$c6,$c6,$c6,$c6,$00,$00,$00,$00,$00,$00,$fc,$66,
+$66,$66,$7c,$60,$60,$60,$60,$f0,$00,$00,$00,$00,$00,$00,$3c,$66,$c2,$c0,$c0,$c0,$c0,$c2,$66,$3c,$00,$00,$00,$00,
+$00,$00,$7e,$5a,$18,$18,$18,$18,$18,$18,$18,$3c,$00,$00,$00,$00,$00,$00,$c6,$c6,$c6,$c6,$c6,$7e,$06,$06,$c6,$7c,
+$00,$00,$00,$00,$00,$3c,$18,$7e,$db,$db,$db,$db,$db,$7e,$18,$3c,$00,$00,$00,$00,$00,$00,$c6,$c6,$6c,$7c,$38,$38,
+$7c,$6c,$c6,$c6,$00,$00,$00,$00,$00,$00,$cc,$cc,$cc,$cc,$cc,$cc,$cc,$cc,$cc,$fe,$06,$06,$00,$00,$00,$00,$c6,$c6,
+$c6,$c6,$c6,$7e,$06,$06,$06,$06,$00,$00,$00,$00,$00,$00,$db,$db,$db,$db,$db,$db,$db,$db,$db,$ff,$00,$00,$00,$00,
+$00,$00,$db,$db,$db,$db,$db,$db,$db,$db,$db,$ff,$03,$03,$00,$00,$00,$00,$f8,$b0,$30,$30,$3c,$36,$36,$36,$36,$7c,
+$00,$00,$00,$00,$00,$00,$c3,$c3,$c3,$c3,$f3,$db,$db,$db,$db,$f3,$00,$00,$00,$00,$00,$00,$f0,$60,$60,$60,$7c,$66,
+$66,$66,$66,$fc,$00,$00,$00,$00,$00,$00,$7c,$c6,$06,$26,$3e,$26,$06,$06,$c6,$7c,$00,$00,$00,$00,$00,$00,$ce,$db,
+$db,$db,$fb,$db,$db,$db,$db,$ce,$00,$00,$00,$00,$00,$00,$3f,$66,$66,$66,$3e,$3e,$66,$66,$66,$e7,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$78,$0c,$7c,$cc,$cc,$cc,$76,$00,$00,$00,$00,$00,$02,$06,$3c,$60,$60,$7c,$66,$66,$66,$66,$3c,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$fc,$66,$66,$7c,$66,$66,$fc,$00,$00,$00,$00,$00,$00,$00,$00,$00,$7e,$32,$32,
+$30,$30,$30,$78,$00,$00,$00,$00,$00,$00,$00,$00,$00,$1e,$36,$36,$66,$66,$66,$ff,$c3,$c3,$00,$00,$00,$00,$00,$00,
+$00,$7c,$c6,$fe,$c0,$c0,$c6,$7c,$00,$00,$00,$00,$00,$00,$00,$00,$00,$d6,$d6,$54,$7c,$54,$d6,$d6,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$3c,$66,$06,$0c,$06,$66,$3c,$00,$00,$00,$00,$00,$00,$00,$00,$00,$c6,$c6,$ce,$d6,$e6,$c6,$c6,
+$00,$00,$00,$00,$00,$00,$00,$38,$38,$c6,$c6,$ce,$d6,$e6,$c6,$c6,$00,$00,$00,$00,$00,$00,$00,$00,$00,$e6,$6c,$78,
+$78,$6c,$66,$e6,$00,$00,$00,$00,$00,$00,$00,$00,$00,$1e,$36,$66,$66,$66,$66,$66,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$c6,$ee,$fe,$fe,$d6,$d6,$c6,$00,$00,$00,$00,$00,$00,$00,$00,$00,$c6,$c6,$c6,$fe,$c6,$c6,$c6,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$7c,$c6,$c6,$c6,$c6,$c6,$7c,$00,$00,$00,$00,$00,$00,$00,$00,$00,$fe,$c6,$c6,$c6,$c6,$c6,$c6,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$dc,$66,$66,$66,$66,$66,$7c,$60,$60,$f0,$00,$00,$00,$00,$00,$00,$7c,$c6,$c0,
+$c0,$c0,$c6,$7c,$00,$00,$00,$00,$00,$00,$00,$00,$00,$7e,$5a,$18,$18,$18,$18,$3c,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$c6,$c6,$c6,$c6,$c6,$7e,$06,$06,$c6,$7c,$00,$00,$00,$00,$00,$3c,$18,$7e,$db,$db,$db,$db,$7e,$18,$18,$3c,$00,
+$00,$00,$00,$00,$00,$c6,$6c,$38,$38,$38,$6c,$c6,$00,$00,$00,$00,$00,$00,$00,$00,$00,$cc,$cc,$cc,$cc,$cc,$cc,$fe,
+$06,$06,$00,$00,$00,$00,$00,$00,$00,$c6,$c6,$c6,$c6,$7e,$06,$06,$00,$00,$00,$00,$00,$00,$00,$00,$00,$d6,$d6,$d6,
+$d6,$d6,$d6,$fe,$00,$00,$00,$00,$00,$00,$00,$00,$00,$d6,$d6,$d6,$d6,$d6,$d6,$fe,$03,$03,$00,$00,$00,$00,$00,$00,
+$00,$f8,$b0,$30,$3e,$33,$33,$7e,$00,$00,$00,$00,$00,$00,$00,$00,$00,$c6,$c6,$c6,$f6,$de,$de,$f6,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$f0,$60,$60,$7c,$66,$66,$fc,$00,$00,$00,$00,$00,$00,$00,$00,$00,$3c,$66,$06,$1e,$06,$66,$3c,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$ce,$db,$db,$fb,$db,$db,$ce,$00,$00,$00,$00,$00,$00,$00,$00,$00,$7e,$cc,$cc,
+$fc,$6c,$cc,$ce,$00,$00,$00,$00);
+const kgiFont16Wdt: array[0..256-1] of Byte = (
+$00,$08,$08,$07,$07,$08,$08,$24,$08,$16,$08,$07,$16,$07,$08,$08,$07,$07,$16,$16,$08,$07,$07,$16,$16,$16,$07,$07,
+$07,$07,$07,$07,$00,$24,$16,$07,$07,$07,$07,$13,$24,$24,$08,$16,$23,$07,$32,$07,$07,$16,$07,$07,$07,$07,$07,$07,
+$07,$07,$32,$23,$16,$07,$16,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$24,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,
+$16,$07,$07,$07,$07,$16,$07,$24,$07,$24,$07,$08,$23,$07,$07,$07,$07,$07,$06,$07,$07,$24,$16,$07,$24,$07,$07,$07,
+$07,$07,$07,$07,$07,$07,$16,$07,$07,$07,$07,$16,$32,$16,$07,$07,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+$07,$05,$00,$00,$00,$00,$00,$00,$08,$08,$08,$08,$08,$08,$08,$08,$07,$08,$08,$08,$08,$08,$08,$08,$07,$07,$07,$07,
+$08,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$16,$07,$08,$07,$07,$07,$08,$08,$07,$08,$07,$07,$08,$08,
+$07,$16,$07,$16,$08,$07,$07,$16,$07,$07,$07,$16,$07,$07,$07,$07,$07,$07,$16,$07,$08,$07,$07,$07,$07,$08,$08,$07,
+$07,$16,$08,$07);
+
+const kgiWFont8: array[0..256*8-1] of Byte = (
+ $00,$00,$00,$00,$00,$00,$00,$00,$7e,$81,$a5,$81,$bd,$99,$81,$7e,$7e,$ff,$db,$ff,$c3,$e7,$ff,$7e,$6c,$fe,$fe,$fe,
+ $7c,$38,$10,$00,$10,$38,$7c,$fe,$7c,$38,$10,$00,$10,$7c,$10,$fe,$fe,$92,$10,$7c,$00,$10,$38,$7c,$fe,$7c,$10,$7c,
+ $00,$00,$18,$3c,$3c,$18,$00,$00,$ff,$ff,$e7,$c3,$c3,$e7,$ff,$ff,$00,$3c,$66,$42,$42,$66,$3c,$00,$ff,$c3,$99,$bd,
+ $bd,$99,$c3,$ff,$0f,$03,$05,$79,$cc,$cc,$cc,$78,$3c,$66,$66,$66,$3c,$18,$7e,$18,$3e,$30,$3e,$30,$30,$70,$f0,$e0,
+ $7f,$63,$7f,$63,$63,$67,$e6,$c0,$89,$4a,$3c,$e4,$27,$3c,$52,$91,$80,$e0,$f8,$fe,$f8,$e0,$80,$00,$02,$0e,$3e,$fe,
+ $3e,$0e,$02,$00,$18,$3c,$7e,$18,$18,$7e,$3c,$18,$24,$24,$24,$24,$24,$00,$24,$00,$7f,$db,$db,$7b,$1b,$1b,$1b,$00,
+ $3e,$63,$38,$6c,$6c,$38,$86,$fc,$00,$00,$00,$00,$7e,$7e,$7e,$00,$18,$3c,$7e,$18,$7e,$3c,$18,$ff,$18,$3c,$7e,$18,
+ $18,$18,$18,$00,$18,$18,$18,$18,$7e,$3c,$18,$00,$00,$18,$0c,$fe,$0c,$18,$00,$00,$00,$30,$60,$fe,$60,$30,$00,$00,
+ $00,$00,$00,$c0,$c0,$fe,$00,$00,$00,$24,$66,$ff,$66,$24,$00,$00,$00,$18,$3c,$7e,$ff,$ff,$00,$00,$00,$ff,$ff,$7e,
+ $3c,$18,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$18,$3c,$3c,$18,$18,$00,$18,$00,$6c,$6c,$28,$00,$00,$00,$00,$00,
+ $6c,$6c,$fe,$6c,$fe,$6c,$6c,$00,$18,$7e,$c0,$7c,$06,$fc,$18,$00,$00,$c6,$cc,$18,$30,$66,$c6,$00,$38,$6c,$38,$76,
+ $dc,$cc,$76,$00,$30,$30,$60,$00,$00,$00,$00,$00,$18,$30,$60,$60,$60,$30,$18,$00,$60,$30,$18,$18,$18,$30,$60,$00,
+ $00,$66,$3c,$ff,$3c,$66,$00,$00,$00,$18,$18,$7e,$18,$18,$00,$00,$00,$00,$00,$00,$00,$18,$18,$30,$00,$00,$00,$7e,
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$18,$18,$00,$06,$0c,$18,$30,$60,$c0,$80,$00,$7c,$ce,$de,$f6,$e6,$c6,$7c,$00,
+ $30,$70,$30,$30,$30,$30,$fc,$00,$78,$cc,$0c,$38,$60,$cc,$fc,$00,$78,$cc,$0c,$38,$0c,$cc,$78,$00,$1c,$3c,$6c,$cc,
+ $fe,$0c,$1e,$00,$fc,$c0,$f8,$0c,$0c,$cc,$78,$00,$38,$60,$c0,$f8,$cc,$cc,$78,$00,$fc,$cc,$0c,$18,$30,$30,$30,$00,
+ $78,$cc,$cc,$78,$cc,$cc,$78,$00,$78,$cc,$cc,$7c,$0c,$18,$70,$00,$00,$18,$18,$00,$00,$18,$18,$00,$00,$18,$18,$00,
+ $00,$18,$18,$30,$18,$30,$60,$c0,$60,$30,$18,$00,$00,$00,$7e,$00,$7e,$00,$00,$00,$60,$30,$18,$0c,$18,$30,$60,$00,
+ $3c,$66,$0c,$18,$18,$00,$18,$00,$7c,$c6,$de,$de,$dc,$c0,$7c,$00,$30,$78,$cc,$cc,$fc,$cc,$cc,$00,$fc,$66,$66,$7c,
+ $66,$66,$fc,$00,$3c,$66,$c0,$c0,$c0,$66,$3c,$00,$f8,$6c,$66,$66,$66,$6c,$f8,$00,$fe,$62,$68,$78,$68,$62,$fe,$00,
+ $fe,$62,$68,$78,$68,$60,$f0,$00,$3c,$66,$c0,$c0,$ce,$66,$3a,$00,$cc,$cc,$cc,$fc,$cc,$cc,$cc,$00,$78,$30,$30,$30,
+ $30,$30,$78,$00,$1e,$0c,$0c,$0c,$cc,$cc,$78,$00,$e6,$66,$6c,$78,$6c,$66,$e6,$00,$f0,$60,$60,$60,$62,$66,$fe,$00,
+ $c6,$ee,$fe,$fe,$d6,$c6,$c6,$00,$c6,$e6,$f6,$de,$ce,$c6,$c6,$00,$38,$6c,$c6,$c6,$c6,$6c,$38,$00,$fc,$66,$66,$7c,
+ $60,$60,$f0,$00,$7c,$c6,$c6,$c6,$d6,$7c,$0e,$00,$fc,$66,$66,$7c,$6c,$66,$e6,$00,$7c,$c6,$e0,$78,$0e,$c6,$7c,$00,
+ $fc,$b4,$30,$30,$30,$30,$78,$00,$cc,$cc,$cc,$cc,$cc,$cc,$fc,$00,$cc,$cc,$cc,$cc,$cc,$78,$30,$00,$c6,$c6,$c6,$c6,
+ $d6,$fe,$6c,$00,$c6,$c6,$6c,$38,$6c,$c6,$c6,$00,$cc,$cc,$cc,$78,$30,$30,$78,$00,$fe,$c6,$8c,$18,$32,$66,$fe,$00,
+ $78,$60,$60,$60,$60,$60,$78,$00,$c0,$60,$30,$18,$0c,$06,$02,$00,$78,$18,$18,$18,$18,$18,$78,$00,$10,$38,$6c,$c6,
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$ff,$30,$30,$18,$00,$00,$00,$00,$00,$00,$00,$78,$0c,$7c,$cc,$76,$00,
+ $e0,$60,$60,$7c,$66,$66,$dc,$00,$00,$00,$78,$cc,$c0,$cc,$78,$00,$1c,$0c,$0c,$7c,$cc,$cc,$76,$00,$00,$00,$78,$cc,
+ $fc,$c0,$78,$00,$38,$6c,$64,$f0,$60,$60,$f0,$00,$00,$00,$76,$cc,$cc,$7c,$0c,$f8,$e0,$60,$6c,$76,$66,$66,$e6,$00,
+ $30,$00,$70,$30,$30,$30,$78,$00,$0c,$00,$1c,$0c,$0c,$cc,$cc,$78,$e0,$60,$66,$6c,$78,$6c,$e6,$00,$70,$30,$30,$30,
+ $30,$30,$78,$00,$00,$00,$cc,$fe,$fe,$d6,$d6,$00,$00,$00,$b8,$cc,$cc,$cc,$cc,$00,$00,$00,$78,$cc,$cc,$cc,$78,$00,
+ $00,$00,$dc,$66,$66,$7c,$60,$f0,$00,$00,$76,$cc,$cc,$7c,$0c,$1e,$00,$00,$dc,$76,$62,$60,$f0,$00,$00,$00,$7c,$c0,
+ $70,$1c,$f8,$00,$10,$30,$fc,$30,$30,$34,$18,$00,$00,$00,$cc,$cc,$cc,$cc,$76,$00,$00,$00,$cc,$cc,$cc,$78,$30,$00,
+ $00,$00,$c6,$c6,$d6,$fe,$6c,$00,$00,$00,$c6,$6c,$38,$6c,$c6,$00,$00,$00,$cc,$cc,$cc,$7c,$0c,$f8,$00,$00,$fc,$98,
+ $30,$64,$fc,$00,$1c,$30,$30,$e0,$30,$30,$1c,$00,$18,$18,$18,$00,$18,$18,$18,$00,$e0,$30,$30,$1c,$30,$30,$e0,$00,
+ $76,$dc,$00,$00,$00,$00,$00,$00,$00,$10,$38,$6c,$c6,$c6,$fe,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+ $48,$00,$fc,$c0,$c0,$f8,$c0,$fe,$a0,$d0,$90,$90,$90,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+ $00,$00,$00,$00,$00,$00,$00,$00,$22,$88,$22,$88,$22,$88,$22,$88,$55,$aa,$55,$aa,$55,$aa,$55,$aa,$ff,$ab,$d5,$ab,
+ $d5,$ab,$d5,$ff,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$f0,$10,$10,$10,$10,$10,$f0,$10,$f0,$10,$10,$10,
+ $14,$14,$14,$14,$f4,$14,$14,$14,$00,$00,$00,$00,$fc,$14,$14,$14,$48,$00,$78,$cc,$fc,$c0,$7c,$00,$14,$14,$f4,$04,
+ $f4,$14,$14,$14,$14,$14,$14,$14,$14,$14,$14,$14,$00,$00,$fc,$04,$f4,$14,$14,$14,$14,$14,$f4,$04,$fc,$00,$00,$00,
+ $14,$14,$14,$14,$fc,$00,$00,$00,$10,$10,$f0,$10,$f0,$00,$00,$00,$00,$00,$00,$00,$f0,$10,$10,$10,$0e,$1e,$36,$66,
+ $fe,$c6,$c6,$00,$fc,$c0,$c0,$fc,$c6,$c6,$fc,$00,$f8,$cc,$cc,$fc,$c6,$c6,$fc,$00,$fc,$c0,$c0,$c0,$c0,$c0,$c0,$00,
+ $7e,$66,$66,$66,$66,$66,$ff,$c3,$fc,$c0,$c0,$f8,$c0,$c0,$fe,$00,$db,$db,$7e,$18,$7e,$db,$db,$00,$3c,$66,$06,$3c,
+ $06,$c6,$7c,$00,$c6,$c6,$ce,$de,$f6,$e6,$c6,$00,$d6,$c6,$ce,$de,$f6,$e6,$c6,$00,$c6,$cc,$d8,$f8,$cc,$c6,$c6,$00,
+ $06,$0e,$1e,$36,$66,$c6,$c6,$00,$c6,$ee,$fe,$d6,$c6,$c6,$c6,$00,$c6,$c6,$c6,$fe,$c6,$c6,$c6,$00,$7c,$c6,$c6,$c6,
+ $c6,$c6,$7c,$00,$fe,$c6,$c6,$c6,$c6,$c6,$c6,$00,$fc,$c6,$c6,$fc,$c0,$c0,$c0,$00,$7c,$c6,$c0,$c0,$c0,$c6,$7c,$00,
+ $fc,$30,$30,$30,$30,$30,$30,$00,$c6,$c6,$c6,$7e,$06,$c6,$7c,$00,$18,$7e,$db,$db,$db,$7e,$18,$00,$c3,$66,$3c,$18,
+ $3c,$66,$c3,$00,$cc,$cc,$cc,$cc,$cc,$cc,$fe,$06,$c6,$c6,$c6,$7e,$06,$06,$06,$00,$d6,$d6,$d6,$d6,$d6,$d6,$fe,$00,
+ $d6,$d6,$d6,$d6,$d6,$d6,$ff,$03,$f0,$30,$30,$3e,$33,$33,$3e,$00,$c2,$c2,$c2,$f2,$da,$da,$f2,$00,$c0,$c0,$c0,$fc,
+ $c6,$c6,$fc,$00,$7c,$c6,$06,$1e,$06,$c6,$7c,$00,$ce,$db,$db,$fb,$db,$db,$ce,$00,$7e,$c6,$c6,$7e,$36,$66,$c6,$00,
+ $00,$00,$78,$0c,$7c,$cc,$7e,$00,$04,$78,$c0,$f8,$cc,$cc,$78,$00,$00,$00,$f8,$cc,$f8,$c6,$fc,$00,$00,$00,$fc,$c0,
+ $c0,$c0,$c0,$00,$00,$00,$7e,$66,$66,$66,$ff,$c3,$00,$00,$78,$cc,$fc,$c0,$7c,$00,$00,$00,$db,$7e,$18,$7e,$db,$00,
+ $00,$00,$78,$cc,$18,$cc,$78,$00,$00,$00,$cc,$cc,$dc,$ec,$cc,$00,$30,$00,$cc,$cc,$dc,$ec,$cc,$00,$00,$00,$cc,$d8,
+ $f0,$cc,$cc,$00,$00,$00,$0e,$1e,$36,$66,$c6,$00,$00,$00,$c6,$ee,$d6,$c6,$c6,$00,$00,$00,$cc,$cc,$fc,$cc,$cc,$00,
+ $00,$00,$78,$cc,$cc,$cc,$78,$00,$00,$00,$fc,$cc,$cc,$cc,$cc,$00,$00,$00,$f8,$cc,$cc,$f8,$c0,$c0,$00,$00,$78,$cc,
+ $c0,$cc,$78,$00,$00,$00,$fc,$30,$30,$30,$30,$00,$00,$00,$cc,$cc,$7c,$0c,$cc,$78,$00,$18,$7e,$db,$db,$7e,$18,$18,
+ $00,$00,$c6,$6c,$38,$6c,$c6,$00,$00,$00,$cc,$cc,$cc,$cc,$fe,$06,$00,$00,$cc,$cc,$7c,$0c,$0c,$00,$00,$00,$d6,$d6,
+ $d6,$d6,$fe,$00,$00,$00,$d6,$d6,$d6,$d6,$ff,$03,$00,$00,$f0,$30,$3e,$33,$3e,$00,$00,$00,$c2,$c2,$f2,$da,$f2,$00,
+ $00,$00,$c0,$c0,$f8,$cc,$f8,$00,$00,$00,$7c,$c6,$1e,$c6,$7c,$00,$00,$00,$ce,$db,$fb,$db,$ce,$00,$00,$00,$7c,$cc,
+ $7c,$6c,$cc,$00);
+const kgiWFont8Wdt: array[0..256-1] of Byte = (
+ $00,$08,$08,$07,$07,$07,$07,$24,$08,$16,$08,$08,$16,$07,$08,$08,$07,$07,$16,$24,$08,$08,$16,$08,$16,$16,$07,$07,
+ $07,$08,$08,$08,$00,$24,$15,$07,$07,$07,$07,$13,$14,$14,$08,$16,$23,$16,$32,$07,$07,$06,$06,$06,$07,$06,$06,$06,
+ $06,$06,$32,$23,$05,$16,$15,$16,$07,$06,$07,$07,$07,$07,$07,$07,$06,$14,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,
+ $06,$06,$06,$07,$07,$06,$07,$14,$07,$14,$07,$08,$23,$07,$07,$06,$07,$06,$06,$07,$07,$14,$06,$07,$14,$07,$06,$06,
+ $07,$07,$07,$06,$06,$07,$06,$07,$07,$06,$06,$06,$32,$06,$07,$07,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
+ $07,$04,$00,$00,$00,$00,$00,$00,$08,$08,$08,$08,$08,$08,$08,$08,$06,$08,$08,$08,$08,$08,$08,$08,$07,$07,$07,$06,
+ $08,$07,$08,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$06,$07,$08,$08,$07,$07,$07,$08,$08,$07,$07,$07,$08,$07,
+ $07,$06,$07,$06,$08,$06,$08,$06,$06,$06,$06,$07,$07,$06,$06,$06,$06,$06,$06,$06,$08,$07,$07,$06,$07,$08,$08,$07,
+ $06,$07,$08,$06);
+
+
+function createFontTexture (const font: PByte; const fontwdt: PByte; hgt: Integer; prop: Boolean): GLuint;
const
Width = 16*8;
- Height = 16*8;
+ Height = 16*16;
var
tex, tpp: PByte;
b: Byte;
x, y, dx, dy: Integer;
begin
GetMem(tex, Width*Height*4);
+ FillChar(tex^, Width*Height*4, 0);
for cc := 0 to 255 do
begin
x := (cc mod 16)*8;
- y := (cc div 16)*8;
- for dy := 0 to 7 do
+ y := (cc div 16)*16;
+ for dy := 0 to hgt-1 do
begin
- b := font[cc*8+dy];
+ b := font[cc*hgt+dy];
if prop then b := b shl (fontwdt[cc] shr 4);
tpp := tex+((y+dy)*(Width*4))+x*4;
for dx := 0 to 7 do