more tuning (more caching)
authorClaus Gittinger <cg@exept.de>
Mon, 03 May 1999 14:46:31 +0200
changeset 2623 f35bd0833a59
parent 2622 c1f2727a424b
child 2624 cb390689e97f
more tuning (more caching)
WinWorkstat.st
WinWorkstation.st
--- a/WinWorkstat.st	Mon May 03 14:45:32 1999 +0200
+++ b/WinWorkstat.st	Mon May 03 14:46:31 1999 +0200
@@ -166,7 +166,8 @@
     short       clipW;
     short       clipH;
     short       clipping;
-    short       clipByChild;
+    char        clipByChildren;
+    char        bkMode;
     short       bitmapColorBitCount;
     short       maskOrgX;
     short       maskOrgY;
@@ -178,6 +179,7 @@
     COLORREF    fgColor;
     COLORREF    bgColor;
     HFONT       hFont;
+    HFONT       save_hFont;
     HPEN        hPen;
     HPEN        save_hPen;
     HBRUSH      hBrush;
@@ -319,6 +321,10 @@
 #define CAPTURE_IMPLICIT 7
 #define CAPTURE_EXPLICIT 8
 
+#define BK_UNDEF         0
+#define BK_TRANSPARENT   1
+#define BK_OPAQUE        2
+
 /*#define ControlMask            8
 #define ShiftMask              16*/
 #define LeftAltMask            Mod1Mask
@@ -759,7 +765,7 @@
     gcData->fgColor = 0xffffff;
     /* gcData->bgColor = 0; - not needed - memset does it */
     gcData->clipping = FALSE;
-    gcData->clipByChild = TRUE;
+    gcData->clipByChildren = TRUE;
     gcData->bitbltrop2 = BITBLT_COPY;
     gcData->lineWidth = 1;
     gcData->lStyle = PS_SOLID | PS_JOIN_MITER | PS_ENDCAP_FLAT;
@@ -831,6 +837,10 @@
 	SelectObject(hDC, gcData->save_hPen);
 	gcData->save_hPen = 0;
     }
