void ScintillaBase::CallTipShow(Point pt, const char *defn) { ac.Cancel(); pt.y += vs.lineHeight; // If container knows about STYLE_CALLTIP then use it in place of the // STYLE_DEFAULT for the face name, size and character set. Also use it // for the foreground and background colour. int ctStyle = ct.UseStyleCallTip() ? STYLE_CALLTIP : STYLE_DEFAULT; if (ct.UseStyleCallTip()) { ct.SetForeBack(vs.styles[STYLE_CALLTIP].fore, vs.styles[STYLE_CALLTIP].back); } PRectangle rc = ct.CallTipStart(sel.MainCaret(), pt, defn, vs.styles[ctStyle].fontName, vs.styles[ctStyle].sizeZoomed, CodePage(), vs.styles[ctStyle].characterSet, wMain); // If the call-tip window would be out of the client // space, adjust so it displays above the text. PRectangle rcClient = GetClientRectangle(); if (rc.bottom > rcClient.bottom) { int offset = vs.lineHeight + rc.Height(); rc.top -= offset; rc.bottom -= offset; } // Now display the window. CreateCallTipWindow(rc); ct.wCallTip.SetPositionRelative(rc, wMain); ct.wCallTip.Show(); }
void SurfaceImpl::RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back) { PenColour(fore); BrushColour(back); QRect rect = QRect(rc.left, rc.top, rc.Width() - 1, rc.Height() - 1); GetPainter()->drawRect(rect); }
void SurfaceImpl::DrawXPM(PRectangle rc, const XPM *xpm) { Q_ASSERT(painter); XYPOSITION x, y; const QPixmap &qpm = xpm->Pixmap(); x = rc.left + (rc.Width() - qpm.width()) / 2.0; y = rc.top + (rc.Height() - qpm.height()) / 2.0; painter->drawPixmap(QPointF(x, y), qpm); }
void SurfaceImpl::DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) { Q_ASSERT(painter); int x, y; const QImage *qim = reinterpret_cast<const QImage *>(pixelsImage); x = rc.left + (rc.Width() - width) / 2; y = rc.top + (rc.Height() - height) / 2; painter->drawImage(x, y, *qim); }
void HandleMouseWheel(const PDMouseWheelEvent& wheelEvent) { int topLineNew = topLine; int lines; int xPos = xOffset; int pixels; if (wheelEvent.wheelAxis == PDWHEEL_AXIS_HORIZONTAL) { m_wheelHRotation += wheelEvent.rotation * (wheelEvent.columnsPerRotation * vs.spaceWidth); pixels = m_wheelHRotation / wheelEvent.wheelDelta; m_wheelHRotation -= pixels * wheelEvent.wheelDelta; if (pixels != 0) { xPos += pixels; PRectangle rcText = GetTextRectangle(); if (xPos > scrollWidth - (int)rcText.Width()) xPos = scrollWidth - (int)rcText.Width(); HorizontalScrollTo(xPos); } } else if (wheelEvent.keyFlags & PDKEY_CTRL) { if (wheelEvent.rotation > 0) KeyCommand(SCI_ZOOMIN); else KeyCommand(SCI_ZOOMOUT); } else { short delta = wheelEvent.wheelDelta; if (!delta) delta = 120; m_wheelVRotation += wheelEvent.rotation; lines = m_wheelVRotation / delta; m_wheelVRotation -= lines * delta; if (lines != 0) { bool isPageScroll = (wheelEvent.keyFlags & PDKEY_SHIFT); if (isPageScroll) lines = lines * LinesOnScreen(); // lines is either +1 or -1 else lines *= wheelEvent.linesPerRotation; topLineNew -= lines; ScrollTo(topLineNew); } } }
void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill, ColourDesired outline, int alphaOutline, int /*flags*/) { QColor qOutline = QColorFromCA(outline); qOutline.setAlpha(alphaOutline); GetPainter()->setPen(QPen(qOutline)); QColor qFill = QColorFromCA(fill); qFill.setAlpha(alphaFill); GetPainter()->setBrush(QBrush(qFill)); // A radius of 1 shows no curve so add 1 qreal radius = cornerSize+1; QRect rect(rc.left, rc.top, rc.Width() - 1, rc.Height() - 1); GetPainter()->drawRoundedRect(rect, radius, radius); }
void XPM::Draw(Surface *surface, PRectangle &rc) { if (!data || !codes || !colours || !lines) { return; } // Centre the pixmap int startY = rc.top + (rc.Height() - height) / 2; int startX = rc.left + (rc.Width() - width) / 2; for (int y=0;y<height;y++) { int prevCode = 0; int xStartRun = 0; for (int x=0; x<width; x++) { int code = lines[y+nColours+1][x]; if (code != prevCode) { FillRun(surface, prevCode, startX + xStartRun, startY + y, startX + x); xStartRun = x; prevCode = code; } } FillRun(surface, prevCode, startX + xStartRun, startY + y, startX + width); } }
void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) { //Platform::DebugPrintf("AutoComplete %s\n", list); ct.CallTipCancel(); if (ac.chooseSingle && (listType == 0)) { if (list && !strchr(list, ac.GetSeparator())) { const char *typeSep = strchr(list, ac.GetTypesep()); int lenInsert = typeSep ? static_cast<int>(typeSep-list) : static_cast<int>(strlen(list)); if (ac.ignoreCase) { // May need to convert the case before invocation, so remove lenEntered characters AutoCompleteInsert(sel.MainCaret() - lenEntered, lenEntered, list, lenInsert); } else { AutoCompleteInsert(sel.MainCaret(), 0, list + lenEntered, lenInsert - lenEntered); } ac.Cancel(); return; } } ac.Start(wMain, idAutoComplete, sel.MainCaret(), PointMainCaret(), lenEntered, vs.lineHeight, IsUnicodeMode(), technology); PRectangle rcClient = GetClientRectangle(); Point pt = LocationFromPosition(sel.MainCaret() - lenEntered); PRectangle rcPopupBounds = wMain.GetMonitorRect(pt); if (rcPopupBounds.Height() == 0) rcPopupBounds = rcClient; int heightLB = ac.heightLBDefault; int widthLB = ac.widthLBDefault; if (pt.x >= rcClient.right - widthLB) { HorizontalScrollTo(xOffset + pt.x - rcClient.right + widthLB); Redraw(); pt = PointMainCaret(); } if (wMargin.GetID()) { Point ptOrigin = GetVisibleOriginInMain(); pt.x += ptOrigin.x; pt.y += ptOrigin.y; } PRectangle rcac; rcac.left = pt.x - ac.lb->CaretFromEdge(); if (pt.y >= rcPopupBounds.bottom - heightLB && // Wont fit below. pt.y >= (rcPopupBounds.bottom + rcPopupBounds.top) / 2) { // and there is more room above. rcac.top = pt.y - heightLB; if (rcac.top < rcPopupBounds.top) { heightLB -= (rcPopupBounds.top - rcac.top); rcac.top = rcPopupBounds.top; } } else { rcac.top = pt.y + vs.lineHeight; } rcac.right = rcac.left + widthLB; rcac.bottom = Platform::Minimum(rcac.top + heightLB, rcPopupBounds.bottom); ac.lb->SetPositionRelative(rcac, wMain); ac.lb->SetFont(vs.styles[STYLE_DEFAULT].font); unsigned int aveCharWidth = vs.styles[STYLE_DEFAULT].aveCharWidth; ac.lb->SetAverageCharWidth(aveCharWidth); ac.lb->SetDoubleClickAction(AutoCompleteDoubleClick, this); ac.SetList(list ? list : ""); // Fiddle the position of the list so it is right next to the target and wide enough for all its strings PRectangle rcList = ac.lb->GetDesiredRect(); int heightAlloced = rcList.bottom - rcList.top; widthLB = Platform::Maximum(widthLB, rcList.right - rcList.left); if (maxListWidth != 0) widthLB = Platform::Minimum(widthLB, aveCharWidth*maxListWidth); // Make an allowance for large strings in list rcList.left = pt.x - ac.lb->CaretFromEdge(); rcList.right = rcList.left + widthLB; if (((pt.y + vs.lineHeight) >= (rcPopupBounds.bottom - heightAlloced)) && // Wont fit below. ((pt.y + vs.lineHeight / 2) >= (rcPopupBounds.bottom + rcPopupBounds.top) / 2)) { // and there is more room above. rcList.top = pt.y - heightAlloced; } else { rcList.top = pt.y + vs.lineHeight; } rcList.bottom = rcList.top + heightAlloced; ac.lb->SetPositionRelative(rcList, wMain); ac.Show(true); if (lenEntered != 0) { AutoCompleteMoveToCurrentWord(); } }
void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter, typeOfFold tFold) { ColourPair head = back; ColourPair body = back; ColourPair tail = back; switch (tFold) { case LineMarker::head : case LineMarker::headWithTail : head = backSelected; tail = backSelected; break; case LineMarker::body : head = backSelected; body = backSelected; break; case LineMarker::tail : body = backSelected; tail = backSelected; break; default : // LineMarker::undefined break; } if ((markType == SC_MARK_PIXMAP) && (pxpm)) { pxpm->Draw(surface, rcWhole); return; } if ((markType == SC_MARK_RGBAIMAGE) && (image)) { surface->DrawRGBAImage(rcWhole, image->GetWidth(), image->GetHeight(), image->Pixels()); return; } // Restrict most shapes a bit PRectangle rc = rcWhole; rc.top++; rc.bottom--; int minDim = Platform::Minimum(rc.Width(), rc.Height()); minDim--; // Ensure does not go beyond edge int centreX = (rc.right + rc.left) / 2; int centreY = (rc.bottom + rc.top) / 2; int dimOn2 = minDim / 2; int dimOn4 = minDim / 4; int blobSize = dimOn2-1; int armSize = dimOn2-2; if (rc.Width() > (rc.Height() * 2)) { // Wide column is line number so move to left to try to avoid overlapping number centreX = rc.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.allocated, back.allocated); } else if (markType == SC_MARK_CIRCLE) { PRectangle rcCircle; rcCircle.left = centreX - dimOn2; rcCircle.top = centreY - dimOn2; rcCircle.right = centreX + dimOn2; rcCircle.bottom = centreY + dimOn2; surface->Ellipse(rcCircle, fore.allocated, back.allocated); } else if (markType == SC_MARK_ARROW) { Point pts[] = { Point(centreX - dimOn4, centreY - dimOn2), Point(centreX - dimOn4, centreY + dimOn2), Point(centreX + dimOn2 - dimOn4, centreY), }; surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), fore.allocated, back.allocated); } else if (markType == SC_MARK_ARROWDOWN) { Point pts[] = { Point(centreX - dimOn2, centreY - dimOn4), Point(centreX + dimOn2, centreY - dimOn4), Point(centreX, centreY + dimOn2 - dimOn4), }; surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), fore.allocated, back.allocated); } else if (markType == SC_MARK_PLUS) { Point pts[] = { 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, sizeof(pts) / sizeof(pts[0]), fore.allocated, back.allocated); } else if (markType == SC_MARK_MINUS) { Point pts[] = { Point(centreX - armSize, centreY - 1), Point(centreX + armSize, centreY -1), Point(centreX + armSize, centreY +1), Point(centreX - armSize, centreY + 1), }; surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), fore.allocated, back.allocated); } 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.allocated, back.allocated); } 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(body.allocated); surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, rcWhole.bottom); } else if (markType == SC_MARK_LCORNER) { surface->PenColour(tail.allocated); surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, rc.top + dimOn2); surface->LineTo(rc.right - 2, rc.top + dimOn2); } else if (markType == SC_MARK_TCORNER) { surface->PenColour(tail.allocated); surface->MoveTo(centreX, rc.top + dimOn2); surface->LineTo(rc.right - 2, rc.top + dimOn2); surface->PenColour(body.allocated); surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, rc.top + dimOn2 + 1); surface->PenColour(head.allocated); surface->LineTo(centreX, rcWhole.bottom); } else if (markType == SC_MARK_LCORNERCURVE) { surface->PenColour(tail.allocated); surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, rc.top + dimOn2-3); surface->LineTo(centreX+3, rc.top + dimOn2); surface->LineTo(rc.right - 1, rc.top + dimOn2); } else if (markType == SC_MARK_TCORNERCURVE) { surface->PenColour(tail.allocated); surface->MoveTo(centreX, rc.top + dimOn2-3); surface->LineTo(centreX+3, rc.top + dimOn2); surface->LineTo(rc.right - 1, rc.top + dimOn2); surface->PenColour(body.allocated); surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, rc.top + dimOn2-2); surface->PenColour(head.allocated); surface->LineTo(centreX, rcWhole.bottom); } else if (markType == SC_MARK_BOXPLUS) { DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated); DrawPlus(surface, centreX, centreY, blobSize, tail.allocated); } else if (markType == SC_MARK_BOXPLUSCONNECTED) { if (tFold == LineMarker::headWithTail) surface->PenColour(tail.allocated); else surface->PenColour(body.allocated); surface->MoveTo(centreX, centreY + blobSize); surface->LineTo(centreX, rcWhole.bottom); surface->PenColour(body.allocated); surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, centreY - blobSize); DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated); DrawPlus(surface, centreX, centreY, blobSize, tail.allocated); if (tFold == LineMarker::body) { surface->PenColour(tail.allocated); 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.allocated, head.allocated); DrawMinus(surface, centreX, centreY, blobSize, tail.allocated); surface->PenColour(head.allocated); surface->MoveTo(centreX, centreY + blobSize); surface->LineTo(centreX, rcWhole.bottom); } else if (markType == SC_MARK_BOXMINUSCONNECTED) { DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated); DrawMinus(surface, centreX, centreY, blobSize, tail.allocated); surface->PenColour(head.allocated); surface->MoveTo(centreX, centreY + blobSize); surface->LineTo(centreX, rcWhole.bottom); surface->PenColour(body.allocated); surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, centreY - blobSize); if (tFold == LineMarker::body) { surface->PenColour(tail.allocated); 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.allocated, head.allocated); DrawPlus(surface, centreX, centreY, blobSize, tail.allocated); } else if (markType == SC_MARK_CIRCLEPLUSCONNECTED) { if (tFold == LineMarker::headWithTail) surface->PenColour(tail.allocated); else surface->PenColour(body.allocated); surface->MoveTo(centreX, centreY + blobSize); surface->LineTo(centreX, rcWhole.bottom); surface->PenColour(body.allocated); surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, centreY - blobSize); DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated); DrawPlus(surface, centreX, centreY, blobSize, tail.allocated); } else if (markType == SC_MARK_CIRCLEMINUS) { DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated); DrawMinus(surface, centreX, centreY, blobSize, tail.allocated); surface->PenColour(head.allocated); surface->MoveTo(centreX, centreY + blobSize); surface->LineTo(centreX, rcWhole.bottom); } else if (markType == SC_MARK_CIRCLEMINUSCONNECTED) { DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated); DrawMinus(surface, centreX, centreY, blobSize, tail.allocated); surface->PenColour(head.allocated); surface->MoveTo(centreX, centreY + blobSize); surface->LineTo(centreX, rcWhole.bottom); surface->PenColour(body.allocated); surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, centreY - blobSize); } else if (markType >= SC_MARK_CHARACTER) { char character[1]; character[0] = static_cast<char>(markType - SC_MARK_CHARACTER); int width = surface->WidthText(fontForCharacter, character, 1); rc.left += (rc.Width() - width) / 2; rc.right = rc.left + width; surface->DrawTextClipped(rc, fontForCharacter, rc.bottom - 2, character, 1, fore.allocated, back.allocated); } else if (markType == SC_MARK_DOTDOTDOT) { int right = centreX - 6; for (int b=0; b<3; b++) { PRectangle rcBlob(right, rc.bottom - 4, right + 2, rc.bottom-2); surface->FillRectangle(rcBlob, fore.allocated); right += 5; } } else if (markType == SC_MARK_ARROWS) { surface->PenColour(fore.allocated); int right = centreX - 2; for (int b=0; b<3; b++) { surface->MoveTo(right - 4, centreY - 4); surface->LineTo(right, centreY); surface->LineTo(right - 5, centreY + 5); right += 4; } } else if (markType == SC_MARK_SHORTARROW) { Point pts[] = { 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, sizeof(pts) / sizeof(pts[0]), fore.allocated, back.allocated); } else if (markType == SC_MARK_LEFTRECT) { PRectangle rcLeft = rcWhole; rcLeft.right = rcLeft.left + 4; surface->FillRectangle(rcLeft, back.allocated); } else { // SC_MARK_FULLRECT surface->FillRectangle(rcWhole, back.allocated); } }
void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine) { surface->PenColour(fore); int ymid = (rc.bottom + rc.top) / 2; if (style == INDIC_SQUIGGLE) { surface->MoveTo(rc.left, rc.top); int x = rc.left + 2; int y = 2; while (x < rc.right) { surface->LineTo(x, rc.top + y); x += 2; y = 2 - y; } surface->LineTo(rc.right, rc.top + y); // Finish the line } else if (style == INDIC_SQUIGGLELOW) { surface->MoveTo(rc.left, rc.top); int x = rc.left + 3; int y = 0; while (x < rc.right) { surface->LineTo(x-1, rc.top + y); y = 1 - y; surface->LineTo(x, rc.top + y); x += 3; } surface->LineTo(rc.right, rc.top + y); // Finish the line } else if (style == INDIC_TT) { surface->MoveTo(rc.left, ymid); int x = rc.left + 5; while (x < rc.right) { surface->LineTo(x, ymid); surface->MoveTo(x-3, ymid); surface->LineTo(x-3, ymid+2); x++; surface->MoveTo(x, ymid); x += 5; } surface->LineTo(rc.right, ymid); // Finish the line if (x - 3 <= rc.right) { surface->MoveTo(x-3, ymid); surface->LineTo(x-3, ymid+2); } } else if (style == INDIC_DIAGONAL) { int x = rc.left; while (x < rc.right) { surface->MoveTo(x, rc.top+2); int endX = x+3; int endY = rc.top - 1; if (endX > rc.right) { endY += endX - rc.right; endX = rc.right; } surface->LineTo(endX, endY); x += 4; } } else if (style == INDIC_STRIKE) { surface->MoveTo(rc.left, rc.top - 4); surface->LineTo(rc.right, rc.top - 4); } else if (style == INDIC_HIDDEN) { // Draw nothing } else if (style == INDIC_BOX) { surface->MoveTo(rc.left, ymid+1); surface->LineTo(rc.right, ymid+1); surface->LineTo(rc.right, rcLine.top+1); surface->LineTo(rc.left, rcLine.top+1); surface->LineTo(rc.left, ymid+1); } else if (style == INDIC_ROUNDBOX || style == INDIC_STRAIGHTBOX) { PRectangle rcBox = rcLine; rcBox.top = rcLine.top + 1; rcBox.left = rc.left; rcBox.right = rc.right; surface->AlphaRectangle(rcBox, (style == INDIC_ROUNDBOX) ? 1 : 0, fore, fillAlpha, fore, outlineAlpha, 0); } else if (style == INDIC_DOTBOX) { PRectangle rcBox = rcLine; rcBox.top = rcLine.top + 1; rcBox.left = rc.left; rcBox.right = rc.right; // Cap width at 4000 to avoid large allocations when mistakes made int width = Platform::Minimum(rcBox.Width(), 4000); RGBAImage image(width, rcBox.Height(), 0); // Draw horizontal lines top and bottom for (int x=0; x<width; x++) { for (int y=0; y<rcBox.Height(); y += rcBox.Height()-1) { image.SetPixel(x, y, fore, ((x + y) % 2) ? outlineAlpha : fillAlpha); } } // Draw vertical lines left and right for (int y=1; y<rcBox.Height(); y++) { for (int x=0; x<width; x += width-1) { image.SetPixel(x, y, fore, ((x + y) % 2) ? outlineAlpha : fillAlpha); } } surface->DrawRGBAImage(rcBox, image.GetWidth(), image.GetHeight(), image.Pixels()); } else if (style == INDIC_DASH) { int x = rc.left; while (x < rc.right) { surface->MoveTo(x, ymid); surface->LineTo(Platform::Minimum(x + 4, rc.right), ymid); x += 7; } } else if (style == INDIC_DOTS) { int x = rc.left; while (x < rc.right) { PRectangle rcDot(x, ymid, x+1, ymid+1); surface->FillRectangle(rcDot, fore); x += 2; } } else { // Either INDIC_PLAIN or unknown surface->MoveTo(rc.left, ymid); surface->LineTo(rc.right, ymid); } }
wxRect wxRectFromPRectangle(PRectangle prc) { wxRect r(prc.left, prc.top, prc.Width(), prc.Height()); return r; }
void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine, DrawState drawState, int value) const { StyleAndColour sacDraw = sacNormal; if (Flags() & SC_INDICFLAG_VALUEFORE) { sacDraw.fore = value & SC_INDICVALUEMASK; } if (drawState == drawHover) { sacDraw = sacHover; } surface->PenColour(sacDraw.fore); int ymid = static_cast<int>(rc.bottom + rc.top) / 2; if (sacDraw.style == INDIC_SQUIGGLE) { int x = int(rc.left+0.5); int xLast = int(rc.right+0.5); int y = 0; surface->MoveTo(x, static_cast<int>(rc.top) + y); while (x < xLast) { if ((x + 2) > xLast) { if (xLast > x) y = 1; x = xLast; } else { x += 2; y = 2 - y; } surface->LineTo(x, static_cast<int>(rc.top) + y); } } else if (sacDraw.style == INDIC_SQUIGGLEPIXMAP) { PRectangle rcSquiggle = PixelGridAlign(rc); int width = Platform::Minimum(4000, static_cast<int>(rcSquiggle.Width())); RGBAImage image(width, 3, 1.0, 0); enum { alphaFull = 0xff, alphaSide = 0x2f, alphaSide2=0x5f }; for (int x = 0; x < width; x++) { if (x%2) { // Two halfway columns have a full pixel in middle flanked by light pixels image.SetPixel(x, 0, sacDraw.fore, alphaSide); image.SetPixel(x, 1, sacDraw.fore, alphaFull); image.SetPixel(x, 2, sacDraw.fore, alphaSide); } else { // Extreme columns have a full pixel at bottom or top and a mid-tone pixel in centre image.SetPixel(x, (x % 4) ? 0 : 2, sacDraw.fore, alphaFull); image.SetPixel(x, 1, sacDraw.fore, alphaSide2); } } surface->DrawRGBAImage(rcSquiggle, image.GetWidth(), image.GetHeight(), image.Pixels()); } else if (sacDraw.style == INDIC_SQUIGGLELOW) { surface->MoveTo(static_cast<int>(rc.left), static_cast<int>(rc.top)); int x = static_cast<int>(rc.left) + 3; int y = 0; while (x < rc.right) { surface->LineTo(x - 1, static_cast<int>(rc.top) + y); y = 1 - y; surface->LineTo(x, static_cast<int>(rc.top) + y); x += 3; } surface->LineTo(static_cast<int>(rc.right), static_cast<int>(rc.top) + y); // Finish the line } else if (sacDraw.style == INDIC_TT) { surface->MoveTo(static_cast<int>(rc.left), ymid); int x = static_cast<int>(rc.left) + 5; while (x < rc.right) { surface->LineTo(x, ymid); surface->MoveTo(x-3, ymid); surface->LineTo(x-3, ymid+2); x++; surface->MoveTo(x, ymid); x += 5; } surface->LineTo(static_cast<int>(rc.right), ymid); // Finish the line if (x - 3 <= rc.right) { surface->MoveTo(x-3, ymid); surface->LineTo(x-3, ymid+2); } } else if (sacDraw.style == INDIC_DIAGONAL) { int x = static_cast<int>(rc.left); while (x < rc.right) { surface->MoveTo(x, static_cast<int>(rc.top) + 2); int endX = x+3; int endY = static_cast<int>(rc.top) - 1; if (endX > rc.right) { endY += endX - static_cast<int>(rc.right); endX = static_cast<int>(rc.right); } surface->LineTo(endX, endY); x += 4; } } else if (sacDraw.style == INDIC_STRIKE) { surface->MoveTo(static_cast<int>(rc.left), static_cast<int>(rc.top) - 4); surface->LineTo(static_cast<int>(rc.right), static_cast<int>(rc.top) - 4); } else if ((sacDraw.style == INDIC_HIDDEN) || (sacDraw.style == INDIC_TEXTFORE)) { // Draw nothing } else if (sacDraw.style == INDIC_BOX) { surface->MoveTo(static_cast<int>(rc.left), ymid + 1); surface->LineTo(static_cast<int>(rc.right), ymid + 1); surface->LineTo(static_cast<int>(rc.right), static_cast<int>(rcLine.top) + 1); surface->LineTo(static_cast<int>(rc.left), static_cast<int>(rcLine.top) + 1); surface->LineTo(static_cast<int>(rc.left), ymid + 1); } else if (sacDraw.style == INDIC_ROUNDBOX || sacDraw.style == INDIC_STRAIGHTBOX || sacDraw.style == INDIC_FULLBOX) { PRectangle rcBox = rcLine; if (sacDraw.style != INDIC_FULLBOX) rcBox.top = rcLine.top + 1; rcBox.left = rc.left; rcBox.right = rc.right; surface->AlphaRectangle(rcBox, (sacDraw.style == INDIC_ROUNDBOX) ? 1 : 0, sacDraw.fore, fillAlpha, sacDraw.fore, outlineAlpha, 0); } else if (sacDraw.style == INDIC_DOTBOX) { PRectangle rcBox = PixelGridAlign(rc); rcBox.top = rcLine.top + 1; rcBox.bottom = rcLine.bottom; // Cap width at 4000 to avoid large allocations when mistakes made int width = Platform::Minimum(static_cast<int>(rcBox.Width()), 4000); RGBAImage image(width, static_cast<int>(rcBox.Height()), 1.0, 0); // Draw horizontal lines top and bottom for (int x=0; x<width; x++) { for (int y = 0; y<static_cast<int>(rcBox.Height()); y += static_cast<int>(rcBox.Height()) - 1) { image.SetPixel(x, y, sacDraw.fore, ((x + y) % 2) ? outlineAlpha : fillAlpha); } } // Draw vertical lines left and right for (int y = 1; y<static_cast<int>(rcBox.Height()); y++) { for (int x=0; x<width; x += width-1) { image.SetPixel(x, y, sacDraw.fore, ((x + y) % 2) ? outlineAlpha : fillAlpha); } } surface->DrawRGBAImage(rcBox, image.GetWidth(), image.GetHeight(), image.Pixels()); } else if (sacDraw.style == INDIC_DASH) { int x = static_cast<int>(rc.left); while (x < rc.right) { surface->MoveTo(x, ymid); surface->LineTo(Platform::Minimum(x + 4, static_cast<int>(rc.right)), ymid); x += 7; } } else if (sacDraw.style == INDIC_DOTS) { int x = static_cast<int>(rc.left); while (x < static_cast<int>(rc.right)) { PRectangle rcDot = PRectangle::FromInts(x, ymid, x + 1, ymid + 1); surface->FillRectangle(rcDot, sacDraw.fore); x += 2; } } else if (sacDraw.style == INDIC_COMPOSITIONTHICK) { PRectangle rcComposition(rc.left+1, rcLine.bottom-2, rc.right-1, rcLine.bottom); surface->FillRectangle(rcComposition, sacDraw.fore); } else if (sacDraw.style == INDIC_COMPOSITIONTHIN) { PRectangle rcComposition(rc.left+1, rcLine.bottom-2, rc.right-1, rcLine.bottom-1); surface->FillRectangle(rcComposition, sacDraw.fore); } else { // Either INDIC_PLAIN or unknown surface->MoveTo(static_cast<int>(rc.left), ymid); surface->LineTo(static_cast<int>(rc.right), ymid); } }