more pen caching
authorClaus Gittinger <cg@exept.de>
Fri, 14 May 1999 23:36:54 +0200
changeset 2666 95aea895f5b1
parent 2665 4b88034ccb36
child 2667 f35e2d76acc3
more pen caching
WinWorkstat.st
WinWorkstation.st
--- a/WinWorkstat.st	Wed May 12 09:04:45 1999 +0200
+++ b/WinWorkstat.st	Fri May 14 23:36:54 1999 +0200
@@ -39,7 +39,7 @@
 #define CACHE_LAST_BRUSH                /* remember brush in gcData */
 #define CACHE_LAST_WM_PAINT_BRUSH       /* remember last viewBackground brush */
 #define CACHE_LAST_WM_PAINT_DC          /* remember last viewBackground paints dc */
-#define xxNUM_PEN_CACHED  5
+#define NUM_PEN_CACHED  8
 
 #undef INT
 #define INT WIN_INT
@@ -459,7 +459,7 @@
 #endif
 
 #ifdef NUM_PEN_CACHED
-struc __penCache {
+struct __penCache {
      HPEN           pen;
      int            clr;
 } __penCache[NUM_PEN_CACHED];
@@ -857,6 +857,34 @@
     return 1;
 }
 
+#ifdef NUM_PEN_CACHED
+
+static int
+_DeletePenIfNotInPenCache(p, lineNr)
+    HPEN p;
+{
+    int i, r;
+
+    for (i=0; i<NUM_PEN_CACHED;i++) { 
+	if (__penCache[i].pen == p) { 
+	    return 1; /* not deleted, but OK */
+	}
+    } 
+    if ((p == __whitePen)
+     || (p == __blackPen)) {
+	return 1; /* not deleted, but OK */
+    }
+    r = DeleteObject(p);
+
+    if (r == 0)
+	fprintf(stderr, "WinWorkstation: ERROR in DeletePen2 %x [%d]\n", p, lineNr);
+    return r;
+}
+
+#else
+# define _DeletePenIfNotInPenCache(p, lineNr)   _DeletePen(p, lineNr)
+#endif
+
 static struct gcData *
 newGcData() {
     struct gcData *gcData = (struct gcData *)malloc(sizeof(struct gcData));
@@ -888,22 +916,6 @@
 # define FLUSH_CACHED_DC(x)     /* */
 #endif
 
-#ifdef NUM_PEN_CACHED
-# define FLUSH_MULTIPEN_CACHE(__gcData__) \
-    {          \
-	int i; \
-	for (i=0; i<NUM_PEN_CACHED;i++) { \
-	    if (__penCache[i].gcData == __gcData__) { \
-		_DeleteObject(__penCache[i].pen, __LINE__); \
-		__penCache[i].pen = 0; \
-		break;  \
-	    } \
-	} \
-    }
-#else
-# define FLUSH_MULTIPEN_CACHE(__gcData__)  /* NOTHING */
-#endif
-
 #ifdef CACHE_LAST_PEN
 # define FLUSH_CACHED_PEN(__gcData__) \
     if (__gcData__->hPen) {           \
@@ -911,7 +923,7 @@
 	    SelectObject(__gcData__->_hDC, __gcData__->save_hPen); \
 	    __gcData__->save_hPen = 0;   \
 	} \
-	_DeletePen(__gcData__->hPen, __LINE__); \
+	_DeletePenIfNotInPenCache(__gcData__->hPen, __LINE__); \
 	__gcData__->hPen = 0; \
     }
 #else
@@ -963,7 +975,7 @@
 
 #ifdef CACHE_LAST_PEN
     if (gcData->hPen) {
-	_DeletePen(gcData->hPen, __LINE__);
+	_DeletePenIfNotInPenCache(gcData->hPen, __LINE__);
 	gcData->hPen = 0;
     }
 #endif
@@ -1160,16 +1172,35 @@
 #endif
 	    return __whitePen;
 	}
+
 #ifdef NUM_PEN_CACHED
