diff options
-rw-r--r-- | gtk/ScintillaGTK.cxx | 51 |
1 files changed, 42 insertions, 9 deletions
diff --git a/gtk/ScintillaGTK.cxx b/gtk/ScintillaGTK.cxx index 9a695a107..75740f283 100644 --- a/gtk/ScintillaGTK.cxx +++ b/gtk/ScintillaGTK.cxx @@ -160,7 +160,7 @@ class ScintillaGTK : public ScintillaBase { gint wheelMouseIntensity; #if GTK_CHECK_VERSION(3,0,0) - cairo_region_t *rgnUpdate; + cairo_rectangle_list_t *rgnUpdate; #else GdkRegion *rgnUpdate; #endif @@ -432,7 +432,7 @@ void ScintillaGTK::RealizeThis(GtkWidget *widget) { gtk_widget_set_window(widget, gdk_window_new(gtk_widget_get_parent_window(widget), &attrs, GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_CURSOR)); gdk_window_set_user_data(gtk_widget_get_window(widget), widget); - gdk_window_set_background(gtk_widget_get_window(widget), + gdk_window_set_background(gtk_widget_get_window(widget), &(gtk_widget_get_style(widget)->bg[GTK_STATE_NORMAL])); gdk_window_show(gtk_widget_get_window(widget)); gdk_cursor_unref(cursor); @@ -1028,18 +1028,39 @@ bool ScintillaGTK::HaveMouseCapture() { return capturedMouse; } +#if GTK_CHECK_VERSION(3,0,0) + +// Is crcTest completely in crcContainer? +static bool CRectContains(const cairo_rectangle_t &crcContainer, const cairo_rectangle_t &crcTest) { + return + (crcTest.x >= crcContainer.x) && ((crcTest.x + crcTest.width) <= (crcContainer.x + crcContainer.width)) && + (crcTest.y >= crcContainer.y) && ((crcTest.y + crcTest.height) <= (crcContainer.y + crcContainer.height)); +} + +// Is crcTest completely in crcListContainer? +// May incorrectly return false if complex shape +static bool CRectListContains(const cairo_rectangle_list_t *crcListContainer, const cairo_rectangle_t &crcTest) { + for (int r=0; r<crcListContainer->num_rectangles; r++) { + if (CRectContains(crcListContainer->rectangles[r], crcTest)) + return true; + } + return false; +} + +#endif + bool ScintillaGTK::PaintContains(PRectangle rc) { + // This allows optimization when a rectangle is completely in the update region. + // It is OK to return false when too difficult to determine as that just performs extra drawing bool contains = true; if (paintState == painting) { if (!rcPaint.Contains(rc)) { contains = false; } else if (rgnUpdate) { #if GTK_CHECK_VERSION(3,0,0) - cairo_rectangle_int_t grc = {rc.left, rc.top, + cairo_rectangle_t grc = {rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top}; - if (cairo_region_contains_rectangle(rgnUpdate, &grc) != CAIRO_REGION_OVERLAP_IN) { - contains = false; - } + contains = CRectListContains(rgnUpdate, grc); #else GdkRectangle grc = {rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top}; @@ -2372,8 +2393,20 @@ gboolean ScintillaGTK::DrawTextThis(cairo_t *cr) { rcPaint = GetClientRectangle(); PLATFORM_ASSERT(rgnUpdate == NULL); - // TODO: find the region being exposed - rgnUpdate = 0; + rgnUpdate = cairo_copy_clip_rectangle_list(cr); + if (rgnUpdate && rgnUpdate->status != CAIRO_STATUS_SUCCESS) { + // If not successful then ignore + fprintf(stderr, "DrawTextThis failed to copy update region %d [%d]\n", rgnUpdate->status, rgnUpdate->num_rectangles); + cairo_rectangle_list_destroy(rgnUpdate); + rgnUpdate = 0; + } + + double x1, y1, x2, y2; + cairo_clip_extents(cr, &x1, &y1, &x2, &y2); + rcPaint.left = x1; + rcPaint.top = y1; + rcPaint.right = x2; + rcPaint.bottom = y2; PRectangle rcClient = GetClientRectangle(); paintingAllText = rcPaint.Contains(rcClient); Surface *surfaceWindow = Surface::Allocate(); @@ -2390,7 +2423,7 @@ gboolean ScintillaGTK::DrawTextThis(cairo_t *cr) { paintState = notPainting; if (rgnUpdate) { - cairo_region_destroy(rgnUpdate); + cairo_rectangle_list_destroy(rgnUpdate); } rgnUpdate = 0; paintState = notPainting; |