diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Style.cxx | 136 | ||||
-rw-r--r-- | src/Style.h | 61 | ||||
-rw-r--r-- | src/ViewStyle.cxx | 117 | ||||
-rw-r--r-- | src/ViewStyle.h | 15 |
4 files changed, 217 insertions, 112 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 } diff --git a/src/Style.h b/src/Style.h index c1f87e1b3..460dad490 100644 --- a/src/Style.h +++ b/src/Style.h @@ -12,18 +12,53 @@ namespace Scintilla { #endif +struct FontSpecification { + const char *fontName; + bool bold; + bool italic; + int size; + int characterSet; + int extraFontFlag; + FontSpecification() : + fontName(0), + bold(false), + italic(false), + size(10), + characterSet(0), + extraFontFlag(0) { + } + bool EqualTo(const FontSpecification &other) const; +}; + +// Just like Font but only has a copy of the FontID so should not delete it +class FontAlias : public Font { + // Private so FontAlias objects can not be copied + FontAlias(const FontAlias &); + FontAlias &operator=(const FontAlias &); +public: + FontAlias(); + virtual ~FontAlias(); + void ClearFont(); +}; + +struct FontMeasurements { + unsigned int lineHeight; + unsigned int ascent; + unsigned int descent; + unsigned int externalLeading; + unsigned int aveCharWidth; + unsigned int spaceWidth; + int sizeZoomed; + FontMeasurements(); + void Clear(); +}; + /** */ -class Style { +class Style : public FontSpecification, public FontMeasurements { public: ColourPair fore; ColourPair back; - bool aliasOfDefaultFont; - bool bold; - bool italic; - int size; - const char *fontName; - int characterSet; bool eolFilled; bool underline; enum ecaseForced {caseMixed, caseUpper, caseLower}; @@ -32,14 +67,7 @@ public: bool changeable; bool hotspot; - Font font; - int sizeZoomed; - unsigned int lineHeight; - unsigned int ascent; - unsigned int descent; - unsigned int externalLeading; - unsigned int aveCharWidth; - unsigned int spaceWidth; + FontAlias font; Style(); Style(const Style &source); @@ -52,8 +80,7 @@ public: bool underline_, ecaseForced caseForce_, bool visible_, bool changeable_, bool hotspot_); void ClearTo(const Style &source); - bool EquivalentFontTo(const Style *other) const; - void Realise(Surface &surface, int zoomLevel, Style *defaultStyle = 0, int extraFontFlag = 0); + void Copy(Font &font_, const FontMeasurements &fm_); bool IsProtected() const { return !(changeable && visible);} }; 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() { diff --git a/src/ViewStyle.h b/src/ViewStyle.h index 6ca488dff..cf45be41f 100644 --- a/src/ViewStyle.h +++ b/src/ViewStyle.h @@ -39,6 +39,19 @@ public: const char *Save(const char *name); }; +class FontRealised : public Font, public FontSpecification, public FontMeasurements { + // Private so FontRealised objects can not be copied + FontRealised(const FontRealised &); + FontRealised &operator=(const FontRealised &); +public: + FontRealised *frNext; + FontRealised(const FontSpecification &fs); + virtual ~FontRealised(); + void Realise(Surface &surface, int zoomLevel); + FontRealised *Find(const FontSpecification &fs); + void FindMaxAscentDescent(unsigned int &maxAscent, unsigned int &maxDescent); +}; + enum IndentView {ivNone, ivReal, ivLookForward, ivLookBoth}; enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterIndent=2}; @@ -48,6 +61,7 @@ enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterInden class ViewStyle { public: FontNames fontNames; + FontRealised *frFirst; size_t stylesSize; Style *styles; LineMarker markers[MARKER_MAX + 1]; @@ -119,6 +133,7 @@ public: ViewStyle(const ViewStyle &source); ~ViewStyle(); void Init(size_t stylesSize_=64); + void CreateFont(const FontSpecification &fs); void RefreshColourPalette(Palette &pal, bool want); void Refresh(Surface &surface); void AllocStyles(size_t sizeNew); |