diff options
| author | Neil <nyamatongwe@gmail.com> | 2021-03-20 17:43:48 +1100 | 
|---|---|---|
| committer | Neil <nyamatongwe@gmail.com> | 2021-03-20 17:43:48 +1100 | 
| commit | 5890eafae756457cee82a23bdd0aa49d1ca74172 (patch) | |
| tree | e431efe0f4e6dc531e404da48b5c485c71750ffe /src/LineMarker.cxx | |
| parent | 1f630daf4b61ea12bc2ec2d688dba2586c172611 (diff) | |
| download | scintilla-mirror-5890eafae756457cee82a23bdd0aa49d1ca74172.tar.gz | |
Use new Surface APIs for marker drawing. Clipping allows rounded fold markers to
be highlighted better.
Diffstat (limited to 'src/LineMarker.cxx')
| -rw-r--r-- | src/LineMarker.cxx | 554 | 
1 files changed, 283 insertions, 271 deletions
| diff --git a/src/LineMarker.cxx b/src/LineMarker.cxx index 0bafbe75f..13d8b05ae 100644 --- a/src/LineMarker.cxx +++ b/src/LineMarker.cxx @@ -23,7 +23,6 @@  #include "Scintilla.h" -#include "IntegerRectangle.h"  #include "XPM.h"  #include "LineMarker.h" @@ -83,41 +82,72 @@ void LineMarker::SetRGBAImage(Point sizeRGBAImage, float scale, const unsigned c  	markType = SC_MARK_RGBAIMAGE;  } -static void DrawBox(Surface *surface, int centreX, int centreY, int armSize, ColourDesired fore, ColourDesired back) { -	const PRectangle rc = PRectangle::FromInts( -				      centreX - armSize, -				      centreY - armSize, -				      centreX + armSize + 1, -				      centreY + armSize + 1); -	surface->RectangleDraw(rc, back, fore); -} +namespace { + +enum class Expansion { Minus, Plus }; +enum class Shape { Square, Circle }; + +void DrawSymbol(Surface *surface, Shape shape, Expansion expansion, PRectangle rcSymbol, XYPOSITION widthStroke, +	ColourDesired colourFill, ColourDesired colourFrame, ColourDesired colourFrameRight, ColourDesired colourExpansion) { -static void DrawCircle(Surface *surface, int centreX, int centreY, int armSize, ColourDesired fore, ColourDesired back) { -	const PRectangle rcCircle = PRectangle::FromInts( -					    centreX - armSize, -					    centreY - armSize, -					    centreX + armSize + 1, -					    centreY + armSize + 1); -	surface->Ellipse(rcCircle, back, fore); +	const FillStroke fillStroke(colourFill, colourFrame, widthStroke); +	const PRectangle rcSymbolLeft = Side(rcSymbol, Edge::left, (rcSymbol.Width() + widthStroke) / 2.0f); +	surface->SetClip(rcSymbolLeft); +	if (shape == Shape::Square) { +		// Hollowed square +		surface->RectangleDraw(rcSymbol, fillStroke); +	} else { +		surface->Ellipse(rcSymbol, fillStroke); +	} +	surface->PopClip(); + +	const FillStroke fillStrokeRight(colourFill, colourFrameRight, widthStroke); +	const PRectangle rcSymbolRight = Side(rcSymbol, Edge::right, (rcSymbol.Width() - widthStroke) / 2.0f); +	surface->SetClip(rcSymbolRight); +	if (shape == Shape::Square) { +		surface->RectangleDraw(rcSymbol, fillStrokeRight); +	} else { +		surface->Ellipse(rcSymbol, fillStrokeRight); +	} +	surface->PopClip(); + +	const PRectangle rcPlusMinus = rcSymbol.Inset(widthStroke + 1.0f); +	const XYPOSITION armWidth = (rcPlusMinus.Width() - widthStroke) / 2.0f; +	const XYPOSITION top = rcPlusMinus.top + armWidth; +	const PRectangle rcH = PRectangle( +		rcPlusMinus.left, top, +		rcPlusMinus.right, top + widthStroke); +	surface->FillRectangle(rcH, colourExpansion); +	if (expansion == Expansion::Plus) { +		const XYPOSITION left = rcPlusMinus.left + armWidth; +		const PRectangle rcV = PRectangle( +			left, rcPlusMinus.top, +			left + widthStroke, rcPlusMinus.bottom); +		surface->FillRectangle(rcV, colourExpansion); +	}  } -static void DrawPlus(Surface *surface, int centreX, int centreY, int armSize, ColourDesired fore) { -	const PRectangle rcV = PRectangle::FromInts(centreX, centreY - armSize + 2, centreX + 1, centreY + armSize - 2 + 1); -	surface->FillRectangle(rcV, fore); -	const PRectangle rcH = PRectangle::FromInts(centreX - armSize + 2, centreY, centreX + armSize - 2 + 1, centreY + 1); -	surface->FillRectangle(rcH, fore); +void DrawTail(Surface *surface, XYPOSITION leftLine, XYPOSITION rightTail, XYPOSITION centreY, XYPOSITION widthSymbolStroke, ColourDesired fill) { +	const XYPOSITION slopeLength = 2.0f + widthSymbolStroke; +	const XYPOSITION strokeTop = centreY + slopeLength; +	const XYPOSITION halfWidth = widthSymbolStroke / 2.0f; +	const XYPOSITION strokeMiddle = strokeTop + halfWidth; +	Point lines[] = { +		// Stick +		Point(rightTail, strokeMiddle), +		Point(leftLine + halfWidth + slopeLength, strokeMiddle), +		// Slope +		Point(leftLine + widthSymbolStroke / 2.0f, centreY + halfWidth), +	}; +	surface->PolyLine(lines, std::size(lines), Stroke(fill, widthSymbolStroke));  } -static void DrawMinus(Surface *surface, int centreX, int centreY, int armSize, ColourDesired fore) { -	const PRectangle rcH = PRectangle::FromInts(centreX - armSize + 2, centreY, centreX + armSize - 2 + 1, centreY + 1); -	surface->FillRectangle(rcH, fore);  } -void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, const Font *fontForCharacter, FoldPart part, int marginStyle) const { -	if (customDraw) { -		customDraw(surface, rcWhole, fontForCharacter, static_cast<int>(part), marginStyle, this); -		return; -	} +void LineMarker::DrawFoldingMark(Surface *surface, const PRectangle &rcWhole, FoldPart part) const { +	// Assume: edges of rcWhole are integers. +	// Code can only really handle integer strokeWidth. +	constexpr float strokeWidth = 1.0f;  	ColourDesired colourHead = back;  	ColourDesired colourBody = back; @@ -138,10 +168,156 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, const Font *fontFor  		colourTail = backSelected;  		break;  	default: -		// FoldPart::undefined +		// LineMarker::undefined  		break;  	} +	const int pixelDivisions = surface->PixelDivisions(); + +	// Folding symbols should have equal height and width to be either a circle or square. +	// So find the minimum of width and height. +	const XYPOSITION minDimension = std::floor(std::min(rcWhole.Width(), rcWhole.Height() - 2)) - 1; + +	// If strokeWidth would take up too much of area reduce to reasonable width. +	const XYPOSITION widthStroke = PixelAlignFloor(std::min(strokeWidth, minDimension / 5.0f), pixelDivisions); + +	// To centre +/-, odd strokeWidth -> odd symbol width, even -> even +	const XYPOSITION widthSymbol = +		((std::lround(minDimension * pixelDivisions) % 2) == (std::lround(widthStroke * pixelDivisions) % 2)) ? +		minDimension : minDimension - 1.0f / pixelDivisions; + +	const Point centre = PixelAlign(rcWhole.Centre(), pixelDivisions); + +	// Folder symbols and lines follow some rules to join up, fit the pixel grid, +	// and avoid over-painting. + +	const XYPOSITION halfSymbol = std::round(widthSymbol / 2); +	const Point topLeft(centre.x - halfSymbol, centre.y - halfSymbol); +	const PRectangle rcSymbol( +		topLeft.x, topLeft.y, +		topLeft.x + widthSymbol, topLeft.y + widthSymbol); +	const XYPOSITION leftLine = rcSymbol.Centre().x - widthStroke / 2.0f; +	const XYPOSITION rightLine = leftLine + widthStroke; + +	// This is the vertical line through the whole area which is subdivided +	// when there is a symbol on the line or the colour changes for highlighting. +	const PRectangle rcVLine(leftLine, rcWhole.top, rightLine, rcWhole.bottom); + +	// Portions of rcVLine above and below the symbol. +	const PRectangle rcAboveSymbol = Clamp(rcVLine, Edge::bottom, rcSymbol.top); +	const PRectangle rcBelowSymbol = Clamp(rcVLine, Edge::top, rcSymbol.bottom); + +	// Projection to right. +	const PRectangle rcStick( +		rcVLine.right, centre.y + 1.0f - widthStroke, +		rcWhole.right - 1, centre.y + 1.0f); + +	switch (markType) { + +	case SC_MARK_VLINE: +		surface->FillRectangle(rcVLine, colourBody); +		break; + +	case SC_MARK_LCORNER: +		surface->FillRectangle(Clamp(rcVLine, Edge::bottom, centre.y + 1.0f), colourTail); +		surface->FillRectangle(rcStick, colourTail); +		break; + +	case SC_MARK_TCORNER: +		surface->FillRectangle(Clamp(rcVLine, Edge::bottom, centre.y + 1.0f), colourBody); +		surface->FillRectangle(Clamp(rcVLine, Edge::top, centre.y + 1.0f), colourHead); +		surface->FillRectangle(rcStick, colourTail); +		break; + +	// CORNERCURVE cases divide slightly lower than CORNER to accommodate the curve +	case SC_MARK_LCORNERCURVE: +		surface->FillRectangle(Clamp(rcVLine, Edge::bottom, centre.y), colourTail); +		DrawTail(surface, leftLine, rcWhole.right - 1.0f, centre.y - widthStroke, +			widthStroke, colourTail); +		break; + +	case SC_MARK_TCORNERCURVE: +		surface->FillRectangle(Clamp(rcVLine, Edge::bottom, centre.y), colourBody); +		surface->FillRectangle(Clamp(rcVLine, Edge::top, centre.y), colourHead); +		DrawTail(surface, leftLine, rcWhole.right - 1.0f, centre.y - widthStroke, +			widthStroke, colourTail); +		break; + +	case SC_MARK_BOXPLUS: +		DrawSymbol(surface, Shape::Square, Expansion::Plus, rcSymbol, widthStroke, +			fore, colourHead, colourHead, colourTail); +		break; + +	case SC_MARK_BOXPLUSCONNECTED: { +			const ColourDesired colourBelow = (part == FoldPart::headWithTail) ? colourTail : colourBody; +			surface->FillRectangle(rcBelowSymbol, colourBelow); +			surface->FillRectangle(rcAboveSymbol, colourBody); + +			const ColourDesired colourRight = (part == FoldPart::body) ? colourTail : colourHead; +			DrawSymbol(surface, Shape::Square, Expansion::Plus, rcSymbol, widthStroke, +				fore, colourHead, colourRight, colourTail); +		} +		break; + +	case SC_MARK_BOXMINUS: +		surface->FillRectangle(rcBelowSymbol, colourHead); +		DrawSymbol(surface, Shape::Square, Expansion::Minus, rcSymbol, widthStroke, +			fore, colourHead, colourHead, colourTail); +		break; + +	case SC_MARK_BOXMINUSCONNECTED: { +			surface->FillRectangle(rcBelowSymbol, colourHead); +			surface->FillRectangle(rcAboveSymbol, colourBody); + +			const ColourDesired colourRight = (part == FoldPart::body) ? colourTail : colourHead; +			DrawSymbol(surface, Shape::Square, Expansion::Minus, rcSymbol, widthStroke, +				fore, colourHead, colourRight, colourTail); +		} +		break; + +	case SC_MARK_CIRCLEPLUS: +		DrawSymbol(surface, Shape::Circle, Expansion::Plus, rcSymbol, widthStroke, +			fore, colourHead, colourHead, colourTail); +		break; + +	case SC_MARK_CIRCLEPLUSCONNECTED: { +			const ColourDesired colourBelow = (part == FoldPart::headWithTail) ? colourTail : colourBody; +			surface->FillRectangle(rcBelowSymbol, colourBelow); +			surface->FillRectangle(rcAboveSymbol, colourBody); + +			const ColourDesired colourRight = (part == FoldPart::body) ? colourTail : colourHead; +			DrawSymbol(surface, Shape::Circle, Expansion::Plus, rcSymbol, widthStroke, +				fore, colourHead, colourRight, colourTail); +		} +		break; + +	case SC_MARK_CIRCLEMINUS: +		surface->FillRectangle(rcBelowSymbol, colourHead); +		DrawSymbol(surface, Shape::Circle, Expansion::Minus, rcSymbol, widthStroke, +			fore, colourHead, colourHead, colourTail); +		break; + +	case SC_MARK_CIRCLEMINUSCONNECTED: { +			surface->FillRectangle(rcBelowSymbol, colourHead); +			surface->FillRectangle(rcAboveSymbol, colourBody); +			const ColourDesired colourRight = (part == FoldPart::body) ? colourTail : colourHead; +			DrawSymbol(surface, Shape::Circle, Expansion::Minus, rcSymbol, widthStroke, +				fore, colourHead, colourRight, colourTail); +		} +		break; + +	} +} + +void LineMarker::Draw(Surface *surface, const PRectangle &rcWhole, const Font *fontForCharacter, FoldPart part, int marginStyle) const { +	// This is to satisfy the changed API - eventually the stroke width will be exposed to clients +	constexpr float strokeWidth = 1.0f; + +	if (customDraw) { +		customDraw(surface, rcWhole, fontForCharacter, static_cast<int>(part), marginStyle, this); +		return; +	} +  	if ((markType == SC_MARK_PIXMAP) && (pxpm)) {  		pxpm->Draw(surface, rcWhole);  		return; @@ -157,20 +333,25 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, const Font *fontFor  		return;  	} -	const IntegerRectangle ircWhole(rcWhole); +	if ((markType >= SC_MARK_VLINE) && markType <= (SC_MARK_CIRCLEMINUSCONNECTED)) { +		DrawFoldingMark(surface, rcWhole, part); +		return; +	} +  	// Restrict most shapes a bit  	const PRectangle rc(rcWhole.left, rcWhole.top + 1, rcWhole.right, rcWhole.bottom - 1);  	// Ensure does not go beyond edge -	const int minDim = std::min(ircWhole.Width(), ircWhole.Height() - 2) - 1; -	int centreX = (ircWhole.right + ircWhole.left) / 2; -	const int centreY = (ircWhole.bottom + ircWhole.top) / 2; -	const int dimOn2 = minDim / 2; -	const int dimOn4 = minDim / 4; -	const int blobSize = dimOn2 - 1; -	const int armSize = dimOn2 - 2; +	const XYPOSITION minDim = std::min(rcWhole.Width(), rcWhole.Height() - 2) - 1; + +	const Point centre = rcWhole.Centre(); +	XYPOSITION centreX = std::floor(centre.x); +	const XYPOSITION centreY = std::floor(centre.y); +	const XYPOSITION dimOn2 = std::floor(minDim / 2); +	const XYPOSITION dimOn4 = std::floor(minDim / 4); +	const XYPOSITION armSize = dimOn2 - 2;  	if (marginStyle == SC_MARGIN_NUMBER || marginStyle == SC_MARGIN_TEXT || marginStyle == SC_MARGIN_RTEXT) {  		// On textual margins move marker to the left to try to avoid overlapping the text -		centreX = ircWhole.left + dimOn2 + 1; +		centreX = rcWhole.left + dimOn2 + 1;  	}  	switch (markType) { @@ -178,67 +359,67 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, const Font *fontFor  			PRectangle rcRounded = rc;  			rcRounded.left = rc.left + 1;  			rcRounded.right = rc.right - 1; -			surface->RoundedRectangle(rcRounded, fore, back); +			surface->RoundedRectangle(rcRounded, FillStroke(back, fore, strokeWidth));  		}  		break;  	case SC_MARK_CIRCLE: { -			const PRectangle rcCircle = PRectangle::FromInts( +			const PRectangle rcCircle = PRectangle(  							    centreX - dimOn2,  							    centreY - dimOn2,  							    centreX + dimOn2,  							    centreY + dimOn2); -			surface->Ellipse(rcCircle, fore, back); +			surface->Ellipse(rcCircle, FillStroke(back, fore, strokeWidth));  		}  		break;  	case SC_MARK_ARROW: {  			Point pts[] = { -				Point::FromInts(centreX - dimOn4, centreY - dimOn2), -				Point::FromInts(centreX - dimOn4, centreY + dimOn2), -				Point::FromInts(centreX + dimOn2 - dimOn4, centreY), +				Point(centreX - dimOn4, centreY - dimOn2), +				Point(centreX - dimOn4, centreY + dimOn2), +				Point(centreX + dimOn2 - dimOn4, centreY),  			}; -			surface->Polygon(pts, std::size(pts), fore, back); +			surface->Polygon(pts, std::size(pts), FillStroke(back, fore, strokeWidth));  		}  		break;  	case SC_MARK_ARROWDOWN: {  			Point pts[] = { -				Point::FromInts(centreX - dimOn2, centreY - dimOn4), -				Point::FromInts(centreX + dimOn2, centreY - dimOn4), -				Point::FromInts(centreX, centreY + dimOn2 - dimOn4), +				Point(centreX - dimOn2, centreY - dimOn4), +				Point(centreX + dimOn2, centreY - dimOn4), +				Point(centreX, centreY + dimOn2 - dimOn4),  			}; -			surface->Polygon(pts, std::size(pts), fore, back); +			surface->Polygon(pts, std::size(pts), FillStroke(back, fore, strokeWidth));  		}  		break;  	case SC_MARK_PLUS: {  			Point pts[] = { -				Point::FromInts(centreX - armSize, centreY - 1), -				Point::FromInts(centreX - 1, centreY - 1), -				Point::FromInts(centreX - 1, centreY - armSize), -				Point::FromInts(centreX + 1, centreY - armSize), -				Point::FromInts(centreX + 1, centreY - 1), -				Point::FromInts(centreX + armSize, centreY - 1), -				Point::FromInts(centreX + armSize, centreY + 1), -				Point::FromInts(centreX + 1, centreY + 1), -				Point::FromInts(centreX + 1, centreY + armSize), -				Point::FromInts(centreX - 1, centreY + armSize), -				Point::FromInts(centreX - 1, centreY + 1), -				Point::FromInts(centreX - armSize, centreY + 1), +				Point(centreX - armSize, centreY - 1), +				Point(centreX - 1, centreY - 1), +				Point(centreX - 1, centreY - armSize), +				Point(centreX + 1, centreY - armSize), +				Point(centreX + 1, centreY - 1), +				Point(centreX + armSize, centreY - 1), +				Point(centreX + armSize, centreY + 1), +				Point(centreX + 1, centreY + 1), +				Point(centreX + 1, centreY + armSize), +				Point(centreX - 1, centreY + armSize), +				Point(centreX - 1, centreY + 1), +				Point(centreX - armSize, centreY + 1),  			}; -			surface->Polygon(pts, std::size(pts), fore, back); +			surface->Polygon(pts, std::size(pts), FillStroke(back, fore, strokeWidth));  		}  		break;  	case SC_MARK_MINUS: {  			Point pts[] = { -				Point::FromInts(centreX - armSize, centreY - 1), -				Point::FromInts(centreX + armSize, centreY - 1), -				Point::FromInts(centreX + armSize, centreY + 1), -				Point::FromInts(centreX - armSize, centreY + 1), +				Point(centreX - armSize, centreY - 1), +				Point(centreX + armSize, centreY - 1), +				Point(centreX + armSize, centreY + 1), +				Point(centreX - armSize, centreY + 1),  			}; -			surface->Polygon(pts, std::size(pts), fore, back); +			surface->Polygon(pts, std::size(pts), FillStroke(back, fore, strokeWidth));  		}  		break; @@ -248,7 +429,7 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, const Font *fontFor  			rcSmall.top = rc.top + 2;  			rcSmall.right = rc.right - 1;  			rcSmall.bottom = rc.bottom - 2; -			surface->RectangleDraw(rcSmall, fore, back); +			surface->RectangleDraw(rcSmall, FillStroke(back, fore, strokeWidth));  		}  		break; @@ -259,177 +440,6 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, const Font *fontFor  		// An invisible marker so don't draw anything  		break; -	case SC_MARK_VLINE: { -			surface->PenColour(colourBody); -			surface->MoveTo(centreX, ircWhole.top); -			surface->LineTo(centreX, ircWhole.bottom); -		} -		break; - -	case SC_MARK_LCORNER: { -			surface->PenColour(colourTail); -			surface->MoveTo(centreX, ircWhole.top); -			surface->LineTo(centreX, centreY); -			surface->LineTo(ircWhole.right - 1, centreY); -		} -		break; - -	case SC_MARK_TCORNER: { -			surface->PenColour(colourTail); -			surface->MoveTo(centreX, centreY); -			surface->LineTo(ircWhole.right - 1, centreY); - -			surface->PenColour(colourBody); -			surface->MoveTo(centreX, ircWhole.top); -			surface->LineTo(centreX, centreY + 1); - -			surface->PenColour(colourHead); -			surface->LineTo(centreX, ircWhole.bottom); -		} -		break; - -	case SC_MARK_LCORNERCURVE: { -			surface->PenColour(colourTail); -			surface->MoveTo(centreX, ircWhole.top); -			surface->LineTo(centreX, centreY - 3); -			surface->LineTo(centreX + 3, centreY); -			surface->LineTo(ircWhole.right - 1, centreY); -		} -		break; - -	case SC_MARK_TCORNERCURVE: { -			surface->PenColour(colourTail); -			surface->MoveTo(centreX, centreY - 3); -			surface->LineTo(centreX + 3, centreY); -			surface->LineTo(ircWhole.right - 1, centreY); - -			surface->PenColour(colourBody); -			surface->MoveTo(centreX, ircWhole.top); -			surface->LineTo(centreX, centreY - 2); - -			surface->PenColour(colourHead); -			surface->LineTo(centreX, ircWhole.bottom); -		} -		break; - -	case SC_MARK_BOXPLUS: { -			DrawBox(surface, centreX, centreY, blobSize, fore, colourHead); -			DrawPlus(surface, centreX, centreY, blobSize, colourTail); -		} -		break; - -	case SC_MARK_BOXPLUSCONNECTED: { -			if (part == FoldPart::headWithTail) -				surface->PenColour(colourTail); -			else -				surface->PenColour(colourBody); -			surface->MoveTo(centreX, centreY + blobSize); -			surface->LineTo(centreX, ircWhole.bottom); - -			surface->PenColour(colourBody); -			surface->MoveTo(centreX, ircWhole.top); -			surface->LineTo(centreX, centreY - blobSize); - -			DrawBox(surface, centreX, centreY, blobSize, fore, colourHead); -			DrawPlus(surface, centreX, centreY, blobSize, colourTail); - -			if (part == FoldPart::body) { -				surface->PenColour(colourTail); -				surface->MoveTo(centreX + 1, centreY + blobSize); -				surface->LineTo(centreX + blobSize + 1, centreY + blobSize); - -				surface->MoveTo(centreX + blobSize, centreY + blobSize); -				surface->LineTo(centreX + blobSize, centreY - blobSize); - -				surface->MoveTo(centreX + 1, centreY - blobSize); -				surface->LineTo(centreX + blobSize + 1, centreY - blobSize); -			} -		} -		break; - -	case SC_MARK_BOXMINUS: { -			DrawBox(surface, centreX, centreY, blobSize, fore, colourHead); -			DrawMinus(surface, centreX, centreY, blobSize, colourTail); - -			surface->PenColour(colourHead); -			surface->MoveTo(centreX, centreY + blobSize); -			surface->LineTo(centreX, ircWhole.bottom); -		} -		break; - -	case SC_MARK_BOXMINUSCONNECTED: { -			DrawBox(surface, centreX, centreY, blobSize, fore, colourHead); -			DrawMinus(surface, centreX, centreY, blobSize, colourTail); - -			surface->PenColour(colourHead); -			surface->MoveTo(centreX, centreY + blobSize); -			surface->LineTo(centreX, ircWhole.bottom); - -			surface->PenColour(colourBody); -			surface->MoveTo(centreX, ircWhole.top); -			surface->LineTo(centreX, centreY - blobSize); - -			if (part == FoldPart::body) { -				surface->PenColour(colourTail); -				surface->MoveTo(centreX + 1, centreY + blobSize); -				surface->LineTo(centreX + blobSize + 1, centreY + blobSize); - -				surface->MoveTo(centreX + blobSize, centreY + blobSize); -				surface->LineTo(centreX + blobSize, centreY - blobSize); - -				surface->MoveTo(centreX + 1, centreY - blobSize); -				surface->LineTo(centreX + blobSize + 1, centreY - blobSize); -			} -		} -		break; - -	case SC_MARK_CIRCLEPLUS: { -			DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead); -			DrawPlus(surface, centreX, centreY, blobSize, colourTail); -		} -		break; - -	case SC_MARK_CIRCLEPLUSCONNECTED: { -			if (part == FoldPart::headWithTail) -				surface->PenColour(colourTail); -			else -				surface->PenColour(colourBody); -			surface->MoveTo(centreX, centreY + blobSize); -			surface->LineTo(centreX, ircWhole.bottom); - -			surface->PenColour(colourBody); -			surface->MoveTo(centreX, ircWhole.top); -			surface->LineTo(centreX, centreY - blobSize); - -			DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead); -			DrawPlus(surface, centreX, centreY, blobSize, colourTail); -		} -		break; - -	case SC_MARK_CIRCLEMINUS: { -			surface->PenColour(colourHead); -			surface->MoveTo(centreX, centreY + blobSize); -			surface->LineTo(centreX, ircWhole.bottom); - -			DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead); -			DrawMinus(surface, centreX, centreY, blobSize, colourTail); -		} -		break; - -	case SC_MARK_CIRCLEMINUSCONNECTED: { -			surface->PenColour(colourHead); -			surface->MoveTo(centreX, centreY + blobSize); -			surface->LineTo(centreX, ircWhole.bottom); - -			surface->PenColour(colourBody); -			surface->MoveTo(centreX, ircWhole.top); -			surface->LineTo(centreX, centreY - blobSize); - -			DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead); -			DrawMinus(surface, centreX, centreY, blobSize, colourTail); -		} -		break; -  	case SC_MARK_DOTDOTDOT: {  			XYPOSITION right = static_cast<XYPOSITION>(centreX - 6);  			for (int b = 0; b < 3; b++) { @@ -441,31 +451,33 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, const Font *fontFor  		break;  	case SC_MARK_ARROWS: { -			surface->PenColour(fore); -			int right = centreX - 2; -			const int armLength = dimOn2 - 1; +			XYPOSITION right = centreX - 4.0f + strokeWidth / 2.0f; +			const XYPOSITION midY = centreY + strokeWidth / 2.0f; +			const XYPOSITION armLength = std::round(dimOn2 - strokeWidth);  			for (int b = 0; b < 3; b++) { -				surface->MoveTo(right, centreY); -				surface->LineTo(right - armLength, centreY - armLength); -				surface->MoveTo(right, centreY); -				surface->LineTo(right - armLength, centreY + armLength); -				right += 4; +				const Point pts[] = { +					Point(right - armLength, midY - armLength), +					Point(right, midY), +					Point(right - armLength, midY + armLength) +				}; +				surface->PolyLine(pts, std::size(pts), Stroke(fore, strokeWidth)); +				right += strokeWidth + 3.0f;  			}  		}  		break;  	case SC_MARK_SHORTARROW: {  			Point pts[] = { -				Point::FromInts(centreX, centreY + dimOn2), -				Point::FromInts(centreX + dimOn2, centreY), -				Point::FromInts(centreX, centreY - dimOn2), -				Point::FromInts(centreX, centreY - dimOn4), -				Point::FromInts(centreX - dimOn4, centreY - dimOn4), -				Point::FromInts(centreX - dimOn4, centreY + dimOn4), -				Point::FromInts(centreX, centreY + dimOn4), -				Point::FromInts(centreX, centreY + dimOn2), +				Point(centreX, centreY + dimOn2), +				Point(centreX + dimOn2, centreY), +				Point(centreX, centreY - dimOn2), +				Point(centreX, centreY - dimOn4), +				Point(centreX - dimOn4, centreY - dimOn4), +				Point(centreX - dimOn4, centreY + dimOn4), +				Point(centreX, centreY + dimOn4), +				Point(centreX, centreY + dimOn2),  			}; -			surface->Polygon(pts, std::size(pts), fore, back); +			surface->Polygon(pts, std::size(pts), FillStroke(back, fore, strokeWidth));  		}  		break; @@ -481,28 +493,28 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, const Font *fontFor  		break;  	case SC_MARK_BOOKMARK: { -			const int halfHeight = minDim / 3; +			const XYPOSITION halfHeight = std::floor(minDim / 3);  			Point pts[] = { -				Point::FromInts(ircWhole.left, centreY - halfHeight), -				Point::FromInts(ircWhole.right - 3, centreY - halfHeight), -				Point::FromInts(ircWhole.right - 3 - halfHeight, centreY), -				Point::FromInts(ircWhole.right - 3, centreY + halfHeight), -				Point::FromInts(ircWhole.left, centreY + halfHeight), +				Point(rcWhole.left, centreY - halfHeight), +				Point(rcWhole.right - 3, centreY - halfHeight), +				Point(rcWhole.right - 3 - halfHeight, centreY), +				Point(rcWhole.right - 3, centreY + halfHeight), +				Point(rcWhole.left, centreY + halfHeight),  			}; -			surface->Polygon(pts, std::size(pts), fore, back); +			surface->Polygon(pts, std::size(pts), FillStroke(back, fore, strokeWidth));  		}  		break;  	case SC_MARK_VERTICALBOOKMARK: { -			const int halfWidth = minDim / 3; +			const XYPOSITION halfWidth = std::floor(minDim / 3);  			Point pts[] = { -				Point::FromInts(centreX - halfWidth, centreY - dimOn2), -				Point::FromInts(centreX + halfWidth, centreY - dimOn2), -				Point::FromInts(centreX + halfWidth, centreY + dimOn2), -				Point::FromInts(centreX, centreY + dimOn2 - halfWidth), -				Point::FromInts(centreX - halfWidth, centreY + dimOn2), +				Point(centreX - halfWidth, centreY - dimOn2), +				Point(centreX + halfWidth, centreY - dimOn2), +				Point(centreX + halfWidth, centreY + dimOn2), +				Point(centreX, centreY + dimOn2 - halfWidth), +				Point(centreX - halfWidth, centreY + dimOn2),  			}; -			surface->Polygon(pts, std::size(pts), fore, back); +			surface->Polygon(pts, std::size(pts), FillStroke(back, fore, strokeWidth));  		}  		break; | 