+    if (gcData->save_hFont) {
+	SelectObject(hDC, gcData->save_hFont);
+	gcData->save_hFont = 0;
+    }
 
     if (gcData->hWnd) {
 	if (hDC) {
@@ -868,6 +878,8 @@
 _getDC(gcData)
     struct gcData *gcData;
 {
+    HDC hDC;
+
 #ifdef CACHE_LAST_DC
     int currThreadId = GetCurrentThreadId();
 
@@ -882,26 +894,34 @@
     }
 #endif
 
+    hDC = 0;
     if (gcData->hWnd != 0) {
 	if (__isWinNT && (gcData->hWnd == __rootWin)) {
-	    gcData->_hDC = GetDCEx(gcData->hWnd,0,DCX_WINDOW);
+	    hDC = gcData->_hDC = GetDCEx(gcData->hWnd, 0, DCX_WINDOW);
 	    //gcData->_hDC = GetDC(gcData->hWnd);
 	} else {
-	    if (gcData->clipByChild) {
-		//gcData->_hDC = GetDCEx(gcData->hWnd,0,DCX_CLIPCHILDREN);
-		gcData->_hDC = GetDC(gcData->hWnd);
+	    if (gcData->clipByChildren) {
+		//gcData->_hDC = GetDCEx(gcData->hWnd, 0, DCX_CLIPCHILDREN);
+		hDC = gcData->_hDC = GetDC(gcData->hWnd);
 	    } else
-		gcData->_hDC = GetDCEx(gcData->hWnd,0,DCX_PARENTCLIP);
+		hDC = gcData->_hDC = GetDCEx(gcData->hWnd, 0, DCX_PARENTCLIP);
 	}
     } else if (gcData->hBitmap) {
-	gcData->_hDC = CreateCompatibleDC(__tmpDC);
+	hDC = gcData->_hDC = CreateCompatibleDC(__tmpDC);
 	gcData->save_hBitmap = SelectObject(gcData->_hDC,gcData->hBitmap);
     }
-    if (gcData->_hDC) {
-	SetTextColor(gcData->_hDC, gcData->bgColor);
-	SetBkColor(gcData->_hDC, gcData->fgColor);
+    gcData->bkMode = BK_UNDEF;
+
+    if (hDC) {
+#if 0
+	SetTextColor(hDC, gcData->bgColor);
+	SetBkColor(hDC, gcData->fgColor);
+#else
+	SetTextColor(hDC, gcData->fgColor);
+	SetBkColor(hDC, gcData->bgColor);
+#endif
 	if (gcData->rop2) 
-	    SetROP2(gcData->_hDC, gcData->rop2);
+	    SetROP2(hDC, gcData->rop2);
 
 	if (gcData->clipping) {
 	    HRGN  region = CreateRectRgn( gcData->clipX, gcData->clipY,
@@ -910,19 +930,28 @@
 	    if (region == NULL ) {
 		DPRINTF((" clipping region creation failed!\n"));
 	    } else {
-		if (SelectClipRgn(gcData->_hDC, region) == ERROR ) {
+		if (SelectClipRgn(hDC, region) == ERROR ) {
 		    DPRINTF((" clipping region release unsuccessful\n" ));
 		}
 		/*printf("%x c\n",hDC);*/
 		_DeleteObject(region);
 	    }
 	}
+
+	if (gcData->hFont) {
+	    HFONT prevFont;
+
+	    prevFont = SelectObject(hDC, gcData->hFont);
+	    if (! gcData->save_hFont) {
+		gcData->save_hFont = prevFont;
+	    }
+	}
     }
 #ifdef CACHE_LAST_DC
     lastGcData = gcData;
     lastGcOwnerThreadID = currThreadId;
 #endif
-    return gcData->_hDC;
+    return hDC;
 }
 
 static HBRUSH
@@ -974,11 +1003,15 @@
      && (gcData->lineWidth <= 1)) {
 	if (gcData->fgColor == BlackPixel) {
 	    if (! __blackPen) {
+#if 0
 		Brush.lbStyle = BS_SOLID;
 		Brush.lbHatch = 0;
 		Brush.lbColor = BlackPixel;
 		__blackPen = ExtCreatePen(PS_GEOMETRIC | gcData->lStyle,
 					  1, &Brush, 0, 0);
+#else
+		__blackPen = GetStockObject(BLACK_PEN);
+#endif
 	    }
 #ifdef CACHE_LAST_PEN
 	    gcData->hPen = __blackPen;
@@ -987,11 +1020,15 @@
 	    return __blackPen;
 	} else if (gcData->fgColor == WhitePixel) {
 	    if (! __whitePen) {
+#if 0
 		Brush.lbStyle = BS_SOLID;
 		Brush.lbHatch = 0;
 		Brush.lbColor = WhitePixel;
 		__whitePen = ExtCreatePen(PS_GEOMETRIC | gcData->lStyle,
 					  1, &Brush, 0, 0);
+#else
+		__whitePen = GetStockObject(WHITE_PEN);
+#endif
 	    }
 #ifdef CACHE_LAST_PEN
 	    gcData->hPen = __whitePen;
@@ -1067,11 +1104,11 @@
 				gcData->lineWidth,
 				gcData->fgColor));
 
-	    //SetTextColor(hDC, gcData->fgColor);
 	    //
 	    // CG: wrong; must set to opaque, if doubleDashed
 	    //    
 	    SetBkMode(hDC, TRANSPARENT);
+	    gcData->bkMode = BK_TRANSPARENT;
 	}
     }
 
@@ -1095,7 +1132,9 @@
 	SelectObject(hDC, gcData->save_hPen);
 	gcData->save_hPen = NULL;
     }
-    _DeleteObject(hPen); 
+    if ((hPen != __blackPen) && (hPen != __whitePen)) {
+	_DeleteObject(hPen); 
+    }
     gcData->hPen = 0;
 }
 #endif /* CACHE_LAST_PEN */
@@ -6005,20 +6044,20 @@
 
 #if 0
 
-#ifdef DO_GEXPOSE
+# ifdef DO_GEXPOSE
 		UpdateWindow(srcGcData->hWnd);
-#endif
+# endif
 		ScrollWindow(srcGcData->hWnd,
 			    __intVal(dstX) - __intVal(srcX),
 			    __intVal(dstY) - __intVal(srcY),
 			    &rec, 0);
 
-#ifdef DO_GEXPOSE
-# ifdef OLD
+# ifdef DO_GEXPOSE
+#  ifdef OLD
 		UpdateWindow(srcGcData->hWnd);
 		if (GetWindow_eventMask(srcGcData->hWnd) & ExposureMask)
 		    enqEvent(ENQ_AT_END, ExposureMask,srcGcData->hWnd, __WM_NOGEXPOSE, 0, 0, 0, 0, 0);
-# else
+#  else
 		/* notice the reverse order ... */
 		if (GetWindow_eventMask(srcGcData->hWnd) & ExposureMask)
 		    enqEvent(ENQ_AT_FRONT, ExposureMask,srcGcData->hWnd, __WM_NOGEXPOSE, 0, 0, 0, 0, 0);
@@ -6030,10 +6069,10 @@
 			}
 		    }
 		}
+#  endif
+# else
+		UpdateWindow(srcGcData->hWnd);
 # endif
-#else
-		UpdateWindow(srcGcData->hWnd);
-#endif
 #endif /* 0 */
 
 		RETURN ( self );
@@ -6057,7 +6096,9 @@
 		rec.bottom = rec.top + __intVal(h);
 		srcDC = _getDC(srcGcData);
 		DPRINTF(("dst and src is DC %x fun == BITBLT_COPY  --> scrolling %d %d\n",srcDC,__intVal(dstX) - __intVal(srcX),__intVal(dstY) - __intVal(srcY)));
