code cleanup

This commit is contained in:
Vadim Lopatin 2014-03-05 06:48:10 +04:00
parent 99dae613f2
commit 4429bca35c
3 changed files with 131 additions and 46 deletions

View File

@ -190,6 +190,11 @@
</Config> </Config>
<Folder name="dlangui"> <Folder name="dlangui">
<Folder name="3rdparty"> <Folder name="3rdparty">
<Folder name="libpng">
<File path="3rdparty\libpng\source\libpng\png.d" />
<File path="3rdparty\libpng\source\libpng\pngconf.d" />
<File path="3rdparty\libpng\source\libpng\pnglibconf.d" />
</Folder>
<Folder name="win32"> <Folder name="win32">
<File path="3rdparty\win32\basetsd.d" /> <File path="3rdparty\win32\basetsd.d" />
<File path="3rdparty\win32\basetyps.d" /> <File path="3rdparty\win32\basetyps.d" />

View File

@ -4,7 +4,7 @@ public import dlangui.core.types;
public import dlangui.core.logger; public import dlangui.core.logger;
import std.algorithm; import std.algorithm;
public enum FontFamily : int { enum FontFamily : int {
SansSerif, SansSerif,
Serif, Serif,
Fantasy, Fantasy,
@ -12,25 +12,25 @@ public enum FontFamily : int {
MonoSpace MonoSpace
} }
public struct Glyph struct Glyph
{ {
public ubyte blackBoxX; ///< 0: width of glyph ubyte blackBoxX; ///< 0: width of glyph
public ubyte blackBoxY; ///< 1: height of glyph black box ubyte blackBoxY; ///< 1: height of glyph black box
public byte originX; ///< 2: X origin for glyph byte originX; ///< 2: X origin for glyph
public byte originY; ///< 3: Y origin for glyph byte originY; ///< 3: Y origin for glyph
public ushort glyphIndex; ///< 4: bytes in glyph array ushort glyphIndex; ///< 4: bytes in glyph array
public ubyte width; ///< 6: full width of glyph ubyte width; ///< 6: full width of glyph
public ubyte lastUsage; ubyte lastUsage;
public ubyte[] glyph; ///< 7: glyph data, arbitrary size ubyte[] glyph; ///< 7: glyph data, arbitrary size
} }
public struct GlyphCache struct GlyphCache
{ {
Glyph[] _data; Glyph[] _data;
uint _len; uint _len;
// find glyph in cache // find glyph in cache
public Glyph * find(ushort glyphIndex) { Glyph * find(ushort glyphIndex) {
for (uint i = 0; i < _len; i++) { for (uint i = 0; i < _len; i++) {
Glyph * item = &_data[i]; Glyph * item = &_data[i];
if (item.glyphIndex == glyphIndex) { if (item.glyphIndex == glyphIndex) {
@ -41,7 +41,7 @@ public struct GlyphCache
return null; return null;
} }
public Glyph * put(ushort glyphIndex, Glyph * glyph) { Glyph * put(ushort glyphIndex, Glyph * glyph) {
if (_len >= _data.length) { if (_len >= _data.length) {
uint newsize = (_len < 32) ? 32 : _len * 2; uint newsize = (_len < 32) ? 32 : _len * 2;
_data.length = newsize; _data.length = newsize;
@ -53,14 +53,14 @@ public struct GlyphCache
} }
// clear usage flags for all entries // clear usage flags for all entries
public void checkpoint() { void checkpoint() {
for (uint src = 0; src < _len; src++) { for (uint src = 0; src < _len; src++) {
_data[src].lastUsage = 0; _data[src].lastUsage = 0;
} }
} }
// removes entries not used after last call of checkpoint() or cleanup() // removes entries not used after last call of checkpoint() or cleanup()
public void cleanup() { void cleanup() {
uint dst = 0; uint dst = 0;
for (uint src = 0; src < _len; src++) { for (uint src = 0; src < _len; src++) {
if (_data[src].lastUsage != 0) { if (_data[src].lastUsage != 0) {
@ -74,49 +74,56 @@ public struct GlyphCache
} }
// removes all entries // removes all entries
public void clear() { void clear() {
_data = null; _data = null;
_len = 0; _len = 0;
} }
public ~this() { ~this() {
clear(); clear();
} }
} }
public class Font : RefCountedObject { class Font : RefCountedObject {
abstract public @property int size(); abstract @property int size();
abstract public @property int height(); abstract @property int height();
abstract public @property int weight(); abstract @property int weight();
abstract public @property int baseline(); abstract @property int baseline();
abstract public @property bool italic(); abstract @property bool italic();
abstract public @property string face(); abstract @property string face();
abstract public @property FontFamily family(); abstract @property FontFamily family();
abstract public @property bool isNull(); abstract @property bool isNull();
// measure text string, return accumulated widths[] (distance to end of n-th character), returns number of measured chars. // measure text string, return accumulated widths[] (distance to end of n-th character), returns number of measured chars.
abstract public int measureText(const dchar[] text, ref int[] widths, int maxWidth); abstract int measureText(const dchar[] text, ref int[] widths, int maxWidth);
// draw text string to buffer // draw text string to buffer
abstract public void drawText(DrawBuf buf, int x, int y, const dchar[] text, uint color); abstract void drawText(DrawBuf buf, int x, int y, const dchar[] text, uint color);
abstract public Glyph * getCharGlyph(dchar ch); abstract Glyph * getCharGlyph(dchar ch);
public void clear() {}
public ~this() { clear(); } // clear usage flags for all entries
abstract void checkpoint();
// removes entries not used after last call of checkpoint() or cleanup()
abstract void cleanup();
void clear() {}
~this() { clear(); }
} }
alias FontRef = Ref!Font; alias FontRef = Ref!Font;
public struct FontList { struct FontList {
FontRef[] _list; FontRef[] _list;
uint _len; uint _len;
public ~this() { ~this() {
for (uint i = 0; i < _len; i++) { for (uint i = 0; i < _len; i++) {
_list[i].clear(); _list[i].clear();
} }
} }
// returns item by index // returns item by index
public ref FontRef get(int index) { ref FontRef get(int index) {
return _list[index]; return _list[index];
} }
// returns index of found item, -1 if not found // returns index of found item, -1 if not found
public int find(int size, int weight, bool italic, FontFamily family, string face) { int find(int size, int weight, bool italic, FontFamily family, string face) {
for (int i = 0; i < _list.length; i++) { for (int i = 0; i < _len; i++) {
Font item = _list[i].get; Font item = _list[i].get;
if (item.family != family) if (item.family != family)
continue; continue;
@ -130,7 +137,7 @@ public struct FontList {
} }
return -1; return -1;
} }
public ref FontRef add(Font item) { ref FontRef add(Font item) {
Log.d("FontList.add() enter"); Log.d("FontList.add() enter");
if (_len >= _list.length) { if (_len >= _list.length) {
_list.length = _len < 16 ? 16 : _list.length * 2; _list.length = _len < 16 ? 16 : _list.length * 2;
@ -139,16 +146,43 @@ public struct FontList {
Log.d("FontList.add() exit"); Log.d("FontList.add() exit");
return _list[_len - 1]; return _list[_len - 1];
} }
// remove unused items - with reference == 1
void cleanup() {
for (int i = 0; i < _len; i++)
if (_list[i].refCount <= 1)
_list[i].clear();
int dst = 0;
for (int i = 0; i < _len; i++) {
if (!_list[i].isNull)
if (i != dst)
_list[dst++] = _list[i];
}
_len = dst;
for (int i = 0; i < _len; i++)
_list[i].cleanup();
}
void checkpoint() {
for (int i = 0; i < _len; i++)
_list[i].checkpoint();
}
} }
public class FontManager { class FontManager {
static __gshared FontManager _instance; static __gshared FontManager _instance;
public static @property void instance(FontManager manager) { static @property void instance(FontManager manager) {
_instance = manager; _instance = manager;
} }
public static @property FontManager instance() { static @property FontManager instance() {
return _instance; return _instance;
} }
abstract public ref FontRef getFont(int size, int weight, bool italic, FontFamily family, string face);
public ~this() {} abstract ref FontRef getFont(int size, int weight, bool italic, FontFamily family, string face);
// clear usage flags for all entries
abstract void checkpoint();
// removes entries not used after last call of checkpoint() or cleanup()
abstract void cleanup();
~this() {}
} }

View File

@ -1,6 +1,5 @@
module dlangui.platforms.windows.winapp; module dlangui.platforms.windows.winapp;
version (Windows) { version (Windows) {
import core.runtime; import core.runtime;
@ -31,7 +30,10 @@ struct FontDef {
} }
} }
class Win32Font : Font { /**
* Font implementation based on Win32 API system fonts.
*/
public class Win32Font : Font {
HFONT _hfont; HFONT _hfont;
int _size; int _size;
int _height; int _height;
@ -44,12 +46,16 @@ class Win32Font : Font {
Win32ColorDrawBuf _drawbuf; Win32ColorDrawBuf _drawbuf;
GlyphCache _glyphCache; GlyphCache _glyphCache;
/// need to call create() after construction to initialize font
public this() { public this() {
} }
/// do cleanup
public ~this() { public ~this() {
Log.d("Deleting font");
clear(); clear();
} }
/// cleanup resources
public override void clear() { public override void clear() {
if (_hfont !is null) if (_hfont !is null)
{ {
@ -262,6 +268,17 @@ class Win32Font : Font {
Log.d("Created font ", _face, " ", _size); Log.d("Created font ", _face, " ", _size);
return true; return true;
} }
// clear usage flags for all entries
override void checkpoint() {
_glyphCache.checkpoint();
}
// removes entries not used after last call of checkpoint() or cleanup()
override void cleanup() {
_glyphCache.cleanup();
}
public @property override int size() { return _size; } public @property override int size() { return _size; }
public @property override int height() { return _height; } public @property override int height() { return _height; }
public @property override int weight() { return _weight; } public @property override int weight() { return _weight; }
@ -273,15 +290,21 @@ class Win32Font : Font {
} }
/**
* Font manager implementation based on Win32 API system fonts.
*/
class Win32FontManager : FontManager { class Win32FontManager : FontManager {
FontList _activeFonts; FontList _activeFonts;
FontDef[] _fontFaces; FontDef[] _fontFaces;
FontDef*[string] _faceByName; FontDef*[string] _faceByName;
/// initialize in constructor
public this() { public this() {
instance = this; instance = this;
init(); init();
} }
/// initialize font manager by enumerating of system fonts
public bool init() { public bool init() {
Log.i("Win32FontManager.init()"); Log.i("Win32FontManager.init()");
Win32ColorDrawBuf drawbuf = new Win32ColorDrawBuf(1,1); Win32ColorDrawBuf drawbuf = new Win32ColorDrawBuf(1,1);
@ -301,7 +324,11 @@ class Win32FontManager : FontManager {
Log.i("Found ", _fontFaces.length, " font faces"); Log.i("Found ", _fontFaces.length, " font faces");
return res!=0; return res!=0;
} }
/// for returning of not found font
FontRef _emptyFontRef; FontRef _emptyFontRef;
/// get font by properties
public override ref FontRef getFont(int size, int weight, bool italic, FontFamily family, string face) { public override ref FontRef getFont(int size, int weight, bool italic, FontFamily family, string face) {
Log.i("getFont()"); Log.i("getFont()");
FontDef * def = findFace(family, face); FontDef * def = findFace(family, face);
@ -319,6 +346,8 @@ class Win32FontManager : FontManager {
return _emptyFontRef; return _emptyFontRef;
} }
} }
/// find font face definition by family only (try to get one of defaults for family if possible)
FontDef * findFace(FontFamily family) { FontDef * findFace(FontFamily family) {
FontDef * res = null; FontDef * res = null;
switch(family) { switch(family) {
@ -351,6 +380,8 @@ class Win32FontManager : FontManager {
} }
return null; return null;
} }
/// find font face definition by face only
FontDef * findFace(string face) { FontDef * findFace(string face) {
if (face.length == 0) if (face.length == 0)
return null; return null;
@ -358,6 +389,8 @@ class Win32FontManager : FontManager {
return _faceByName[face]; return _faceByName[face];
return null; return null;
} }
/// find font face definition by family and face
public FontDef * findFace(FontFamily family, string face) { public FontDef * findFace(FontFamily family, string face) {
// by face only // by face only
FontDef * res = findFace(face); FontDef * res = findFace(face);
@ -377,12 +410,25 @@ class Win32FontManager : FontManager {
return res; return res;
return &_fontFaces[0]; return &_fontFaces[0];
} }
/// register enumerated font
public bool registerFont(FontFamily family, string fontFace, ubyte pitchAndFamily) { public bool registerFont(FontFamily family, string fontFace, ubyte pitchAndFamily) {
Log.d("registerFont(", family, ",", fontFace, ")"); Log.d("registerFont(", family, ",", fontFace, ")");
_fontFaces ~= FontDef(family, fontFace, pitchAndFamily); _fontFaces ~= FontDef(family, fontFace, pitchAndFamily);
_faceByName[fontFace] = &_fontFaces[$ - 1]; _faceByName[fontFace] = &_fontFaces[$ - 1];
return true; return true;
} }
/// clear usage flags for all entries
public override void checkpoint() {
_activeFonts.checkpoint();
}
/// removes entries not used after last call of checkpoint() or cleanup()
public override void cleanup() {
_activeFonts.cleanup();
//_list.cleanup();
}
} }
string fromStringz(const(char[]) s) { string fromStringz(const(char[]) s) {