in ext/scintilla/src/LineMarker.cxx [113:446]
void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter, typeOfFold tFold, int marginStyle) const {
if (customDraw) {
customDraw(surface, rcWhole, fontForCharacter, tFold, marginStyle, this);
return;
}
ColourDesired colourHead = back;
ColourDesired colourBody = back;
ColourDesired colourTail = back;
switch (tFold) {
case LineMarker::head :
case LineMarker::headWithTail :
colourHead = backSelected;
colourTail = backSelected;
break;
case LineMarker::body :
colourHead = backSelected;
colourBody = backSelected;
break;
case LineMarker::tail :
colourBody = backSelected;
colourTail = backSelected;
break;
default :
// LineMarker::undefined
break;
}
if ((markType == SC_MARK_PIXMAP) && (pxpm)) {
pxpm->Draw(surface, rcWhole);
return;
}
if ((markType == SC_MARK_RGBAIMAGE) && (image)) {
// Make rectangle just large enough to fit image centred on centre of rcWhole
PRectangle rcImage;
rcImage.top = ((rcWhole.top + rcWhole.bottom) - image->GetScaledHeight()) / 2;
rcImage.bottom = rcImage.top + image->GetScaledHeight();
rcImage.left = ((rcWhole.left + rcWhole.right) - image->GetScaledWidth()) / 2;
rcImage.right = rcImage.left + image->GetScaledWidth();
surface->DrawRGBAImage(rcImage, image->GetWidth(), image->GetHeight(), image->Pixels());
return;
}
const IntegerRectangle ircWhole(rcWhole);
// 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;
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;
}
if (markType == SC_MARK_ROUNDRECT) {
PRectangle rcRounded = rc;
rcRounded.left = rc.left + 1;
rcRounded.right = rc.right - 1;
surface->RoundedRectangle(rcRounded, fore, back);
} else if (markType == SC_MARK_CIRCLE) {
const PRectangle rcCircle = PRectangle::FromInts(
centreX - dimOn2,
centreY - dimOn2,
centreX + dimOn2,
centreY + dimOn2);
surface->Ellipse(rcCircle, fore, back);
} else if (markType == SC_MARK_ARROW) {
Point pts[] = {
Point::FromInts(centreX - dimOn4, centreY - dimOn2),
Point::FromInts(centreX - dimOn4, centreY + dimOn2),
Point::FromInts(centreX + dimOn2 - dimOn4, centreY),
};
surface->Polygon(pts, std::size(pts), fore, back);
} else if (markType == SC_MARK_ARROWDOWN) {
Point pts[] = {
Point::FromInts(centreX - dimOn2, centreY - dimOn4),
Point::FromInts(centreX + dimOn2, centreY - dimOn4),
Point::FromInts(centreX, centreY + dimOn2 - dimOn4),
};
surface->Polygon(pts, std::size(pts), fore, back);
} else if (markType == 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),
};
surface->Polygon(pts, std::size(pts), fore, back);
} else if (markType == 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),
};
surface->Polygon(pts, std::size(pts), fore, back);
} else if (markType == SC_MARK_SMALLRECT) {
PRectangle rcSmall;
rcSmall.left = rc.left + 1;
rcSmall.top = rc.top + 2;
rcSmall.right = rc.right - 1;
rcSmall.bottom = rc.bottom - 2;
surface->RectangleDraw(rcSmall, fore, back);
} else if (markType == SC_MARK_EMPTY || markType == SC_MARK_BACKGROUND ||
markType == SC_MARK_UNDERLINE || markType == SC_MARK_AVAILABLE) {
// An invisible marker so don't draw anything
} else if (markType == SC_MARK_VLINE) {
surface->PenColour(colourBody);
surface->MoveTo(centreX, ircWhole.top);
surface->LineTo(centreX, ircWhole.bottom);
} else if (markType == SC_MARK_LCORNER) {
surface->PenColour(colourTail);
surface->MoveTo(centreX, ircWhole.top);
surface->LineTo(centreX, centreY);
surface->LineTo(ircWhole.right - 1, centreY);
} else if (markType == 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);
} else if (markType == 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);
} else if (markType == 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);
} else if (markType == SC_MARK_BOXPLUS) {
DrawBox(surface, centreX, centreY, blobSize, fore, colourHead);
DrawPlus(surface, centreX, centreY, blobSize, colourTail);
} else if (markType == SC_MARK_BOXPLUSCONNECTED) {
if (tFold == LineMarker::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 (tFold == LineMarker::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);
}
} else if (markType == 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);
} else if (markType == 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 (tFold == LineMarker::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);
}
} else if (markType == SC_MARK_CIRCLEPLUS) {
DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead);
DrawPlus(surface, centreX, centreY, blobSize, colourTail);
} else if (markType == SC_MARK_CIRCLEPLUSCONNECTED) {
if (tFold == LineMarker::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);
} else if (markType == 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);
} else if (markType == 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);
} else if (markType >= SC_MARK_CHARACTER) {
std::string character(1, static_cast<char>(markType - SC_MARK_CHARACTER));
const XYPOSITION width = surface->WidthText(fontForCharacter, character);
PRectangle rcText = rc;
rcText.left += (rc.Width() - width) / 2;
rcText.right = rc.left + width;
surface->DrawTextClipped(rcText, fontForCharacter, rcText.bottom - 2,
character, fore, back);
} else if (markType == SC_MARK_DOTDOTDOT) {
XYPOSITION right = static_cast<XYPOSITION>(centreX - 6);
for (int b=0; b<3; b++) {
const PRectangle rcBlob(right, rc.bottom - 4, right + 2, rc.bottom-2);
surface->FillRectangle(rcBlob, fore);
right += 5.0f;
}
} else if (markType == SC_MARK_ARROWS) {
surface->PenColour(fore);
int right = centreX - 2;
const int armLength = dimOn2 - 1;
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;
}
} else if (markType == 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),
};
surface->Polygon(pts, std::size(pts), fore, back);
} else if (markType == SC_MARK_LEFTRECT) {
PRectangle rcLeft = rcWhole;
rcLeft.right = rcLeft.left + 4;
surface->FillRectangle(rcLeft, back);
} else if (markType == SC_MARK_BOOKMARK) {
const int halfHeight = 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),
};
surface->Polygon(pts, std::size(pts), fore, back);
} else if (markType == SC_MARK_VERTICALBOOKMARK) {
const int halfWidth = 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),
};
surface->Polygon(pts, std::size(pts), fore, back);
} else { // SC_MARK_FULLRECT
surface->FillRectangle(rcWhole, back);
}
}