-		ScrollDC(srcDC,__intVal(dstX)-_srcX, __intVal(dstY)-_srcY, &rec, 0, 0, &uprec);
+		ScrollDC(srcDC, __intVal(dstX)-_srcX, 
+				__intVal(dstY)-_srcY, 
+				&rec, 0, 0, &uprec);
 #ifndef CACHE_LAST_DC
 		_releaseDC(srcGcData);
 #endif
@@ -6078,8 +6119,14 @@
 #endif
 	    if (dstGcData == srcGcData) {
 		srcDC = dstDC;
+		SetBkColor(srcDC, srcGcData->fgColor);
+		SetTextColor(srcDC, srcGcData->bgColor);
 	    } else {
 		srcDC = _getDC(srcGcData);
+		SetBkColor(srcDC, srcGcData->fgColor);
+		SetBkColor(dstDC, dstGcData->fgColor);
+		SetTextColor(srcDC, srcGcData->bgColor);
+		SetTextColor(dstDC, dstGcData->bgColor);
 	    }
 
 	    DDPRINTF(("bitblt src f:%x b:%x",GetTextColor(srcDC),GetBkColor(srcDC)));
@@ -6513,6 +6560,22 @@
 	pY = __intVal(y);
 	pY -= gcData->fontAscent;
 
+	if (opaque == true) {
+	    if (gcData->bkMode != BK_OPAQUE) {
+		SetBkMode(hDC, OPAQUE);
+		gcData->bkMode = BK_OPAQUE;
+	    }
+	} else {
+	    if (gcData->bkMode != BK_TRANSPARENT) {
+		SetBkMode(hDC, TRANSPARENT);
+		gcData->bkMode = BK_TRANSPARENT;
+	    }
+	}
+#if 0
+	hOldFont = SelectObject(hDC, gcData->hFont);
+	SetTextColor(hDC, gcData->fgColor);
+	SetBkColor(hDC, gcData->bgColor);
+#endif
 	cls = __qClass(aString);
 
 	i1 = __intVal(index1) - 1;
@@ -6530,19 +6593,10 @@
 		if (i2 < n) {
 		    cp += i1;
 		    DDPRINTF(("string1: %s pos=%d/%d l=%d hDC=%x hWnd=%x\n", cp, pX, pY,l,hDC,_HWNDVal(aDrawableId)));
-		    if (opaque == true) {
-			SetBkMode(hDC, OPAQUE);
-		    } else {
-			SetBkMode(hDC, TRANSPARENT);
-		    }
-		    hOldFont = SelectObject(hDC, gcData->hFont);
-		    SetTextColor(hDC, gcData->fgColor);
-		    SetBkColor(hDC, gcData->bgColor);
 
 		    if (!TextOut(hDC, pX, pY, (char *)cp, l)) {
 		       PRINTF(("Textout failed. %d\n", GetLastError()));
 		    }
-		    SelectObject(hDC, hOldFont);
 		    goto ret; 
 		}
 	    }
@@ -6556,16 +6610,9 @@
 		if (i2 < n) {
 		    cp += i1;
 		    DDPRINTF(("string: %s pos=%d/%d\n", cp, pX, pY));
-		    if (opaque == true) {
-			SetBkMode(hDC, OPAQUE);
-		    } else {
-			SetBkMode(hDC, TRANSPARENT);
+		    if (!TextOut(hDC, pX, pY, (char *)cp, l)) {
+		       PRINTF(("Textout failed. %d\n", GetLastError()));
 		    }
-		    hOldFont = SelectObject(hDC, gcData->hFont);
-		    SetTextColor(hDC, gcData->fgColor);
-		    SetBkColor(hDC, gcData->bgColor);
-		    TextOut(hDC, pX, pY, (char *)cp, l);
-		    SelectObject(hDC, hOldFont);
 		    goto ret; 
 		}
 	    }
@@ -6622,7 +6669,10 @@
 #endif
 	}
 ret:   
+#if 0
+	SelectObject(hDC, hOldFont);
 	_releaseDC(gcData); 
+#endif
     }
 #undef NLOCALBUFFER
 %}
@@ -8615,25 +8665,25 @@
 
 primEnumFontTypesInto:typeFaceList
 %{      /* xxLIMITEDSTACK (WIN95) */
-	if (__tmpDC) {
-	    if ( EnumFontFamilies( __tmpDC, NULL, EnumFPTypeFaceProc, (DWORD)&(typeFaceList))) {
-		DPRINTF(("EnumFonts successful\n"));
-	    }
-	}
+    if (__tmpDC) {
+	if ( EnumFontFamilies( __tmpDC, NULL, EnumFPTypeFaceProc, (DWORD)&(typeFaceList))) {
+	    DPRINTF(("EnumFonts successful\n"));
+	}
+    }
 %}
 !
 
 primEnumFontsIn:typeFace into:fontList
 %{      /* xxLIMITEDSTACK (WIN95) */
-	char *cp;
-
-	if (__isString(typeFace)) {
-	    if (__tmpDC) {
-		if (EnumFontFamilies(__tmpDC, __stringVal(typeFace), EnumFontsProc, (DWORD)&(fontList))) {
-		    DPRINTF(("EnumFonts Successful\n"));
-		}
-	    }
-	}
+    char *cp;
+
+    if (__isString(typeFace)) {
+	if (__tmpDC) {
+	    if (EnumFontFamilies(__tmpDC, __stringVal(typeFace), EnumFontsProc, (DWORD)&(fontList))) {
+		DPRINTF(("EnumFonts Successful\n"));
+	    }
+	}
+    }
 %}.
 !
 
