--- 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