diff options
| -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); | 
