performance optimizations

This commit is contained in:
Vadim Lopatin 2014-04-23 16:43:56 +04:00
parent 02f158e128
commit 729b406a45
7 changed files with 98 additions and 14 deletions

View File

@ -80,7 +80,7 @@
<cv2pdbPre2043>0</cv2pdbPre2043> <cv2pdbPre2043>0</cv2pdbPre2043>
<cv2pdbNoDemangle>0</cv2pdbNoDemangle> <cv2pdbNoDemangle>0</cv2pdbNoDemangle>
<cv2pdbEnumType>0</cv2pdbEnumType> <cv2pdbEnumType>0</cv2pdbEnumType>
<cv2pdbOptions /> <cv2pdbOptions>-profile</cv2pdbOptions>
<objfiles /> <objfiles />
<linkswitches /> <linkswitches />
<libfiles>libpng15.lib dlangui.lib phobos.lib ole32.lib kernel32.lib user32.lib comctl32.lib comdlg32.lib shell32.lib dlangui.lib</libfiles> <libfiles>libpng15.lib dlangui.lib phobos.lib ole32.lib kernel32.lib user32.lib comctl32.lib comdlg32.lib shell32.lib dlangui.lib</libfiles>

View File

@ -145,6 +145,10 @@ struct Glyph
///< 0: unique id of glyph (for drawing in hardware accelerated scenes) ///< 0: unique id of glyph (for drawing in hardware accelerated scenes)
uint id; uint id;
} }
///< 8: character
//uint glyphIndex;
///< 4: width of glyph black box ///< 4: width of glyph black box
ubyte blackBoxX; ubyte blackBoxX;
///< 5: height of glyph black box ///< 5: height of glyph black box
@ -153,8 +157,7 @@ struct Glyph
byte originX; byte originX;
///< 7: Y origin for glyph ///< 7: Y origin for glyph
byte originY; byte originY;
///< 8: bytes in glyph array
ushort glyphIndex;
///< 10: full width of glyph ///< 10: full width of glyph
ubyte width; ubyte width;
///< 11: usage flag, to handle cleanup of unused glyphs ///< 11: usage flag, to handle cleanup of unused glyphs

View File