@@ -8648,17 +8698,23 @@
 	HGDIOBJ hFont;
 	HGDIOBJ prevFont;
 	TEXTMETRIC tmet;
-	int len;
+	static char *s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+	static int len;
+
 	hFont = _HGDIOBJVal(fontId);
+
 	/*
 	 * temporarily set this font in the root context
 	 */
 	prevFont = SelectObject(__tmpDC, hFont);
 	GetTextMetrics(__tmpDC, &tmet);
-	GetTextExtentPoint32(__tmpDC,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrst"
-	 "uvwxyz",52,&size);
+	if (len == 0) {
+	    len = strlen(s);
+	}
+	GetTextExtentPoint32(__tmpDC, s, len, &size);
 	SelectObject(__tmpDC, prevFont);
-	avgWidth = (size.cx/26+1)/2;
+
+	avgWidth = (size.cx / (len / 2) + 1) / 2;
 
 	__ArrayInstPtr(data)->a_element[0] = __MKSMALLINT(tmet.tmAscent);
 	__ArrayInstPtr(data)->a_element[1] = __MKSMALLINT(tmet.tmDescent);
@@ -8833,7 +8889,7 @@
 	    ShowWindow(hWnd, SW_SHOWNOACTIVATE);
 	    //EnableWindow(hWnd,TRUE);
 	    SetWindowPos(hWnd, HWND_TOP,
-			 0, 0, 0, 0,SWP_NOREDRAW|SWP_NOSENDCHANGING|SWP_NOCOPYBITS
+			 0, 0, 0, 0, SWP_NOREDRAW|SWP_NOSENDCHANGING|SWP_NOCOPYBITS
 				    |SWP_NOACTIVATE |SWP_NOMOVE|SWP_NOSIZE);
 	    CPRINTF(("setRootCapture %x\n",hWnd));
 	}
@@ -8950,13 +9006,14 @@
 	struct gcData *gcData = _GCDATA(aGCId);
 
 	if (gcData && gcData->hWnd) {
-	    if ( aBool == true ) {
-		/* set clip by child */
-		gcData->clipByChild = TRUE;
-	    } else {
-		gcData->clipByChild = FALSE;
-	    }
-	    FLUSH_CACHED_DC(gcData);
+	    int newClip;
+
+	    newClip = (aBool == true) ? TRUE : FALSE;
+	    if (newClip != gcData->clipByChildren) {
+		/* set/clear clip by children */
+		gcData->clipByChildren = newClip;
+		FLUSH_CACHED_DC(gcData);
+	    }
 	} else {
 	    DPRINTF(("clipping by child failed - invalid win\n" ));
 	}
@@ -9028,30 +9085,39 @@
     {
 	struct gcData *gcData = _GCDATA(aGCId);
 	HDC hDC;
-	HGDIOBJ oldFont, hFont;
+	HGDIOBJ prevFont, hFont;
 	TEXTMETRIC tmet;
 
 	hDC = _getDC(gcData);
 
 	hFont = _HGDIOBJVal(aFontId);
-	oldFont = gcData->hFont;
-	if (oldFont != hFont) {
+	if (gcData->hFont != hFont) {
 	    gcData->hFont = hFont;
 
-	    hFont = SelectObject(hDC, hFont);
-	    GetTextMetrics(hDC, &tmet);
+	    prevFont = SelectObject(__tmpDC, hFont);
+	    GetTextMetrics(__tmpDC, &tmet);
 	    gcData->fontAscent = tmet.tmAscent;
-#ifdef DEBUG
+#ifdef SUPERDEBUG
 	    if (__debug__) {
 		char buf[80];
 
-		GetTextFace(hDC,80,buf);
-		PRINTF(("setFont: %x %s\n", hFont,buf));
-	    }
-#endif
-	    SelectObject(hDC, hFont);
+		GetTextFace(__tmpDC, 80, buf);
+		PRINTF(("setFont: %x %s\n", hFont, buf));
+	    }
+#endif
+	    SelectObject(__tmpDC, prevFont);
+
+#if 0
 	    _releaseDC(gcData);
 	    FLUSH_CACHED_DC(gcData);
+#else
+	    if (lastGcData == gcData) {
+		prevFont = SelectObject(gcData->_hDC, hFont);
+		if (! gcData->save_hFont) {
+		    gcData->save_hFont = prevFont;
+		}
+	    }
+#endif
 	    RETURN ( self );
 	}
     }
