mirror of https://github.com/buggins/dlangui.git
performance optimizations
This commit is contained in:
parent
02f158e128
commit
729b406a45
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue