ref counting

This commit is contained in:
Vadim Lopatin 2014-03-03 18:40:27 +04:00
parent 0fa02cbcb5
commit 5c77ebb3f1
4 changed files with 88 additions and 13 deletions

View File

@ -37,3 +37,51 @@ public struct Rect {
return right > left && bottom > top;
}
}
public class RefCountedObject {
protected int _refCount;
public @property int refCount() { return _refCount; }
public void addRef() { _refCount++; }
public void releaseRef() { if (--_refCount == 0) destroy(this); }
public ~this() {}
}
public struct Ref(T) { // if (T is RefCountedObject)
T _data;
alias _data this;
public @property bool isNull() { return _data is null; }
public @property int refCount() { return _data !is null ? _data.refCount : 0; }
public this(T data) {
_data = data;
if (_data !is null)
_data.addRef();
}
public void opAssign(Ref!T data) {
if (data._data == _data)
return;
if (_data !is null)
_data.releaseRef();
_data = data._data;
if (_data !is null)
_data.addRef();
}
public void opAssign(T data) {
if (data == _data)
return;
if (_data !is null)
_data.releaseRef();
_data = data;
if (_data !is null)
_data.addRef();
}
public void clear() {
if (_data !is null) {
_data.releaseRef();
_data = null;
}
}
public ~this() {
if (_data !is null)
_data.releaseRef();
}
}

View File

@ -16,7 +16,7 @@ public uint blendARGB(uint dst, uint src, uint alpha) {
return (r << 16) | (g << 8) | b;
}
class DrawBuf {
class DrawBuf : RefCountedObject {
protected Rect _clipRect;
public @property int width() { return 0; }
public @property int height() { return 0; }
@ -42,11 +42,13 @@ class DrawBuf {
public void afterDrawing() { }
public uint * scanLine(int y) { return null; }
abstract public void resize(int width, int height);
abstract public void clear(uint color);
abstract public void fill(uint color);
public void fillRect(int left, int top, int right, int bottom, uint color) {
fillRect(Rect(left, top, right, bottom), color);
}
abstract public void fillRect(Rect rc, uint color);
public void clear() {}
public ~this() { clear(); }
}
class ColorDrawBufBase : DrawBuf {
@ -92,7 +94,7 @@ class ColorDrawBuf : ColorDrawBufBase {
_dy = height;
_buf.length = _dx * _dy;
}
public override void clear(uint color) {
public override void fill(uint color) {
int len = _dx * _dy;
uint * p = _buf.ptr;
for (int i = 0; i < len; i++)

View File

@ -1,4 +1,5 @@
module dlangui.graphics.fonts;
import dlangui.core.types;
enum FontFamily : int {
SansSerif,
@ -6,7 +7,7 @@ enum FontFamily : int {
MonoSpace
}
class Font {
class Font : RefCountedObject {
abstract public @property int size();
abstract public @property int height();
abstract public @property int weight();
@ -15,7 +16,10 @@ class Font {
abstract public @property string face();
abstract public @property FontFamily family();
abstract public @property bool isNull();
public void clear() {}
public ~this() { clear(); }
}
alias FontRef = Ref!Font;
class FontManager {
static __gshared FontManager _instance;
@ -26,4 +30,5 @@ class FontManager {
return _instance;
}
abstract public Font getFont(int size, int weight, bool italic, FontFamily family, string face);
public ~this() {}
}

View File

@ -15,6 +15,11 @@ import dlangui.graphics.fonts;
pragma(lib, "gdi32.lib");
pragma(lib, "user32.lib");
struct FontDef {
string _face;
FontFamily _family;
}
class Win32Font : Font {
HFONT _hfont;
int _size;
@ -29,7 +34,7 @@ class Win32Font : Font {
public this() {
_drawbuf = new Win32ColorDrawBuf(1, 1);
}
public void clear() {
public override void clear() {
if (_hfont !is null)
{
DeleteObject(_hfont);
@ -69,11 +74,21 @@ class Win32Font : Font {
SelectObject(_drawbuf.dc, _hfont);
TEXTMETRICW tm;
GetTextMetricsW(_drawbuf.dc, &tm);
_family = FontFamily.SansSerif;
ubyte pitchAndFamily = _logfont.lfPitchAndFamily;
if ((pitchAndFamily & (FIXED_PITCH | MONO_FONT | FF_MODERN)) != 0)
_family = FontFamily.MonoSpace;
else if ((pitchAndFamily & (FF_ROMAN | FF_SCRIPT)) != 0)
_family = FontFamily.Serif;
_logfont.lfHeight = tm.tmHeight;
_logfont.lfWeight = tm.tmWeight;
_logfont.lfItalic = tm.tmItalic;
_logfont.lfCharSet = tm.tmCharSet;
GetTextFaceA(_drawbuf.dc, _logfont.lfFaceName.length - 1, _logfont.lfFaceName.ptr);
int i = 0;
for (;_logfont.lfFaceName[i]; i++) {
}
_face = _logfont.lfFaceName[0..i].dup;
_height = tm.tmHeight;
_baseline = _height - tm.tmDescent;
return true;
@ -139,7 +154,7 @@ class Win32FontManager : FontManager {
//if (!fnt.getGlyphInfo( chars[i], &glyph, L' ' )) //def_char
// return 1;
}
fontman.registerFont(lf); //&lpelfe->elfLogFont
fontman.registerFont(lf);
}
fnt.clear();
}
@ -301,6 +316,15 @@ class Win32ColorDrawBuf : ColorDrawBufBase {
return _pixels + _dx * (_dy - 1 - y);
return null;
}
public override void clear() {
if (_drawbmp !is null) {
DeleteObject( _drawbmp );
DeleteObject( _drawdc );
_pixels = null;
_dx = 0;
_dy = 0;
}
}
public override void resize(int width, int height) {
if (width< 0)
width = 0;
@ -308,13 +332,9 @@ class Win32ColorDrawBuf : ColorDrawBufBase {
height = 0;
if (_dx == width && _dy == height)
return;
clear();
_dx = width;
_dy = height;
if (_drawbmp !is null) {
DeleteObject( _drawbmp );
DeleteObject( _drawdc );
_pixels = null;
}
if (_dx > 0 && _dy > 0) {
BITMAPINFO bmi;
//memset( &bmi, 0, sizeof(bmi) );
@ -334,7 +354,7 @@ class Win32ColorDrawBuf : ColorDrawBufBase {
SelectObject(_drawdc, _drawbmp);
}
}
public override void clear(uint color) {
public override void fill(uint color) {
int len = _dx * _dy;
for (int i = 0; i < len; i++)
_pixels[i] = color;
@ -412,7 +432,7 @@ LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
hdc = BeginPaint(hwnd, &ps);
Win32ColorDrawBuf buf = window.getDrawBuf();
buf.clear(0x808080);
buf.fill(0x808080);
window.onDraw(buf);
buf.drawTo(hdc, 0, 0);
//drawBuf2DC(hdc, 0, 0, buf);