@@ -11250,6 +11316,6 @@
 !WinWorkstation class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview/Attic/WinWorkstat.st,v 1.105 1999-05-02 14:54:13 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/Attic/WinWorkstat.st,v 1.106 1999-05-03 12:46:31 cg Exp $'
 ! !
 WinWorkstation initialize!
--- a/WinWorkstation.st	Mon May 03 14:45:32 1999 +0200
+++ b/WinWorkstation.st	Mon May 03 14:46:31 1999 +0200
@@ -166,7 +166,8 @@
     short       clipW;
     short       clipH;
     short       clipping;
-    short       clipByChild;
+    char        clipByChildren;
+    char        bkMode;
     short       bitmapColorBitCount;
     short       maskOrgX;
     short       maskOrgY;
@@ -178,6 +179,7 @@
     COLORREF    fgColor;
     COLORREF    bgColor;
     HFONT       hFont;
+    HFONT       save_hFont;
     HPEN        hPen;
     HPEN        save_hPen;
     HBRUSH      hBrush;
@@ -319,6 +321,10 @@
 #define CAPTURE_IMPLICIT 7
 #define CAPTURE_EXPLICIT 8
 
+#define BK_UNDEF         0
+#define BK_TRANSPARENT   1
+#define BK_OPAQUE        2
+
 /*#define ControlMask            8
 #define ShiftMask              16*/
 #define LeftAltMask            Mod1Mask
@@ -759,7 +765,7 @@
     gcData->fgColor = 0xffffff;
     /* gcData->bgColor = 0; - not needed - memset does it */
     gcData->clipping = FALSE;
-    gcData->clipByChild = TRUE;
+    gcData->clipByChildren = TRUE;
     gcData->bitbltrop2 = BITBLT_COPY;
     gcData->lineWidth = 1;
     gcData->lStyle = PS_SOLID | PS_JOIN_MITER | PS_ENDCAP_FLAT;
@@ -831,6 +837,10 @@
 	SelectObject(hDC, gcData->save_hPen);
 	gcData->save_hPen = 0;
     }
+    if (gcData->save_hFont) {
+	SelectObject(hDC, gcData->save_hFont);
+	gcData->save_hFont = 0;
+    }
 
     if (gcData->hWnd) {
 	if (hDC) {
@@ -868,6 +878,8 @@
 _getDC(gcData)
     struct gcData *gcData;
 {
+    HDC hDC;
+
 #ifdef CACHE_LAST_DC
     int currThreadId = GetCurrentThreadId();
 
@@ -882,26 +894,34 @@
     }
 #endif
 
+    hDC = 0;
     if (gcData->hWnd != 0) {
 	if (__isWinNT && (gcData->hWnd == __rootWin)) {
-	    gcData->_hDC = GetDCEx(gcData->hWnd,0,DCX_WINDOW);
+	    hDC = gcData->_hDC = GetDCEx(gcData->hWnd, 0, DCX_WINDOW);
 	    //gcData->_hDC = GetDC(gcData->hWnd);
 	} else {
-	    if (gcData->clipByChild) {
-		//gcData->_hDC = GetDCEx(gcData->hWnd,0,DCX_CLIPCHILDREN);
-		gcData->_hDC = GetDC(gcData->hWnd);
+	    if (gcData->clipByChildren) {
+		//gcData->_hDC = GetDCEx(gcData->hWnd, 0, DCX_CLIPCHILDREN);
+		hDC = gcData->_hDC = GetDC(gcData->hWnd);
 	    } else
-		gcData->_hDC = GetDCEx(gcData->hWnd,0,DCX_PARENTCLIP);
+		hDC = gcData->_hDC = GetDCEx(gcData->hWnd, 0, DCX_PARENTCLIP);
 	}
     } else if (gcData->hBitmap) {
-	gcData->_hDC = CreateCompatibleDC(__tmpDC);
+	hDC = gcData->_hDC = CreateCompatibleDC(__tmpDC);
 	gcData->save_hBitmap = SelectObject(gcData->_hDC,gcData->hBitmap);
     }
-    if (gcData->_hDC) {
-	SetTextColor(gcData->_hDC, gcData->bgColor);
-	SetBkColor(gcData->_hDC, gcData->fgColor);
+    gcData->bkMode = BK_UNDEF;
+
+    if (hDC) {
+#if 0
+	SetTextColor(hDC, gcData->bgColor);
+	SetBkColor(hDC, gcData->fgColor);
+#else
+	SetTextColor(hDC, gcData->fgColor);
+	SetBkColor(hDC, gcData->bgColor);
+#endif
 	if (gcData->rop2) 
-	    SetROP2(gcData->_hDC, gcData->rop2);
+	    SetROP2(hDC, gcData->rop2);
 
 	if (gcData->clipping) {
 	    HRGN  region = CreateRectRgn( gcData->clipX, gcData->clipY,
@@ -910,19 +930,28 @@
 	    if (region == NULL ) {
 		DPRINTF((" clipping region creation failed!\n"));
 	    } else {
-		if (SelectClipRgn(gcData->_hDC, region) == ERROR ) {
+		if (SelectClipRgn(hDC, region) == ERROR ) {
 		    DPRINTF((" clipping region release unsuccessful\n" ));
 		}
 		/*printf("%x c\n",hDC);*/
 		_DeleteObject(region);
 	    }
 	}
+
+	if (gcData->hFont) {
+	    HFONT prevFont;
+
+	    prevFont = SelectObject(hDC, gcData->hFont);
+	    if (! gcData->save_hFont) {
+		gcData->save_hFont = prevFont;
+	    }
+	}
     }
 #ifdef CACHE_LAST_DC
     lastGcData = gcData;
     lastGcOwnerThreadID = currThreadId;
 #endif
-    return gcData->_hDC;
+    return hDC;
 }
 
 static HBRUSH
@@ -974,11 +1003,15 @@
      && (gcData->lineWidth <= 1)) {
 	if (gcData->fgColor == BlackPixel) {
 	    if (! __blackPen) {
+#if 0
 		Brush.lbStyle = BS_SOLID;
 		Brush.lbHatch = 0;
 		Brush.lbColor = BlackPixel;
 		__blackPen = ExtCreatePen(PS_GEOMETRIC | gcData->lStyle,
 					  1, &Brush, 0, 0);
+#else
+		__blackPen = GetStockObject(BLACK_PEN);
+#endif
 	    }
 #ifdef CACHE_LAST_PEN
 	    gcData->hPen = __blackPen;
@@ -987,11 +1020,15 @@
 	    return __blackPen;
 	} else if (gcData->fgColor == WhitePixel) {
 	    if (! __whitePen) {
+#if 0
 		Brush.lbStyle = BS_SOLID;
 		Brush.lbHatch = 0;
 		Brush.lbColor = WhitePixel;
 		__whitePen = ExtCreatePen(PS_GEOMETRIC | gcData->lStyle,
 					  1, &Brush, 0, 0);
+#else
+		__whitePen = GetStockObject(WHITE_PEN);
+#endif
 	    }
 #ifdef CACHE_LAST_PEN
 	    gcData->hPen = __whitePen;
@@ -1067,11 +1104,11 @@
 				gcData->lineWidth,
 				gcData->fgColor));
 
-	    //SetTextColor(hDC, gcData->fgColor);
 	    //
 	    // CG: wrong; must set to opaque, if doubleDashed
 	    //    
 	    SetBkMode(hDC, TRANSPARENT);
+	    gcData->bkMode = BK_TRANSPARENT;
 	}
     }
 
@@ -1095,7 +1132,9 @@
 	SelectObject(hDC, gcData->save_hPen);
 	gcData->save_hPen = NULL;
     }
-    _DeleteObject(hPen); 
+    if ((hPen != __blackPen) && (hPen != __whitePen)) {
+	_DeleteObject(hPen); 
+    }
     gcData->hPen = 0;
 }
 #endif /* CACHE_LAST_PEN */
