aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/ViewStyle.cxx
diff options
context:
space:
mode:
authornyamatongwe <unknown>2011-03-30 10:27:05 +1100
committernyamatongwe <unknown>2011-03-30 10:27:05 +1100
commitf88ad3864ccdf534e46cc004b377b2c08d318a04 (patch)
tree2efa44a4ecfe7b1b864c2c049d1bc6397b779bc3 /src/ViewStyle.cxx
parentef7f8a349a89dd7d72d62f7a162cb3e553ca4ba6 (diff)
downloadscintilla-mirror-f88ad3864ccdf534e46cc004b377b2c08d318a04.tar.gz
Optimize font use by only allocating platform font resources for unique fonts
and using aliases of these in the Style objects. Font measurement is also performed once for each unique font and the results copied into each style. No change is needed in callers. On PLAT_WX, the font ascent is cached in the Font object when Ascent is called but this is not copied into the aliases as ascent is protected. Therefore the code that copies the FontID into the alias also calls Ascent to ensure the ascent value is cached.
Diffstat (limited to 'src/ViewStyle.cxx')
-rw-r--r--src/ViewStyle.cxx117
1 files changed, 100 insertions, 17 deletions
diff --git a/src/ViewStyle.cxx b/src/ViewStyle.cxx
index 78ba1f78c..30911d3f5 100644
--- a/src/ViewStyle.cxx
+++ b/src/ViewStyle.cxx
@@ -72,11 +72,65 @@ const char *FontNames::Save(const char *name) {
return names[max-1];
}
+FontRealised::FontRealised(const FontSpecification &fs) {
+ frNext = NULL;
+ (FontSpecification &)(*this) = fs;
+}
+
+FontRealised::~FontRealised() {
+ delete frNext;
+ frNext = 0;
+}
+
+void FontRealised::Realise(Surface &surface, int zoomLevel) {
+ PLATFORM_ASSERT(fontName);
+ sizeZoomed = size + zoomLevel;
+ if (sizeZoomed <= 2) // Hangs if sizeZoomed <= 1
+ sizeZoomed = 2;
+
+ int deviceHeight = surface.DeviceHeightFont(sizeZoomed);
+ Create(fontName, characterSet, deviceHeight, bold, italic, extraFontFlag);
+
+ ascent = surface.Ascent(*this);
+ descent = surface.Descent(*this);
+ externalLeading = surface.ExternalLeading(*this);
+ lineHeight = surface.Height(*this);
+ aveCharWidth = surface.AverageCharWidth(*this);
+ spaceWidth = surface.WidthChar(*this, ' ');
+ if (frNext) {
+ frNext->Realise(surface, zoomLevel);
+ }
+}
+
+FontRealised *FontRealised::Find(const FontSpecification &fs) {
+ if (!fs.fontName)
+ return this;
+ FontRealised *fr = this;
+ while (fr) {
+ if (fr->EqualTo(fs))
+ return fr;
+ fr = fr->frNext;
+ }
+ return 0;
+}
+
+void FontRealised::FindMaxAscentDescent(unsigned int &maxAscent, unsigned int &maxDescent) {
+ FontRealised *fr = this;
+ while (fr) {
+ if (maxAscent < ascent)
+ maxAscent = ascent;
+ if (maxDescent < descent)
+ maxDescent = descent;
+ fr = fr->frNext;
+ }
+}
+
ViewStyle::ViewStyle() {
Init();
}
ViewStyle::ViewStyle(const ViewStyle &source) {
+ frFirst = NULL;
Init(source.stylesSize);
for (unsigned int sty=0; sty<source.stylesSize; sty++) {
styles[sty] = source.styles[sty];
@@ -155,9 +209,12 @@ ViewStyle::ViewStyle(const ViewStyle &source) {
ViewStyle::~ViewStyle() {
delete []styles;
styles = NULL;
+ delete frFirst;
+ frFirst = NULL;
}
void ViewStyle::Init(size_t stylesSize_) {
+ frFirst = NULL;
stylesSize = 0;
styles = NULL;
AllocStyles(stylesSize_);
@@ -290,22 +347,51 @@ void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
pal.WantFind(hotspotBackground, want);
}
+void ViewStyle::CreateFont(const FontSpecification &fs) {
+ if (fs.fontName) {
+ for (FontRealised *cur=frFirst; cur; cur=cur->frNext) {
+ if (cur->EqualTo(fs))
+ return;
+ if (!cur->frNext) {
+ cur->frNext = new FontRealised(fs);
+ return;
+ }
+ }
+ frFirst = new FontRealised(fs);
+ }
+}
+
void ViewStyle::Refresh(Surface &surface) {
+ delete frFirst;
+ frFirst = NULL;
selbar.desired = Platform::Chrome();
selbarlight.desired = Platform::ChromeHighlight();
- styles[STYLE_DEFAULT].Realise(surface, zoomLevel, NULL, extraFontFlag);
- maxAscent = styles[STYLE_DEFAULT].ascent;
- maxDescent = styles[STYLE_DEFAULT].descent;
+
+ for (unsigned int i=0; i<stylesSize; i++) {
+ styles[i].extraFontFlag = extraFontFlag;
+ }
+
+ CreateFont(styles[STYLE_DEFAULT]);
+ for (unsigned int i=0; i<stylesSize; i++) {
+ CreateFont(styles[i]);
+ }
+
+ frFirst->Realise(surface, zoomLevel);
+
+ for (unsigned int i=0; i<stylesSize; i++) {
+ FontRealised *fr = frFirst->Find(styles[i]);
+ styles[i].Copy(*fr, *fr);
+ }
+ maxAscent = 1;
+ maxDescent = 1;
+ frFirst->FindMaxAscentDescent(maxAscent, maxDescent);
+ maxAscent += extraAscent;
+ maxDescent += extraDescent;
+ lineHeight = maxAscent + maxDescent;
+
someStylesProtected = false;
someStylesForceCase = false;
for (unsigned int i=0; i<stylesSize; i++) {
- if (i != STYLE_DEFAULT) {
- styles[i].Realise(surface, zoomLevel, &styles[STYLE_DEFAULT], extraFontFlag);
- if (maxAscent < styles[i].ascent)
- maxAscent = styles[i].ascent;
- if (maxDescent < styles[i].descent)
- maxDescent = styles[i].descent;
- }
if (styles[i].IsProtected()) {
someStylesProtected = true;
}
@@ -313,10 +399,7 @@ void ViewStyle::Refresh(Surface &surface) {
someStylesForceCase = true;
}
}
- maxAscent += extraAscent;
- maxDescent += extraDescent;
- lineHeight = maxAscent + maxDescent;
aveCharWidth = styles[STYLE_DEFAULT].aveCharWidth;
spaceWidth = styles[STYLE_DEFAULT].spaceWidth;
@@ -361,10 +444,10 @@ void ViewStyle::EnsureStyle(size_t index) {
void ViewStyle::ResetDefaultStyle() {
styles[STYLE_DEFAULT].Clear(ColourDesired(0,0,0),
- ColourDesired(0xff,0xff,0xff),
- Platform::DefaultFontSize(), fontNames.Save(Platform::DefaultFont()),
- SC_CHARSET_DEFAULT,
- false, false, false, false, Style::caseMixed, true, true, false);
+ ColourDesired(0xff,0xff,0xff),
+ Platform::DefaultFontSize(), fontNames.Save(Platform::DefaultFont()),
+ SC_CHARSET_DEFAULT,
+ false, false, false, false, Style::caseMixed, true, true, false);
}
void ViewStyle::ClearStyles() {