WinWorkstation.st
branchjv
changeset 7994 42a7e4c6503d
parent 7743 fa3c8eb0bc1d
child 8016 653376a94c8f
--- a/WinWorkstation.st	Sun Mar 12 22:07:34 2017 +0000
+++ b/WinWorkstation.st	Tue Apr 04 12:20:33 2017 +0200
@@ -2800,7 +2800,8 @@
 		  lpmmi->ptMaxPosition.y = 0;
 		  lpmmi->ptMaxSize.x = lI->currentMonitorWidth;
 		  lpmmi->ptMaxSize.y = lI->currentMonitorHeight;
-#define MIN(a, b) (a < b ? a : b)
+/* Added Extra parentheses to avoid operator precedence problem */
+#define MIN(a,b) (((a)<(b))?(a):(b))
 		  lpmmi->ptMaxSize.x = MIN(GetSystemMetrics(SM_CXMAXIMIZED), lI->maxWidth);
 		  lpmmi->ptMaxSize.y = MIN(GetSystemMetrics(SM_CYMAXIMIZED), lI->maxHeight);
 
@@ -10760,13 +10761,18 @@
     "draw a sub-string - if opaque is false, draw foreground only; otherwise, draw both
      foreground and background characters.
      If the coordinates are not integers, an error is triggered."
-
-%{  /* NOCONTEXT */
+%{  /* NOCONTEXT */
+  /* NOTICE:
+   * A change here was forced by (an undocumented) limited internal display buffer. 
+   * A check is needed to draw against such internal limit; then draw it chunk-by-chunk.
+   */
+
     unsigned char *cp;
     OBJ cls;
-    int i1, i2, l, n;
+    int i1, i2, n, l, toDisplay;
     int nInstBytes;
 
+
     if (__isExternalAddress(aGCId)
      && __isNonNilObject(aString)
      && __bothSmallInteger(index1, index2)
@@ -10777,6 +10783,9 @@
 	HDC hDC;
 	HFONT hOldFont;
 
+	/* Windows (as in 7 or newer) limits the string size for TextOut* to 3275 */
+	const int MAX_DISPLAY_BUFFER = 3275;
+
 	i1 = __intVal(index1) - 1;
 	i2 = __intVal(index2) - 1;
 	if ((i1 < 0) || (i2 < i1)) {
@@ -10813,25 +10822,29 @@
 #endif
 
 	cls = __qClass(aString);
-
 	cp = __stringVal(aString);
 	l = i2 - i1 + 1;
-	if (l > 32758) {
-	    /* Windows (as in XP) limits the string size for TextOut* to 32758 */
-	    l = 32758;
-	}
+	toDisplay = l;
+
+	/* Set the current point to the reference point. */
+	SetTextAlign(hDC, TA_UPDATECP);
+	MoveToEx(hDC, pX, pY, NULL);
 
 	if (__isStringLike(aString)) {
 	    n = __stringSize(aString);
 commonOutChars:
 	    if (i2 < n) {
-		cp += i1;
-		CPRINTF(("string1: %s pos=%d/%d l=%d hDC=%x\n", cp, pX, pY,l,hDC));
-		if (! TextOutA(hDC, pX, pY, (char *)cp, l)) {
-		    PRINTF(("WinWorkstation [warning]: TextOutA failed. [%d]\n", __LINE__));
-		    PRINTF(("WinWorkstation [warning]: lastError=%d x:%d y:%d len:%d\n", GetLastError(), pX, pY, l));
-		    goto error;
-		}
+	        cp += i1;
+	        do {
+	            /* TA_UPDATECP used => pX, pY ignored */
+	            if (! TextOutA(hDC, 0, 0, (char *)cp, MIN(toDisplay, MAX_DISPLAY_BUFFER))) { 
+	                PRINTF(("WinWorkstation [warning]: TextOutA failed. [%d]\n", __LINE__));
+	                PRINTF(("WinWorkstation [warning]: lastError=%d x:%d y:%d len:%d leftToShow=%d\n", GetLastError(), pX, pY, l, toDisplay));
+	                goto error;
+	            }
+	            cp += MAX_DISPLAY_BUFFER;
+	            toDisplay -= MAX_DISPLAY_BUFFER;
+	        } while(toDisplay > 0);
 	    }
 	    goto ret;
 	}
@@ -10847,15 +10860,21 @@
 	/* Unicode */
 	if (__isWords(aString)) {
 	    n = n / 2;
-	    if (i2 < n) {
-		WIDECHAR *w_cp = (WIDECHAR *)cp;
-		w_cp += i1;
-		if (! TextOutW(hDC, pX, pY, w_cp, l)) {
-		    PRINTF(("WinWorkstation [warning]: TextOutW failed. [%d]\n", __LINE__));
-		    PRINTF(("WinWorkstation [warning]: lastError=%d x:%d y:%d len:%d\n", GetLastError(), pX, pY, l));
-		}
-		goto ret;
-	    }
+	    WIDECHAR *w_cp = (WIDECHAR *)cp;
+	    if (i2 < n){
+	        w_cp += i1;
+	        do {
+	            /* TA_UPDATECP used => pX, pY ignored */
+	            if (! TextOutW(hDC, 0, 0, w_cp, MIN(toDisplay, MAX_DISPLAY_BUFFER))) { 
+	                PRINTF(("WinWorkstation [warning]: TextOutW failed. [%d]\n", __LINE__));
+	                PRINTF(("WinWorkstation [warning]: lastError=%d x:%d y:%d len:%d leftToShow=%d\n", GetLastError(), pX, pY, l, toDisplay));
+	                goto error;
+	            }
+	            w_cp += MAX_DISPLAY_BUFFER;
+	            toDisplay -= MAX_DISPLAY_BUFFER;
+	        } while (toDisplay > 0);
+	    }
+	    goto ret;
 	}
 ret:;
 #if 0