@@ -6005,20 +6044,20 @@
 
 #if 0
 
-#ifdef DO_GEXPOSE
+# ifdef DO_GEXPOSE
 		UpdateWindow(srcGcData->hWnd);
-#endif
+# endif
 		ScrollWindow(srcGcData->hWnd,
 			    __intVal(dstX) - __intVal(srcX),
 			    __intVal(dstY) - __intVal(srcY),
 			    &rec, 0);
 
-#ifdef DO_GEXPOSE
-# ifdef OLD
+# ifdef DO_GEXPOSE
+#  ifdef OLD
 		UpdateWindow(srcGcData->hWnd);
 		if (GetWindow_eventMask(srcGcData->hWnd) & ExposureMask)
 		    enqEvent(ENQ_AT_END, ExposureMask,srcGcData->hWnd, __WM_NOGEXPOSE, 0, 0, 0, 0, 0);
-# else
+#  else
 		/* notice the reverse order ... */
 		if (GetWindow_eventMask(srcGcData->hWnd) & ExposureMask)
 		    enqEvent(ENQ_AT_FRONT, ExposureMask,srcGcData->hWnd, __WM_NOGEXPOSE, 0, 0, 0, 0, 0);
@@ -6030,10 +6069,10 @@
 			}
 		    }
 		}
+#  endif
+# else
+		UpdateWindow(srcGcData->hWnd);
 # endif
-#else
-		UpdateWindow(srcGcData->hWnd);
-#endif
 #endif /* 0 */
 
 		RETURN ( self );
@@ -6057,7 +6096,9 @@
 		rec.bottom = rec.top + __intVal(h);
 		srcDC = _getDC(srcGcData);
 		DPRINTF(("dst and src is DC %x fun == BITBLT_COPY  --> scrolling %d %d\n",srcDC,__intVal(dstX) - __intVal(srcX),__intVal(dstY) - __intVal(srcY)));
-		ScrollDC(srcDC,__intVal(dstX)-_srcX, __intVal(dstY)-_srcY, &rec, 0, 0, &uprec);
+		ScrollDC(srcDC, __intVal(dstX)-_srcX, 
+				__intVal(dstY)-_srcY, 
+				&rec, 0, 0, &uprec);
 #ifndef CACHE_LAST_DC
 		_releaseDC(srcGcData);
 #endif
