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>
<cv2pdbNoDemangle>0</cv2pdbNoDemangle>
<cv2pdbEnumType>0</cv2pdbEnumType>
<cv2pdbOptions />
<cv2pdbOptions>-profile</cv2pdbOptions>
<objfiles />
<linkswitches />
<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)
uint id;
}
///< 8: character
//uint glyphIndex;
///< 4: width of glyph black box
ubyte blackBoxX;
///< 5: height of glyph black box
@ -153,8 +157,7 @@ struct Glyph
byte originX;
///< 7: Y origin for glyph
byte originY;
///< 8: bytes in glyph array
ushort glyphIndex;
///< 10: full width of glyph
ubyte width;
///< 11: usage flag, to handle cleanup of unused glyphs

View File

@ -57,6 +57,76 @@ version (USE_OPENGL) {
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
struct GlyphCache
{
@ -218,6 +288,7 @@ struct GlyphCache
clear();
}
}
*/
/// Font object
class Font : RefCountedObject {

View File

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

View File

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

View File

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

View File

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