--- a/WinWorkstation.st Mon Jun 11 10:50:04 2018 +0100
+++ b/WinWorkstation.st Wed Jul 11 16:58:29 2018 +0200
@@ -1,6 +1,6 @@
"
COPYRIGHT (c) 1996 by Claus Gittinger
-COPYRIGHT (c) 2017 Patrik Svestka
+COPYRIGHT (c) 2017-2018 Patrik Svestka
COPYRIGHT (c) 2015-2018 Jan Vrany
All Rights Reserved
@@ -172,6 +172,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
+#include <assert.h>
/* #include <malloc.h> */
/* #include <math.h> */
/* #include <string.h> */
@@ -5284,7 +5285,7 @@
copyright
"
COPYRIGHT (c) 1996 by Claus Gittinger
-COPYRIGHT (c) 2017 Patrik Svestka
+COPYRIGHT (c) 2017-2018 Patrik Svestka
COPYRIGHT (c) 2015-2018 Jan Vrany
All Rights Reserved
@@ -8087,11 +8088,15 @@
] valueUninterruptably.
windowId notNil ifTrue:[
- self addKnownView:aView withId:windowId
+ self addKnownView:aView withId:windowId.
+ (aView windowStyle == #toolWindow) ifTrue:[
+ self raiseWindowToTopMost: aView id.
+ ].
].
^ windowId
"Modified: / 28-01-2012 / 10:20:30 / cg"
+ "Modified: / 25-01-2018 / 10:19:46 / jv"
!
dcGetClipBoxForGC: gcId
@@ -10773,10 +10778,13 @@
unsigned char *cp;
OBJ cls;
- int i1, i2, n, l, toDisplay;
+ SIZE size;
+ TEXTMETRICW tmet;
+ short maxDisplayBuffer;
+ int i1, i2, n, l;
+ int maxWidth, toDisplay;
int nInstBytes;
-
if (__isExternalAddress(aGCId)
&& __isNonNilObject(aString)
&& __bothSmallInteger(index1, index2)
@@ -10787,9 +10795,6 @@
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,6 +10818,34 @@
gcData->bkMode = BK_TRANSPARENT;
}
}
+
+ /* The Windows (as in 7 or newer) limits the string size for TextOut*. There is apparently
+ * an undocumented limit to the overall raster size. It changes according to the font size (width)!
+ * The maximum value for the raster size is apparently 16384 (experimentally tested on Windows 7).
+ */
+
+
+ /* GetTextMetricsW gives all needed font metrics (has a fallback when fails)
+ * - a maxWidth parameter takes in account the worst case scenario - user prints
+ * with the widest possible characters from the selected font.
+ * - a overHang is a parameter which allows the font to grow outside the maxWidth size
+ */
+
+ if (GetTextMetricsW(hDC, &tmet)) {
+ maxWidth = tmet.tmMaxCharWidth;
+ // Dynamically calculate the maximum buffer size for the selected font and its size
+ maxDisplayBuffer = 16384 / (maxWidth + tmet.tmOverhang);
+ } else {
+ /* A fallback when GetTextMetricsW fails. Should not normally happen!
+ * The works case scenario, experimentally tested from 1170 fonts, is Microsoft Uighur-build-italic-288
+ * with maxWidth = 2179. That would mean only 7 characters at the maxDisplayBuffer (16384 / 2179).
+ * Such a buffer would be rediculously slow!. A compromise is needed (speed vs. functionality)
+ * Taking an avgWidth from all 1170 with fonts size 96pt -> avgWidth = 152,
+ * which should suffice 99.9% of time. The buffer would then be int(16384/152) = 107, which is reasonable.
+ */
+ maxDisplayBuffer = 107;
+ }
+
#if 0
/* leftover code from tries to make TextOut honor the gc-mode,
* until I googled, that TextOut does not (by purpose, or backward-bug compatibility)
@@ -10841,13 +10874,13 @@
cp += i1;
do {
/* TA_UPDATECP used => pX, pY ignored */
- if (! TextOutA(hDC, 0, 0, (char *)cp, MIN(toDisplay, MAX_DISPLAY_BUFFER))) {
+ if (! TextOutA(hDC, 0, 0, (char *)cp, MIN(toDisplay, maxDisplayBuffer))) {
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;
+ cp += maxDisplayBuffer;
+ toDisplay -= maxDisplayBuffer;
} while(toDisplay > 0);
}
goto ret;
@@ -10869,13 +10902,13 @@
w_cp += i1;
do {
/* TA_UPDATECP used => pX, pY ignored */
- if (! TextOutW(hDC, 0, 0, w_cp, MIN(toDisplay, MAX_DISPLAY_BUFFER))) {
+ if (! TextOutW(hDC, 0, 0, w_cp, MIN(toDisplay, maxDisplayBuffer))) {
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;
+ w_cp += maxDisplayBuffer;
+ toDisplay -= maxDisplayBuffer;
} while (toDisplay > 0);
}
goto ret;
@@ -13270,14 +13303,15 @@
minCode:(rawData at:8)
maxCode:16rFFFF "(rawData at:9)"
direction:nil
- encoding:(rawData at:11).
+ encoding:(rawData at:11)
+ overHang:(rawData at:12).
^ info
!
fontsInFamily:aFamilyName face:aFaceName filtering:filter
"return a set of all available fonts in aFamily/aFace on this display.
- On WinWorkStations there is curently Face
- But only thise matching filter (if nonNil)."
+ On WinWorkStations there is currently Face
+ But only these matching filter (if nonNil)."
|allFonts fonts|
@@ -13777,11 +13811,12 @@
maxDescent -> (data at:4)
minWidth -> (data at:5)
maxWidth -> (data at:6)
- avgWidth -> (data at:7).
- minChar -> (data at:8).
- maxChar -> (data at:9).
- defaultChar-> (data at:10).
- charSet -> (data at:11).
+ avgWidth -> (data at:7)
+ minChar -> (data at:8)
+ maxChar -> (data at:9)
+ defaultChar-> (data at:10)
+ charSet -> (data at:11)
+ overHang -> (data at:12)
"
%{
@@ -13844,10 +13879,11 @@
__ArrayInstPtr(rawData)->a_element[9] = __MKSMALLINT(tmet.tmDefaultChar); /* default -> (data at:10) */
t = __charSetSymbolFor(tmet.tmCharSet);
__ArrayInstPtr(rawData)->a_element[10]= t; __STORE(rawData, t); /* charSet -> (data at:11) */
-
- DPRINTF(("textMetrics h=%x avgAsc=%d avgDesc=%d minW=%d maxW=%d avgW=%d\n",
+ __ArrayInstPtr(rawData)->a_element[11]= __MKSMALLINT(tmet.tmOverhang); /* overHang -> (data at:12) */
+
+ DPRINTF(("textMetrics h=%x avgAsc=%d avgDesc=%d minW=%d maxW=%d avgW=%d overHang=%d\n",
hFont, tmet.tmAscent, tmet.tmDescent, avgWidth, tmet.tmMaxCharWidth,
- tmet.tmAveCharWidth));
+ tmet.tmAveCharWidth, tmet.tmOverhang));
RETURN (self);
}
RETURN (nil);