aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Style.cxx
diff options
context:
space:
mode:
authornyamatongwe <devnull@localhost>2011-03-30 10:27:05 +1100
committernyamatongwe <devnull@localhost>2011-03-30 10:27:05 +1100
commit8d7937803d186c9a5ad3e256fc93503ba861ee78 (patch)
tree0b1009491da396da383186d0560c11966362de40 /src/Style.cxx
parent3ed550474301fa98e75c23d1f9c55763b296224e (diff)
downloadscintilla-mirror-8d7937803d186c9a5ad3e256fc93503ba861ee78.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/Style.cxx')
-rw-r--r--src/Style.cxx136
1 files changed, 58 insertions, 78 deletions
diff --git a/src/Style.cxx b/src/Style.cxx
index 392fd1c9a..b86884aa5 100644
--- a/src/Style.cxx
+++ b/src/Style.cxx
@@ -16,8 +16,41 @@
using namespace Scintilla;
#endif
+FontAlias::FontAlias() {
+}
+
+FontAlias::~FontAlias() {
+ SetID(0);
+ // ~Font will not release the actual font resource sine it is now 0
+}
+
+void FontAlias::ClearFont() {
+ SetID(0);
+}
+
+bool FontSpecification::EqualTo(const FontSpecification &other) const {
+ return bold == other.bold &&
+ italic == other.italic &&
+ size == other.size &&
+ characterSet == other.characterSet &&
+ fontName == other.fontName;
+}
+
+FontMeasurements::FontMeasurements() {
+ Clear();
+}
+
+void FontMeasurements::Clear() {
+ lineHeight = 2;
+ ascent = 1;
+ descent = 1;
+ externalLeading = 0;
+ aveCharWidth = 1;
+ spaceWidth = 1;
+ sizeZoomed = 2;
+}
+
Style::Style() {
- aliasOfDefaultFont = true;
Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff),
Platform::DefaultFontSize(), 0, SC_CHARSET_DEFAULT,
false, false, false, false, caseMixed, true, true, false);
@@ -42,11 +75,6 @@ Style::Style(const Style &source) {
}
Style::~Style() {
- if (aliasOfDefaultFont)
- font.SetID(0);
- else
- font.Release();
- aliasOfDefaultFont = false;
}
Style &Style::operator=(const Style &source) {
@@ -70,10 +98,10 @@ Style &Style::operator=(const Style &source) {
}
void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_,
- const char *fontName_, int characterSet_,
- bool bold_, bool italic_, bool eolFilled_,
- bool underline_, ecaseForced caseForce_,
- bool visible_, bool changeable_, bool hotspot_) {
+ const char *fontName_, int characterSet_,
+ bool bold_, bool italic_, bool eolFilled_,
+ bool underline_, ecaseForced caseForce_,
+ bool visible_, bool changeable_, bool hotspot_) {
fore.desired = fore_;
back.desired = back_;
characterSet = characterSet_;
@@ -87,79 +115,31 @@ void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_,
visible = visible_;
changeable = changeable_;
hotspot = hotspot_;
- if (aliasOfDefaultFont)
- font.SetID(0);
- else
- font.Release();
- aliasOfDefaultFont = false;
- sizeZoomed = 2;
- lineHeight = 2;
- ascent = 1;
- descent = 1;
- externalLeading = 0;
- aveCharWidth = 1;
- spaceWidth = 1;
+ font.ClearFont();
+ FontMeasurements::Clear();
}
void Style::ClearTo(const Style &source) {
Clear(
- source.fore.desired,
- source.back.desired,
- source.size,
- source.fontName,
- source.characterSet,
- source.bold,
- source.italic,
- source.eolFilled,
- source.underline,
- source.caseForce,
- source.visible,
- source.changeable,
- source.hotspot);
+ source.fore.desired,
+ source.back.desired,
+ source.size,
+ source.fontName,
+ source.characterSet,
+ source.bold,
+ source.italic,
+ source.eolFilled,
+ source.underline,
+ source.caseForce,
+ source.visible,
+ source.changeable,
+ source.hotspot);
}
-bool Style::EquivalentFontTo(const Style *other) const {
- if (bold != other->bold ||
- italic != other->italic ||
- size != other->size ||
- characterSet != other->characterSet)
- return false;
- if (fontName == other->fontName)
- return true;
- if (!fontName)
- return false;
- if (!other->fontName)
- return false;
- return strcmp(fontName, other->fontName) == 0;
-}
-
-void Style::Realise(Surface &surface, int zoomLevel, Style *defaultStyle, int extraFontFlag) {
- sizeZoomed = size + zoomLevel;
- if (sizeZoomed <= 2) // Hangs if sizeZoomed <= 1
- sizeZoomed = 2;
-
- if (aliasOfDefaultFont)
- font.SetID(0);
- else
- font.Release();
- int deviceHeight = surface.DeviceHeightFont(sizeZoomed);
- aliasOfDefaultFont = defaultStyle &&
- (EquivalentFontTo(defaultStyle) || !fontName);
- if (aliasOfDefaultFont) {
- font.SetID(defaultStyle->font.GetID());
- } else if (fontName) {
- font.Create(fontName, characterSet, deviceHeight, bold, italic, extraFontFlag);
- } else {
- font.SetID(0);
- }
-
+void Style::Copy(Font &font_, const FontMeasurements &fm_) {
+ font.SetID(font_.GetID());
+ (FontMeasurements &)(*this) = fm_;
+#if PLAT_WX
ascent = surface.Ascent(font);
- descent = surface.Descent(font);
- // Probably more typographically correct to include leading
- // but that means more complex drawing as leading must be erased
- //lineHeight = surface.ExternalLeading() + surface.Height();
- externalLeading = surface.ExternalLeading(font);
- lineHeight = surface.Height(font);
- aveCharWidth = surface.AverageCharWidth(font);
- spaceWidth = surface.WidthChar(font, ' ');
+#endif
}