diff options
-rw-r--r-- | cocoa/ScintillaCocoa.h | 3 | ||||
-rw-r--r-- | cocoa/ScintillaCocoa.mm | 51 | ||||
-rw-r--r-- | cocoa/ScintillaView.mm | 31 | ||||
-rw-r--r-- | src/Editor.cxx | 20 | ||||
-rw-r--r-- | src/Editor.h | 2 |
5 files changed, 104 insertions, 3 deletions
diff --git a/cocoa/ScintillaCocoa.h b/cocoa/ScintillaCocoa.h index 9098d2000..415094c35 100644 --- a/cocoa/ScintillaCocoa.h +++ b/cocoa/ScintillaCocoa.h @@ -113,8 +113,10 @@ private: protected: Point GetVisibleOriginInMain(); PRectangle GetClientRectangle(); + virtual PRectangle GetClientDrawingRectangle(); Point ConvertPoint(NSPoint point); virtual void RedrawRect(PRectangle rc); + virtual void DiscardOverdraw(); virtual void Redraw(); virtual void Initialise(); @@ -144,6 +146,7 @@ public: bool SetIdle(bool on); void SetMouseCapture(bool on); bool HaveMouseCapture(); + void WillDraw(NSRect rect); void ScrollText(int linesToMove); void SetVerticalScrollPos(); void SetHorizontalScrollPos(); diff --git a/cocoa/ScintillaCocoa.mm b/cocoa/ScintillaCocoa.mm index f9e67f7b4..c5f24fcd6 100644 --- a/cocoa/ScintillaCocoa.mm +++ b/cocoa/ScintillaCocoa.mm @@ -714,6 +714,22 @@ PRectangle ScintillaCocoa::GetClientRectangle() //-------------------------------------------------------------------------------------------------- /** + * Allow for prepared rectangle + */ +PRectangle ScintillaCocoa::GetClientDrawingRectangle() { + SCIContentView *content = ContentView(); + if ([content respondsToSelector: @selector(setPreparedContentRect:)]) { + NSRect rcPrepared = [content preparedContentRect]; + if (!NSIsEmptyRect(rcPrepared)) + return PRectangle(rcPrepared.origin.x, rcPrepared.origin.y, + rcPrepared.origin.x+rcPrepared.size.width, rcPrepared.origin.y + rcPrepared.size.height); + } + return ScintillaCocoa::GetClientRectangle(); +} + +//-------------------------------------------------------------------------------------------------- + +/** * Converts the given point from base coordinates to local coordinates and at the same time into * a native Point structure. Base coordinates are used for the top window used in the view hierarchy. * Returned value is in view coordinates. @@ -739,12 +755,24 @@ void ScintillaCocoa::RedrawRect(PRectangle rc) //-------------------------------------------------------------------------------------------------- +void ScintillaCocoa::DiscardOverdraw() +{ + // If running on 10.9, reset prepared area to visible area + SCIContentView *content = ContentView(); + if ([content respondsToSelector: @selector(setPreparedContentRect:)]) { + content.preparedContentRect = [content visibleRect]; + } +} + +//-------------------------------------------------------------------------------------------------- + /** * Ensure all of prepared content is also redrawn. */ void ScintillaCocoa::Redraw() { wMargin.InvalidateAll(); + DiscardOverdraw(); wMain.InvalidateAll(); } @@ -1563,6 +1591,29 @@ void ScintillaCocoa::PaintMargin(NSRect aRect) //-------------------------------------------------------------------------------------------------- /** + * Prepare for drawing. + * + * @param rect The area that will be drawn, given in the sender's coordinate system. + */ +void ScintillaCocoa::WillDraw(NSRect rect) +{ + RefreshStyleData(); + PRectangle rcWillDraw = NSRectToPRectangle(rect); + int positionAfterRect = PositionAfterArea(rcWillDraw); + pdoc->EnsureStyledTo(positionAfterRect); + NotifyUpdateUI(); + if (WrapLines(wsVisible)) { + // Wrap may have reduced number of lines so more lines may need to be styled + positionAfterRect = PositionAfterArea(rcWillDraw); + pdoc->EnsureStyledTo(positionAfterRect); + // The wrapping process has changed the height of some lines so redraw all. + Redraw(); + } +} + +//-------------------------------------------------------------------------------------------------- + +/** * ScrollText is empty because scrolling is handled by the NSScrollView. */ void ScintillaCocoa::ScrollText(int linesToMove) diff --git a/cocoa/ScintillaView.mm b/cocoa/ScintillaView.mm index 7769d87ef..222fcdc8f 100644 --- a/cocoa/ScintillaView.mm +++ b/cocoa/ScintillaView.mm @@ -228,6 +228,37 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) //-------------------------------------------------------------------------------------------------- /** + * Called before repainting. + */ +- (void) viewWillDraw +{ + const NSRect *rects; + NSInteger nRects = 0; + [self getRectsBeingDrawn:&rects count:&nRects]; + if (nRects > 0) { + NSRect rectUnion = rects[0]; + for (int i=0;i<nRects;i++) { + rectUnion = NSUnionRect(rectUnion, rects[i]); + } + mOwner.backend->WillDraw(rectUnion); + } + [super viewWillDraw]; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Called before responsive scrolling overdraw. + */ +- (void) prepareContentInRect: (NSRect) rect +{ + mOwner.backend->WillDraw(rect); + [super prepareContentInRect: rect]; +} + +//-------------------------------------------------------------------------------------------------- + +/** * Gets called by the runtime when the view needs repainting. */ - (void) drawRect: (NSRect) rect diff --git a/src/Editor.cxx b/src/Editor.cxx index 6c29e7100..6381f7eab 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -386,6 +386,10 @@ PRectangle Editor::GetClientRectangle() { return wMain.GetClientPosition(); } +PRectangle Editor::GetClientDrawingRectangle() { + return GetClientRectangle(); +} + PRectangle Editor::GetTextRectangle() { PRectangle rc = GetClientRectangle(); rc.left += vs.textStart; @@ -649,6 +653,10 @@ void Editor::RedrawRect(PRectangle rc) { } } +void Editor::DiscardOverdraw() { + // Overridden on platforms that may draw outside visible area. +} + void Editor::Redraw() { //Platform::DebugPrintf("Redraw all\n"); PRectangle rcClient = GetClientRectangle(); @@ -659,7 +667,10 @@ void Editor::Redraw() { } void Editor::RedrawSelMargin(int line, bool allAfter) { - if (!AbandonPaint()) { + bool abandonDraw = false; + if (!wMargin.GetID()) // Margin in main window so may need to abandon and retry + abandonDraw = AbandonPaint(); + if (!abandonDraw) { if (vs.maskInLine) { Redraw(); } else { @@ -6780,7 +6791,7 @@ int Editor::PositionAfterArea(PRectangle rcArea) const { // The start of the document line after the display line after the area // This often means that the line after a modification is restyled which helps // detect multiline comment additions and heals single line comments - int lineAfter = topLine + (rcArea.bottom - 1) / vs.lineHeight + 1; + int lineAfter = TopLineOfMain() + (rcArea.bottom - 1) / vs.lineHeight + 1; if (lineAfter < cs.LinesDisplayed()) return pdoc->LineStart(cs.DocFromDisplay(lineAfter) + 1); else @@ -6790,7 +6801,7 @@ int Editor::PositionAfterArea(PRectangle rcArea) const { // Style to a position within the view. If this causes a change at end of last line then // affects later lines so style all the viewed text. void Editor::StyleToPositionInView(Position pos) { - int endWindow = (vs.marginInside) ? (PositionAfterArea(GetClientRectangle())) : (pdoc->Length()); + int endWindow = PositionAfterArea(GetClientDrawingRectangle()); if (pos > endWindow) pos = endWindow; int styleAtEnd = pdoc->StyleAt(pos-1); @@ -6798,6 +6809,9 @@ void Editor::StyleToPositionInView(Position pos) { if ((endWindow > pos) && (styleAtEnd != pdoc->StyleAt(pos-1))) { // Style at end of line changed so is multi-line change like starting a comment // so require rest of window to be styled. + DiscardOverdraw(); // Prepared bitmaps may be invalid + // DiscardOverdraw may have truncated client drawing area so recalculate endWindow + endWindow = PositionAfterArea(GetClientDrawingRectangle()); pdoc->EnsureStyledTo(endWindow); } } diff --git a/src/Editor.h b/src/Editor.h index 588967d64..810175b58 100644 --- a/src/Editor.h +++ b/src/Editor.h @@ -338,6 +338,7 @@ protected: // ScintillaBase subclass needs access to much of Editor Point DocumentPointFromView(Point ptView); // Convert a point from view space to document int TopLineOfMain() const; // Return the line at Main's y coordinate 0 virtual PRectangle GetClientRectangle(); + virtual PRectangle GetClientDrawingRectangle(); PRectangle GetTextRectangle(); int LinesOnScreen(); @@ -357,6 +358,7 @@ protected: // ScintillaBase subclass needs access to much of Editor bool AbandonPaint(); virtual void RedrawRect(PRectangle rc); + virtual void DiscardOverdraw(); virtual void Redraw(); void RedrawSelMargin(int line=-1, bool allAfter=false); PRectangle RectangleFromRange(int start, int end); |