diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Editor.cxx | 9 | ||||
| -rw-r--r-- | src/PositionCache.cxx | 16 | ||||
| -rw-r--r-- | src/Style.cxx | 1 | ||||
| -rw-r--r-- | src/Style.h | 2 | ||||
| -rw-r--r-- | src/ViewStyle.cxx | 19 | 
5 files changed, 46 insertions, 1 deletions
| diff --git a/src/Editor.cxx b/src/Editor.cxx index db7e2366e..bd2742539 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -117,7 +117,7 @@ static constexpr bool IsAllSpacesOrTabs(std::string_view sv) noexcept {  	return true;  } -Editor::Editor() : durationWrapOneByte(0.000001, 0.0000001, 0.00001) { +Editor::Editor() : durationWrapOneByte(0.000001, 0.00000001, 0.00001) {  	ctrlID = 0;  	stylesValid = false; @@ -5748,6 +5748,9 @@ void Editor::StyleSetMessage(Message iMessage, uptr_t wParam, sptr_t lParam) {  	case Message::StyleSetHotSpot:  		vs.styles[wParam].hotspot = lParam != 0;  		break; +	case Message::StyleSetCheckMonospaced: +		vs.styles[wParam].checkMonospaced = lParam != 0; +		break;  	default:  		break;  	} @@ -5787,6 +5790,8 @@ sptr_t Editor::StyleGetMessage(Message iMessage, uptr_t wParam, sptr_t lParam) {  		return vs.styles[wParam].changeable ? 1 : 0;  	case Message::StyleGetHotSpot:  		return vs.styles[wParam].hotspot ? 1 : 0; +	case Message::StyleGetCheckMonospaced: +		return vs.styles[wParam].checkMonospaced ? 1 : 0;  	default:  		break;  	} @@ -7202,6 +7207,7 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {  	case Message::StyleSetVisible:  	case Message::StyleSetChangeable:  	case Message::StyleSetHotSpot: +	case Message::StyleSetCheckMonospaced:  		StyleSetMessage(iMessage, wParam, lParam);  		break; @@ -7220,6 +7226,7 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {  	case Message::StyleGetVisible:  	case Message::StyleGetChangeable:  	case Message::StyleGetHotSpot: +	case Message::StyleGetCheckMonospaced:  		return StyleGetMessage(iMessage, wParam, lParam);  	case Message::StyleResetDefault: diff --git a/src/PositionCache.cxx b/src/PositionCache.cxx index 714937dc1..fda736cc7 100644 --- a/src/PositionCache.cxx +++ b/src/PositionCache.cxx @@ -377,6 +377,14 @@ constexpr size_t AlignUp(size_t value, size_t alignment) noexcept {  constexpr size_t alignmentLLC = 20; +constexpr bool GraphicASCII(char ch) noexcept { +	return ch >= ' ' && ch <= '~'; +} + +bool AllGraphicASCII(std::string_view text) noexcept { +	return std::all_of(text.cbegin(), text.cend(), GraphicASCII); +} +  } @@ -895,6 +903,14 @@ void PositionCache::MeasureWidths(Surface *surface, const ViewStyle &vstyle, uns  			probe = probe2;  		}  	} +	if (vstyle.styles[styleNumber].monospaceASCII) { +		if (AllGraphicASCII(sv)) { +			for (size_t i = 0; i < sv.length(); i++) { +				positions[i] = vstyle.styles[styleNumber].aveCharWidth * (i+1); +			} +			return; +		} +	}  	const Font *fontStyle = vstyle.styles[styleNumber].font.get();  	surface->MeasureWidths(fontStyle, sv, positions);  	if (probe < pces.size()) { diff --git a/src/Style.cxx b/src/Style.cxx index d71b62d97..3a57d1a08 100644 --- a/src/Style.cxx +++ b/src/Style.cxx @@ -57,6 +57,7 @@ void FontMeasurements::ClearMeasurements() noexcept {  	capitalHeight = 1;  	aveCharWidth = 1;  	spaceWidth = 1; +	monospaceASCII = false;  	sizeZoomed = 2;  } diff --git a/src/Style.h b/src/Style.h index 8153d156e..087b13b2f 100644 --- a/src/Style.h +++ b/src/Style.h @@ -17,6 +17,7 @@ struct FontSpecification {  	int size;  	Scintilla::CharacterSet characterSet;  	Scintilla::FontQuality extraFontFlag; +	bool checkMonospaced = false;  	FontSpecification() noexcept :  		fontName(nullptr),  		weight(Scintilla::FontWeight::Normal), @@ -35,6 +36,7 @@ struct FontMeasurements {  	XYPOSITION capitalHeight;	// Top of capital letter to baseline: ascent - internal leading  	XYPOSITION aveCharWidth;  	XYPOSITION spaceWidth; +	bool monospaceASCII = false;  	int sizeZoomed;  	FontMeasurements() noexcept;  	void ClearMeasurements() noexcept; diff --git a/src/ViewStyle.cxx b/src/ViewStyle.cxx index 33b861445..47f76d357 100644 --- a/src/ViewStyle.cxx +++ b/src/ViewStyle.cxx @@ -18,6 +18,7 @@  #include <optional>  #include <algorithm>  #include <memory> +#include <numeric>  #include "ScintillaTypes.h" @@ -64,6 +65,24 @@ void FontRealised::Realise(Surface &surface, int zoomLevel, Technology technolog  	capitalHeight = surface.Ascent(font.get()) - surface.InternalLeading(font.get());  	aveCharWidth = surface.AverageCharWidth(font.get());  	spaceWidth = surface.WidthText(font.get(), " "); + +	if (fs.checkMonospaced) { +		std::string allASCIIGraphic("Ayfi");	// "Ay" is normally strongly kerned and "fi" may be a ligature +		for (unsigned char ch = 0x20; ch <= 0x7E; ch++) { +			allASCIIGraphic.push_back(ch); +		} +		std::vector<XYPOSITION> positions(allASCIIGraphic.length()); +		surface.MeasureWidths(font.get(), allASCIIGraphic, positions.data()); +		std::adjacent_difference(positions.begin(), positions.end(), positions.begin()); +		const XYPOSITION maxWidth = *std::max_element(positions.begin(), positions.end()); +		const XYPOSITION minWidth = *std::min_element(positions.begin(), positions.end()); +		const XYPOSITION variance = maxWidth - minWidth; +		const XYPOSITION scaledVariance = variance / aveCharWidth; +		constexpr XYPOSITION monospaceWidthEpsilon = 0.000001;	// May need tweaking if monospace fonts vary more +		monospaceASCII = scaledVariance < monospaceWidthEpsilon; +	} else { +		monospaceASCII = false; +	}  }  ViewStyle::ViewStyle() : markers(MarkerMax + 1), indicators(static_cast<size_t>(IndicatorNumbers::Max) + 1) { | 