@@ -6078,8 +6119,14 @@
 #endif
 	    if (dstGcData == srcGcData) {
 		srcDC = dstDC;
+		SetBkColor(srcDC, srcGcData->fgColor);
+		SetTextColor(srcDC, srcGcData->bgColor);
 	    } else {
 		srcDC = _getDC(srcGcData);
+		SetBkColor(srcDC, srcGcData->fgColor);
+		SetBkColor(dstDC, dstGcData->fgColor);
+		SetTextColor(srcDC, srcGcData->bgColor);
+		SetTextColor(dstDC, dstGcData->bgColor);
 	    }
 
 	    DDPRINTF(("bitblt src f:%x b:%x",GetTextColor(srcDC),GetBkColor(srcDC)));
@@ -6513,6 +6560,22 @@
 	pY = __intVal(y);
 	pY -= gcData->fontAscent;
 
+	if (opaque == true) {
+	    if (gcData->bkMode != BK_OPAQUE) {
+		SetBkMode(hDC, OPAQUE);
+		gcData->bkMode = BK_OPAQUE;
+	    }
+	} else {
+	    if (gcData->bkMode != BK_TRANSPARENT) {
+		SetBkMode(hDC, TRANSPARENT);
+		gcData->bkMode = BK_TRANSPARENT;
+	    }
+	}
+#if 0
+	hOldFont = SelectObject(hDC, gcData->hFont);
+	SetTextColor(hDC, gcData->fgColor);
+	SetBkColor(hDC, gcData->bgColor);
+#endif
 	cls = __qClass(aString);
 
 	i1 = __intVal(index1) - 1;
@@ -6530,19 +6593,10 @@
 		if (i2 < n) {
 		    cp += i1;
 		    DDPRINTF(("string1: %s pos=%d/%d l=%d hDC=%x hWnd=%x\n", cp, pX, pY,l,hDC,_HWNDVal(aDrawableId)));
-		    if (opaque == true) {
-			SetBkMode(hDC, OPAQUE);
-		    } else {
-			SetBkMode(hDC, TRANSPARENT);
-		    }
-		    hOldFont = SelectObject(hDC, gcData->hFont);
-		    SetTextColor(hDC, gcData->fgColor);
-		    SetBkColor(hDC, gcData->bgColor);
 
 		    if (!TextOut(hDC, pX, pY, (char *)cp, l)) {
 		       PRINTF(("Textout failed. %d\n", GetLastError()));
 		    }
-		    SelectObject(hDC, hOldFont);
 		    goto ret; 
 		}
 	    }
@@ -6556,16 +6610,9 @@
 		if (i2 < n) {
 		    cp += i1;
 		    DDPRINTF(("string: %s pos=%d/%d\n", cp, pX, pY));
-		    if (opaque == true) {
-			SetBkMode(hDC, OPAQUE);
-		    } else {
-			SetBkMode(hDC, TRANSPARENT);
+		    if (!TextOut(hDC, pX, pY, (char *)cp, l)) {
+		       PRINTF(("Textout failed. %d\n", GetLastError()));
 		    }
-		    hOldFont = SelectObject(hDC, gcData->hFont);
-		    SetTextColor(hDC, gcData->fgColor);
-		    SetBkColor(hDC, gcData->bgColor);
-		    TextOut(hDC, pX, pY, (char *)cp, l);
-		    SelectObject(hDC, hOldFont);
 		    goto ret; 
 		}
 	    }
@@ -6622,7 +6669,10 @@
 #endif
 	}
 ret:   
+#if 0
+	SelectObject(hDC, hOldFont);
 	_releaseDC(gcData); 
+#endif
     }
 #undef NLOCALBUFFER
 %}
@@ -8615,25 +8665,25 @@
 
 primEnumFontTypesInto:typeFaceList
 %{      /* xxLIMITEDSTACK (WIN95) */
-	if (__tmpDC) {
-	    if ( EnumFontFamilies( __tmpDC, NULL, EnumFPTypeFaceProc, (DWORD)&(typeFaceList))) {
-		DPRINTF(("EnumFonts successful\n"));
-	    }
-	}
+    if (__tmpDC) {
+	if ( EnumFontFamilies( __tmpDC, NULL, EnumFPTypeFaceProc, (DWORD)&(typeFaceList))) {
+	    DPRINTF(("EnumFonts successful\n"));
+	}
+    }
 %}
 !
 
 primEnumFontsIn:typeFace into:fontList
 %{      /* xxLIMITEDSTACK (WIN95) */
-	char *cp;
-
-	if (__isString(typeFace)) {
-	    if (__tmpDC) {
-		if (EnumFontFamilies(__tmpDC, __stringVal(typeFace), EnumFontsProc, (DWORD)&(fontList))) {
-		    DPRINTF(("EnumFonts Successful\n"));
-		}
-	    }
-	}
+    char *cp;
+
+    if (__isString(typeFace)) {
+	if (__tmpDC) {
+	    if (EnumFontFamilies(__tmpDC, __stringVal(typeFace), EnumFontsProc, (DWORD)&(fontList))) {
+		DPRINTF(("EnumFonts Successful\n"));
+	    }
+	}
+    }
 %}.
 !
 
