fix win32 font drawing

This commit is contained in:
Vadim Lopatin 2014-03-25 12:36:33 +04:00
parent 7eaf08aec3
commit 4187da1a2d
4 changed files with 80 additions and 39 deletions
src/dlangui
graphics
platforms/windows

View File

@ -226,8 +226,10 @@ class FontManager {
static __gshared FontManager _instance; static __gshared FontManager _instance;
/// sets new font manager singleton instance /// sets new font manager singleton instance
static @property void instance(FontManager manager) { static @property void instance(FontManager manager) {
if (_instance !is null) if (_instance !is null) {
destroy(_instance); destroy(_instance);
_instance = null;
}
_instance = manager; _instance = manager;
} }
/// returns font manager singleton instance /// returns font manager singleton instance

View File

@ -266,6 +266,9 @@ private class FreeTypeFontFile {
for (int i = 0; i < sz; i++) for (int i = 0; i < sz; i++)
glyph.glyph[i] = bitmap.buffer[i]; glyph.glyph[i] = bitmap.buffer[i];
} }
version (USE_OPENGL) {
glyph.id = nextGlyphId();
}
} }
return true; return true;
} }

View File

@ -203,39 +203,71 @@ class Win32Font : Font {
} }
} }
override int measureText(const dchar[] text, ref int[] widths, int maxWidth) { static if (true) {
if (_hfont is null || _drawbuf is null || text.length == 0) override int measureText(const dchar[] text, ref int[] widths, int maxWidth) {
return 0; if (text.length == 0)
wstring utf16text = toUTF16(text); return 0;
const wchar * pstr = utf16text.ptr; const dchar * pstr = text.ptr;
uint len = cast(uint)utf16text.length; uint len = cast(uint)text.length;
GCP_RESULTSW gcpres; if (widths.length < len)
gcpres.lStructSize = gcpres.sizeof; widths.length = len;
if (widths.length < len + 1) int x = 0;
widths.length = len + 1; int charsMeasured = 0;
gcpres.lpDx = widths.ptr; for (int i = 0; i < len; i++) {
gcpres.nMaxFit = len; Glyph * glyph = getCharGlyph(text[i], true); // TODO: what is better
gcpres.nGlyphs = len; if (glyph is null) {
uint res = GetCharacterPlacementW( // if no glyph, use previous width - treat as zero width
_drawbuf.dc, widths[i] = i > 0 ? widths[i-1] : 0;
pstr, continue;
len, }
maxWidth, int w = x + glyph.width; // using advance
&gcpres, int w2 = x + glyph.originX + glyph.blackBoxX; // using black box
GCP_MAXEXTENT); //|GCP_USEKERNING if (w < w2) // choose bigger value
if (!res) { w = w2;
widths[0] = 0; widths[i] = w;
return 0; x += glyph.width;
} charsMeasured = i + 1;
uint measured = gcpres.nMaxFit; if (x > maxWidth)
int total = 0; break;
for (int i = 0; i < measured; i++) { }
int w = widths[i]; return charsMeasured;
total += w; }
widths[i] = total; } else {
}
return measured; override int measureText(const dchar[] text, ref int[] widths, int maxWidth) {
} if (_hfont is null || _drawbuf is null || text.length == 0)
return 0;
wstring utf16text = toUTF16(text);
const wchar * pstr = utf16text.ptr;
uint len = cast(uint)utf16text.length;
GCP_RESULTSW gcpres;
gcpres.lStructSize = gcpres.sizeof;
if (widths.length < len + 1)
widths.length = len + 1;
gcpres.lpDx = widths.ptr;
gcpres.nMaxFit = len;
gcpres.nGlyphs = len;
uint res = GetCharacterPlacementW(
_drawbuf.dc,
pstr,
len,
maxWidth,
&gcpres,
GCP_MAXEXTENT); //|GCP_USEKERNING
if (!res) {
widths[0] = 0;
return 0;
}
uint measured = gcpres.nMaxFit;
int total = 0;
for (int i = 0; i < measured; i++) {
int w = widths[i];
total += w;
widths[i] = total;
}
return measured;
}
}
bool create(FontDef * def, int size, int weight, bool italic) { bool create(FontDef * def, int size, int weight, bool italic) {
if (!isNull()) if (!isNull())
@ -300,7 +332,7 @@ class Win32FontManager : FontManager {
/// initialize in constructor /// initialize in constructor
this() { this() {
Log.i("Creating Win32FontManager"); Log.i("Creating Win32FontManager");
instance = this; //instance = this;
init(); init();
} }
~this() { ~this() {

View File

@ -201,6 +201,7 @@ class Win32Window : Window {
version (USE_OPENGL) { version (USE_OPENGL) {
private void paintUsingOpenGL() { private void paintUsingOpenGL() {
Log.d("paintUsingOpenGL()");
// hack to stop infinite WM_PAINT loop // hack to stop infinite WM_PAINT loop
PAINTSTRUCT ps; PAINTSTRUCT ps;
HDC hdc2 = BeginPaint(_hwnd, &ps); HDC hdc2 = BeginPaint(_hwnd, &ps);
@ -222,12 +223,14 @@ class Win32Window : Window {
float r = ((_backgroundColor >> 16) & 255) / 255.0f; float r = ((_backgroundColor >> 16) & 255) / 255.0f;
float g = ((_backgroundColor >> 8) & 255) / 255.0f; float g = ((_backgroundColor >> 8) & 255) / 255.0f;
float b = ((_backgroundColor >> 0) & 255) / 255.0f; float b = ((_backgroundColor >> 0) & 255) / 255.0f;
Log.d("paintUsingOpenGL() - clearing buffer");
glClearColor(r, g, b, a); glClearColor(r, g, b, a);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
Log.d("paintUsingOpenGL() - creating drawbuf");
GLDrawBuf buf = new GLDrawBuf(_dx, _dy, false); GLDrawBuf buf = new GLDrawBuf(_dx, _dy, false);
buf.beforeDrawing(); buf.beforeDrawing();
if (false) { static if (false) {
// for testing for render // for testing for render
buf.fillRect(Rect(100, 100, 200, 200), 0x704020); buf.fillRect(Rect(100, 100, 200, 200), 0x704020);
buf.fillRect(Rect(40, 70, 100, 120), 0x000000); buf.fillRect(Rect(40, 70, 100, 120), 0x000000);
@ -241,8 +244,9 @@ class Win32Window : Window {
} else { } else {
onDraw(buf); onDraw(buf);
} }
Log.d("paintUsingOpenGL() - calling buf.afterDrawing");
buf.afterDrawing(); buf.afterDrawing();
//Log.d("onPaint() end drawing opengl"); Log.d("onPaint() end drawing opengl");
SwapBuffers(hdc); SwapBuffers(hdc);
wglMakeCurrent(hdc, null); wglMakeCurrent(hdc, null);
} }
@ -595,8 +599,8 @@ int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int
// use Win32 font manager // use Win32 font manager
if (FontManager.instance is null) { if (FontManager.instance is null) {
Win32FontManager fontMan = new Win32FontManager(); //Win32FontManager fontMan = new Win32FontManager();
FontManager.instance = fontMan; FontManager.instance = new Win32FontManager();
} }
currentTheme = createDefaultTheme(); currentTheme = createDefaultTheme();