-	for (i=0; i<NUM_PEN_CACHED; i++) {
-	    if (__penCache[i].clr == gcData->fgColor) {
-		hPen = __penCache[i].pen;
-		prevPen = SelectObject(hDC, hPen);
-		if (! gcData->save_hPen) {
-		    gcData->save_hPen = prevPen;
-		}
-		gcData->hPen = hPen;
-		return hPen;
+	{
+	    int i;
+
+	    for (i=0; i<NUM_PEN_CACHED; i++) {
+		if (__penCache[i].clr == gcData->fgColor) {
+		    hPen = __penCache[i].pen;
+		    /*
+		     * move it up in the cache
+		     */
+		    if (i > 0) {
+			HPEN t = __penCache[i-1].pen;
+			int c = __penCache[i-1].clr;
+
+			__penCache[i-1].pen = hPen;
+			__penCache[i-1].clr = gcData->fgColor;
+			__penCache[i].pen = t;
+			__penCache[i].clr = c;
+		    }
+#ifdef CACHE_LAST_PEN
+		    prevPen = SelectObject(hDC, hPen);
+		    if (! gcData->save_hPen) {
+			gcData->save_hPen = prevPen;
+		    }
+		    gcData->hPen = hPen;
+#endif
+		    return hPen;
+		}
 	    }
 	}
 #endif
@@ -1269,6 +1300,33 @@
 	gcData->save_hPen = prevPen;
     }
 
+#ifdef NUM_PEN_CACHED
+    /*
+     * remember in penCache
+     */
+    if (((gcData->lStyle & PS_STYLE_MASK) == PS_SOLID)
+     && (gcData->hMask == 0)
+     && (gcData->lineWidth <= 1)) {
+	int i;
+
+	for (i=0; i<NUM_PEN_CACHED; i++) {
+	    if (__penCache[i].pen == 0) {
+		__penCache[i].clr = gcData->fgColor;
+		__penCache[i].pen = hPen;
+		break;
+	    }
+	}
+	if (i == NUM_PEN_CACHED) {
+	    /* replace last in penCache */
+	    HPEN t = __penCache[NUM_PEN_CACHED - 1].pen;
+
+	    __penCache[NUM_PEN_CACHED - 1].pen = hPen;
+	    __penCache[NUM_PEN_CACHED - 1].clr = gcData->fgColor;
+	    _DeletePen(t, __LINE__);
+	}
+    }
+#endif
+
     return hPen;
 }
 
@@ -1287,7 +1345,7 @@
 	gcData->save_hPen = NULL;
     }
     hPen = gcData->hPen;
-    _DeletePen(hPen, __LINE__); 
+    _DeletePenIfNotInPenCache(hPen, __LINE__); 
     gcData->hPen = 0;
 }
 #endif /* CACHE_LAST_PEN */
@@ -11891,6 +11949,6 @@
 !WinWorkstation class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview/Attic/WinWorkstat.st,v 1.122 1999-05-12 07:04:45 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/Attic/WinWorkstat.st,v 1.123 1999-05-14 21:36:54 cg Exp $'
 ! !
 WinWorkstation initialize!
--- a/WinWorkstation.st	Wed May 12 09:04:45 1999 +0200
+++ b/WinWorkstation.st	Fri May 14 23:36:54 1999 +0200
@@ -39,7 +39,7 @@
 #define CACHE_LAST_BRUSH                /* remember brush in gcData */
 #define CACHE_LAST_WM_PAINT_BRUSH       /* remember last viewBackground brush */
 #define CACHE_LAST_WM_PAINT_DC          /* remember last viewBackground paints dc */
-#define xxNUM_PEN_CACHED  5
+#define NUM_PEN_CACHED  8
 
 #undef INT
 #define INT WIN_INT
@@ -459,7 +459,7 @@
 #endif
 
 #ifdef NUM_PEN_CACHED
-struc __penCache {
+struct __penCache {
      HPEN           pen;
      int            clr;
 } __penCache[NUM_PEN_CACHED];
@@ -857,6 +857,34 @@
     return 1;
 }
 
+#ifdef NUM_PEN_CACHED
+
+static int
+_DeletePenIfNotInPenCache(p, lineNr)
+    HPEN p;
+{
+    int i, r;
+
+    for (i=0; i<NUM_PEN_CACHED;i++) { 
+	if (__penCache[i].pen == p) { 
+	    return 1; /* not deleted, but OK */
+	}
+    } 
+    if ((p == __whitePen)
+     || (p == __blackPen)) {
+	return 1; /* not deleted, but OK */
+    }
+    r = DeleteObject(p);
+
+    if (r == 0)
+	fprintf(stderr, "WinWorkstation: ERROR in DeletePen2 %x [%d]\n", p, lineNr);
+    return r;
+}
+
+#else
+# define _DeletePenIfNotInPenCache(p, lineNr)   _DeletePen(p, lineNr)
+#endif
+
 static struct gcData *
 newGcData() {
     struct gcData *gcData = (struct gcData *)malloc(sizeof(struct gcData));
@@ -888,22 +916,6 @@
 # define FLUSH_CACHED_DC(x)     /* */
 #endif
 
-#ifdef NUM_PEN_CACHED
-# define FLUSH_MULTIPEN_CACHE(__gcData__) \
-    {          \
-	int i; \
-	for (i=0; i<NUM_PEN_CACHED;i++) { \
-	    if (__penCache[i].gcData == __gcData__) { \
-		_DeleteObject(__penCache[i].pen, __LINE__); \
-		__penCache[i].pen = 0; \
-		break;  \
-	    } \
-	} \
-    }
-#else
-# define FLUSH_MULTIPEN_CACHE(__gcData__)  /* NOTHING */
-#endif
-
 #ifdef CACHE_LAST_PEN
 # define FLUSH_CACHED_PEN(__gcData__) \
     if (__gcData__->hPen) {           \
@@ -911,7 +923,7 @@
 	    SelectObject(__gcData__->_hDC, __gcData__->save_hPen); \
 	    __gcData__->save_hPen = 0;   \
 	} \
-	_DeletePen(__gcData__->hPen, __LINE__); \
+	_DeletePenIfNotInPenCache(__gcData__->hPen, __LINE__); \
 	__gcData__->hPen = 0; \
     }
 #else
