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>
<Folder name="dlangui">
<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">
<File path="3rdparty\win32\basetsd.d" />
<File path="3rdparty\win32\basetyps.d" />

View File

@ -4,7 +4,7 @@ public import dlangui.core.types;
public import dlangui.core.logger;
import std.algorithm;
public enum FontFamily : int {
enum FontFamily : int {
SansSerif,
Serif,
Fantasy,
@ -12,25 +12,25 @@ public enum FontFamily : int {
MonoSpace
}
public struct Glyph
struct Glyph
{
public ubyte blackBoxX; ///< 0: width of glyph
public ubyte blackBoxY; ///< 1: height of glyph black box
public byte originX; ///< 2: X origin for glyph
public byte originY; ///< 3: Y origin for glyph
public ushort glyphIndex; ///< 4: bytes in glyph array
public ubyte width; ///< 6: full width of glyph
public ubyte lastUsage;
public ubyte[] glyph; ///< 7: glyph data, arbitrary size
ubyte blackBoxX; ///< 0: width of glyph
ubyte blackBoxY; ///< 1: height of glyph black box
byte originX; ///< 2: X origin for glyph
byte originY; ///< 3: Y origin for glyph
ushort glyphIndex; ///< 4: bytes in glyph array
ubyte width; ///< 6: full width of glyph
ubyte lastUsage;
ubyte[] glyph; ///< 7: glyph data, arbitrary size
}
public struct GlyphCache
struct GlyphCache
{
Glyph[] _data;
uint _len;
// find glyph in cache
public Glyph * find(ushort glyphIndex) {
Glyph * find(ushort glyphIndex) {
for (uint i = 0; i < _len; i++) {
Glyph * item = &_data[i];
if (item.glyphIndex == glyphIndex) {
@ -41,7 +41,7 @@ public struct GlyphCache
return null;
}
public Glyph * put(ushort glyphIndex, Glyph * glyph) {
Glyph * put(ushort glyphIndex, Glyph * glyph) {
if (_len >= _data.length) {
uint newsize = (_len < 32) ? 32 : _len * 2;
_data.length = newsize;
@ -53,14 +53,14 @@ public struct GlyphCache
}
// clear usage flags for all entries
public void checkpoint() {
void checkpoint() {
for (uint src = 0; src < _len; src++) {
_data[src].lastUsage = 0;
}
}
// removes entries not used after last call of checkpoint() or cleanup()
public void cleanup() {
void cleanup() {
uint dst = 0;
for (uint src = 0; src < _len; src++) {
if (_data[src].lastUsage != 0) {
@ -74,49 +74,56 @@ public struct GlyphCache
}
// removes all entries
public void clear() {
void clear() {
_data = null;
_len = 0;
}
public ~this() {
~this() {
clear();
}
}
public class Font : RefCountedObject {
abstract public @property int size();
abstract public @property int height();
abstract public @property int weight();
abstract public @property int baseline();
abstract public @property bool italic();
abstract public @property string face();
abstract public @property FontFamily family();
abstract public @property bool isNull();
class Font : RefCountedObject {
abstract @property int size();
abstract @property int height();
abstract @property int weight();
abstract @property int baseline();
abstract @property bool italic();
abstract @property string face();
abstract @property FontFamily family();
abstract @property bool isNull();
// 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
abstract public void drawText(DrawBuf buf, int x, int y, const dchar[] text, uint color);
abstract public Glyph * getCharGlyph(dchar ch);
public void clear() {}
public ~this() { clear(); }
abstract void drawText(DrawBuf buf, int x, int y, const dchar[] text, uint color);
abstract Glyph * getCharGlyph(dchar ch);
// 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;
public struct FontList {
struct FontList {
FontRef[] _list;
uint _len;
public ~this() {
~this() {
for (uint i = 0; i < _len; i++) {
_list[i].clear();
}
}
// returns item by index
public ref FontRef get(int index) {
ref FontRef get(int index) {
return _list[index];
}
// returns index of found item, -1 if not found
public int find(int size, int weight, bool italic, FontFamily family, string face) {
for (int i = 0; i < _list.length; i++) {
int find(int size, int weight, bool italic, FontFamily family, string face) {
for (int i = 0; i < _len; i++) {
Font item = _list[i].get;
if (item.family != family)
continue;
@ -130,7 +137,7 @@ public struct FontList {
}
return -1;
}
public ref FontRef add(Font item) {
ref FontRef add(Font item) {
Log.d("FontList.add() enter");
if (_len >= _list.length) {
_list.length = _len < 16 ? 16 : _list.length * 2;
@ -139,16 +146,43 @@ public struct FontList {
Log.d("FontList.add() exit");
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;
public static @property void instance(FontManager manager) {
static @property void instance(FontManager manager) {
_instance = manager;
}
public static @property FontManager instance() {
static @property FontManager 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;
version (Windows) {
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;
int _size;
int _height;
@ -44,12 +46,16 @@ class Win32Font : Font {
Win32ColorDrawBuf _drawbuf;
GlyphCache _glyphCache;
/// need to call create() after construction to initialize font
public this() {
}
/// do cleanup
public ~this() {
Log.d("Deleting font");
clear();
}
/// cleanup resources
public override void clear() {
if (_hfont !is null)
{
@ -262,6 +268,17 @@ class Win32Font : Font {
Log.d("Created font ", _face, " ", _size);
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 height() { return _height; }
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 {
FontList _activeFonts;
FontDef[] _fontFaces;
FontDef*[string] _faceByName;
/// initialize in constructor
public this() {
instance = this;
init();
}
/// initialize font manager by enumerating of system fonts
public bool init() {
Log.i("Win32FontManager.init()");
Win32ColorDrawBuf drawbuf = new Win32ColorDrawBuf(1,1);
@ -301,7 +324,11 @@ class Win32FontManager : FontManager {
Log.i("Found ", _fontFaces.length, " font faces");
return res!=0;
}
/// for returning of not found font
FontRef _emptyFontRef;
/// get font by properties
public override ref FontRef getFont(int size, int weight, bool italic, FontFamily family, string face) {
Log.i("getFont()");
FontDef * def = findFace(family, face);
@ -319,6 +346,8 @@ class Win32FontManager : FontManager {
return _emptyFontRef;
}
}
/// find font face definition by family only (try to get one of defaults for family if possible)
FontDef * findFace(FontFamily family) {
FontDef * res = null;
switch(family) {
@ -351,6 +380,8 @@ class Win32FontManager : FontManager {
}
return null;
}
/// find font face definition by face only
FontDef * findFace(string face) {
if (face.length == 0)
return null;
@ -358,6 +389,8 @@ class Win32FontManager : FontManager {
return _faceByName[face];
return null;
}
/// find font face definition by family and face
public FontDef * findFace(FontFamily family, string face) {
// by face only
FontDef * res = findFace(face);
@ -377,12 +410,25 @@ class Win32FontManager : FontManager {
return res;
return &_fontFaces[0];
}
/// register enumerated font
public bool registerFont(FontFamily family, string fontFace, ubyte pitchAndFamily) {
Log.d("registerFont(", family, ",", fontFace, ")");
_fontFaces ~= FontDef(family, fontFace, pitchAndFamily);
_faceByName[fontFace] = &_fontFaces[$ - 1];
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) {