@@ -8648,17 +8698,23 @@
 	HGDIOBJ hFont;
 	HGDIOBJ prevFont;
 	TEXTMETRIC tmet;
-	int len;
+	static char *s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+	static int len;
+
 	hFont = _HGDIOBJVal(fontId);
+
 	/*
 	 * temporarily set this font in the root context
 	 */
 	prevFont = SelectObject(__tmpDC, hFont);
 	GetTextMetrics(__tmpDC, &tmet);
-	GetTextExtentPoint32(__tmpDC,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrst"
-	 "uvwxyz",52,&size);
+	if (len == 0) {
+	    len = strlen(s);
+	}
+	GetTextExtentPoint32(__tmpDC, s, len, &size);
 	SelectObject(__tmpDC, prevFont);
-	avgWidth = (size.cx/26+1)/2;
+
+	avgWidth = (size.cx / (len / 2) + 1) / 2;
 
 	__ArrayInstPtr(data)->a_element[0] = __MKSMALLINT(tmet.tmAscent);
 	__ArrayInstPtr(data)->a_element[1] = __MKSMALLINT(tmet.tmDescent);
@@ -8833,7 +8889,7 @@
 	    ShowWindow(hWnd, SW_SHOWNOACTIVATE);
 	    //EnableWindow(hWnd,TRUE);
 	    SetWindowPos(hWnd, HWND_TOP,
-			 0, 0, 0, 0,SWP_NOREDRAW|SWP_NOSENDCHANGING|SWP_NOCOPYBITS
+			 0, 0, 0, 0, SWP_NOREDRAW|SWP_NOSENDCHANGING|SWP_NOCOPYBITS
 				    |SWP_NOACTIVATE |SWP_NOMOVE|SWP_NOSIZE);
 	    CPRINTF(("setRootCapture %x\n",hWnd));
 	}
@@ -8950,13 +9006,14 @@
 	struct gcData *gcData = _GCDATA(aGCId);
 
 	if (gcData && gcData->hWnd) {
-	    if ( aBool == true ) {
-		/* set clip by child */
-		gcData->clipByChild = TRUE;
-	    } else {
-		gcData->clipByChild = FALSE;
-	    }
-	    FLUSH_CACHED_DC(gcData);
+	    int newClip;
+
+	    newClip = (aBool == true) ? TRUE : FALSE;
+	    if (newClip != gcData->clipByChildren) {
+		/* set/clear clip by children */
+		gcData->clipByChildren = newClip;
+		FLUSH_CACHED_DC(gcData);
+	    }
 	} else {
 	    DPRINTF(("clipping by child failed - invalid win\n" ));
 	}
@@ -9028,30 +9085,39 @@
     {
 	struct gcData *gcData = _GCDATA(aGCId);
 	HDC hDC;
-	HGDIOBJ oldFont, hFont;
+	HGDIOBJ prevFont, hFont;
 	TEXTMETRIC tmet;
 
 	hDC = _getDC(gcData);
 
 	hFont = _HGDIOBJVal(aFontId);
-	oldFont = gcData->hFont;
-	if (oldFont != hFont) {
+	if (gcData->hFont != hFont) {
 	    gcData->hFont = hFont;
 
-	    hFont = SelectObject(hDC, hFont);
-	    GetTextMetrics(hDC, &tmet);
+	    prevFont = SelectObject(__tmpDC, hFont);
+	    GetTextMetrics(__tmpDC, &tmet);
 	    gcData->fontAscent = tmet.tmAscent;
-#ifdef DEBUG
+#ifdef SUPERDEBUG
 	    if (__debug__) {
 		char buf[80];
 
-		GetTextFace(hDC,80,buf);
-		PRINTF(("setFont: %x %s\n", hFont,buf));
-	    }
-#endif
-	    SelectObject(hDC, hFont);
+		GetTextFace(__tmpDC, 80, buf);
+		PRINTF(("setFont: %x %s\n", hFont, buf));
+	    }
+#endif
+	    SelectObject(__tmpDC, prevFont);
+
+#if 0
 	    _releaseDC(gcData);
 	    FLUSH_CACHED_DC(gcData);
+#else
+	    if (lastGcData == gcData) {
+		prevFont = SelectObject(gcData->_hDC, hFont);
+		if (! gcData->save_hFont) {
+		    gcData->save_hFont = prevFont;
+		}
+	    }
+#endif
 	    RETURN ( self );
 	}
     }
@@ -11250,6 +11316,6 @@
 !WinWorkstation class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview/WinWorkstation.st,v 1.105 1999-05-02 14:54:13 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/WinWorkstation.st,v 1.106 1999-05-03 12:46:31 cg Exp $'
 ! !
 WinWorkstation initialize!