@@ -963,7 +975,7 @@
 
 #ifdef CACHE_LAST_PEN
     if (gcData->hPen) {
-	_DeletePen(gcData->hPen, __LINE__);
+	_DeletePenIfNotInPenCache(gcData->hPen, __LINE__);
 	gcData->hPen = 0;
     }
 #endif
@@ -1160,16 +1172,35 @@
 #endif
 	    return __whitePen;
 	}
+
 #ifdef NUM_PEN_CACHED
-	for (i=0; i<NUM_PEN_CACHED; i++) {
-	    if (__penCache[i].clr == gcData->fgColor) {
-		hPen = __penCache[i].pen;
-		prevPen = SelectObject(hDC, hPen);
-		if (! gcData->save_hPen) {
-		    gcData->save_hPen = prevPen;
-		}
-		gcData->hPen = hPen;
-		return hPen;
+	{
+	    int i;
+
+	    for (i=0; i<NUM_PEN_CACHED; i++) {
+		if (__penCache[i].clr == gcData->fgColor) {
+		    hPen = __penCache[i].pen;
+		    /*
+		     * move it up in the cache
+		     */
+		    if (i > 0) {
+			HPEN t = __penCache[i-1].pen;
+			int c = __penCache[i-1].clr;
+
+			__penCache[i-1].pen = hPen;
+			__penCache[i-1].clr = gcData->fgColor;
+			__penCache[i].pen = t;
+			__penCache[i].clr = c;
+		    }
+#ifdef CACHE_LAST_PEN
+		    prevPen = SelectObject(hDC, hPen);
+		    if (! gcData->save_hPen) {
+			gcData->save_hPen = prevPen;
+		    }
+		    gcData->hPen = hPen;
+#endif
+		    return hPen;
+		}
 	    }
 	}
 #endif
@@ -1269,6 +1300,33 @@
 	gcData->save_hPen = prevPen;
     }
 
+#ifdef NUM_PEN_CACHED
+    /*
+     * remember in penCache
+     */
+    if (((gcData->lStyle & PS_STYLE_MASK) == PS_SOLID)
+     && (gcData->hMask == 0)
+     && (gcData->lineWidth <= 1)) {
+	int i;
+
+	for (i=0; i<NUM_PEN_CACHED; i++) {
+	    if (__penCache[i].pen == 0) {
+		__penCache[i].clr = gcData->fgColor;
+		__penCache[i].pen = hPen;
+		break;
+	    }
+	}
+	if (i == NUM_PEN_CACHED) {
+	    /* replace last in penCache */
+	    HPEN t = __penCache[NUM_PEN_CACHED - 1].pen;
+
+	    __penCache[NUM_PEN_CACHED - 1].pen = hPen;
+	    __penCache[NUM_PEN_CACHED - 1].clr = gcData->fgColor;
+	    _DeletePen(t, __LINE__);
+	}
+    }
+#endif
+
     return hPen;
 }
 
@@ -1287,7 +1345,7 @@
 	gcData->save_hPen = NULL;
     }
     hPen = gcData->hPen;
-    _DeletePen(hPen, __LINE__); 
+    _DeletePenIfNotInPenCache(hPen, __LINE__); 
     gcData->hPen = 0;
 }
 #endif /* CACHE_LAST_PEN */
@@ -11891,6 +11949,6 @@
 !WinWorkstation class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview/WinWorkstation.st,v 1.122 1999-05-12 07:04:45 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/WinWorkstation.st,v 1.123 1999-05-14 21:36:54 cg Exp $'
 ! !
 WinWorkstation initialize!