@ -57,6 +57,76 @@ version (USE_OPENGL) {
uint nextGlyphId() { return _nextGlyphId++; } uint nextGlyphId() { return _nextGlyphId++; }
} }
struct GlyphCache
{
alias glyph_ptr = Glyph*;
private glyph_ptr[][1024] _glyphs;
Glyph * find(uint ch) {
ch = ch & 0xF_FFFF;
//if (_array is null)
// _array = new Glyph[0x10000];
uint p = ch >> 8;
glyph_ptr[] row = _glyphs[p];
if (row is null)
return null;
ushort i = ch & 0xFF;
return row[i];
}
/// put glyph to cache
Glyph * put(uint ch, Glyph * glyph) {
uint p = ch >> 8;
uint i = ch & 0xFF;
if (_glyphs[p] is null)
_glyphs[p] = new glyph_ptr[256];
_glyphs[p][i] = glyph;
return glyph;
}
/// removes entries not used after last call of checkpoint() or cleanup()
void cleanup() {
// TODO
}
// clear usage flags for all entries
void checkpoint() {
}
/// removes all entries
void clear() {
// notify about destroyed glyphs
version (USE_OPENGL) {
if (_glyphDestroyCallback !is null) {
foreach(part; _glyphs) {
if (part !is null)
foreach(item; part) {
if (item)
_glyphDestroyCallback(item.id);
}
}
}
}
/*
foreach(ref Glyph[] part; _glyphs) {
if (part !is null)
foreach(ref Glyph item; part) {
if (item.glyphIndex) {
item.glyphIndex = 0;
item.glyph = null;
version (USE_OPENGL) {
item.id = 0;
}
}
}
}
*/
}
~this() {
clear();
}
}
/*
/// font glyph cache /// font glyph cache
struct GlyphCache struct GlyphCache
{ {
@ -218,6 +288,7 @@ struct GlyphCache
clear(); clear();
} }
} }
*/
/// Font object /// Font object
class Font : RefCountedObject { class Font : RefCountedObject {

View File

@ -255,7 +255,7 @@ private class FreeTypeFontFile {
glyph.originX = cast(byte)(_slot.metrics.horiBearingX >> 6); glyph.originX = cast(byte)(_slot.metrics.horiBearingX >> 6);
glyph.originY = cast(byte)(_slot.metrics.horiBearingY >> 6); glyph.originY = cast(byte)(_slot.metrics.horiBearingY >> 6);
glyph.width = cast(ubyte)(myabs(cast(int)(_slot.metrics.horiAdvance)) >> 6); glyph.width = cast(ubyte)(myabs(cast(int)(_slot.metrics.horiAdvance)) >> 6);
glyph.glyphIndex = cast(ushort)code; //glyph.glyphIndex = cast(ushort)code;
if (withImage) { if (withImage) {
FT_Bitmap* bitmap = &_slot.bitmap; FT_Bitmap* bitmap = &_slot.bitmap;
ubyte w = cast(ubyte)(bitmap.width); ubyte w = cast(ubyte)(bitmap.width);

View File

@ -101,14 +101,14 @@ class Win32Font : Font {
} }
override Glyph * getCharGlyph(dchar ch, bool withImage = true) { override Glyph * getCharGlyph(dchar ch, bool withImage = true) {
Glyph * found = _glyphCache.find(ch);
if (found !is null)
return found;
uint glyphIndex = getGlyphIndex(ch); uint glyphIndex = getGlyphIndex(ch);
if (!glyphIndex) if (!glyphIndex)
return null; return null;
if (glyphIndex >= 0xFFFF) if (glyphIndex >= 0xFFFF)
return null; return null;
Glyph * found = _glyphCache.find(cast(ushort)glyphIndex);
if (found !is null)
return found;
GLYPHMETRICS metrics; GLYPHMETRICS metrics;
MAT2 identity = { {0,1}, {0,0}, {0,0}, {0,1} }; MAT2 identity = { {0,1}, {0,0}, {0,0}, {0,1} };
@ -130,7 +130,7 @@ class Win32Font : Font {
if (gs >= 0x10000 || gs < 0) if (gs >= 0x10000 || gs < 0)
return null; return null;
Glyph g; Glyph * g = new Glyph;
version (USE_OPENGL) { version (USE_OPENGL) {
g.id = nextGlyphId(); g.id = nextGlyphId();
} }
@ -139,7 +139,7 @@ class Win32Font : Font {
g.originX = cast(byte)metrics.gmptGlyphOrigin.x; g.originX = cast(byte)metrics.gmptGlyphOrigin.x;
g.originY = cast(byte)metrics.gmptGlyphOrigin.y; g.originY = cast(byte)metrics.gmptGlyphOrigin.y;
g.width = cast(ubyte)metrics.gmCellIncX; g.width = cast(ubyte)metrics.gmCellIncX;
g.glyphIndex = cast(ushort)glyphIndex; //g.glyphIndex = cast(ushort)glyphIndex;
if (g.blackBoxX>0 && g.blackBoxY>0) if (g.blackBoxX>0 && g.blackBoxY>0)
{ {
@ -182,7 +182,7 @@ class Win32Font : Font {
} }
} }
// found! // found!
return _glyphCache.put(cast(ushort)glyphIndex, &g); return _glyphCache.put(ch, g);
} }
// draw text string to buffer // draw text string to buffer

View File

@ -461,7 +461,7 @@ class Win32Window : Window {
/// request window redraw /// request window redraw
override void invalidate() { override void invalidate() {
InvalidateRect(_hwnd, null, FALSE); InvalidateRect(_hwnd, null, FALSE);
UpdateWindow(_hwnd); //UpdateWindow(_hwnd);
} }
/// after drawing, call to schedule redraw if animation is active /// after drawing, call to schedule redraw if animation is active
@ -596,7 +596,7 @@ int DLANGUIWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
{ {
Runtime.initialize(); Runtime.initialize();
result = myWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow); result = myWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
//Runtime.terminate(); Runtime.terminate();
} }
catch (Throwable e) // catch any uncaught exceptions catch (Throwable e) // catch any uncaught exceptions
{ {
@ -659,7 +659,7 @@ int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int
Platform.setInstance(platform); Platform.setInstance(platform);
if (true) { if (false) {
/// testing freetype font manager /// testing freetype font manager
import dlangui.graphics.ftfonts; import dlangui.graphics.ftfonts;
import win32.shlobj; import win32.shlobj;

View File

@ -298,8 +298,14 @@ class EditableContent {
} }
/// replace whole text with another content /// replace whole text with another content
@property EditableContent text(dstring newContent) { @property EditableContent text(dstring newContent) {
clearUndo();
_lines.length = 0; _lines.length = 0;
_lines = splitDString(newContent); if (_multiline)
_lines = splitDString(newContent);
else {
_lines.length = 1;
_lines[0] = replaceEolsWithSpaces(newContent);
}
return this; return this;
} }
/// returns line text /// returns line text
@ -472,6 +478,10 @@ class EditableContent {
handleContentChange(op, rangeBefore, rangeAfter); handleContentChange(op, rangeBefore, rangeAfter);
return true; return true;
} }
/// clear undo/redp history
void clearUndo() {
_undoBuffer.clear();
}
} }
/// Editor action codes /// Editor action codes