aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gtk/ScintillaGTK.cxx51
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;