# HG changeset patch
# User Patrik Svestka <patrik.svestka@gmail.com>
# Date 1521448256 -3600
# Mon Mar 19 09:30:56 2018 +0100
# Branch jv
# Node ID d97ece7b69c3f98107c37e7c8cf8b4c07cee2e35
# Parent b99e94212cb56bdff4d5477249e5d46740a5305d
#126 Copy to workspace (same thing in the Inspector) this line - becomes invisible
diff -r b99e94212cb5 -r d97ece7b69c3 DeviceWorkstation.st
a
|
b
|
|
42 | 42 | ! |
43 | 43 | |
44 | 44 | Object subclass:#DeviceFontMetrics |
45 | | instanceVariableNames:'encoding ascent descent maxAscent maxDescent minWidth maxWidth |
46 | | averageWidth minCode maxCode direction' |
| 45 | instanceVariableNames:'ascent descent maxAscent maxDescent minWidth maxWidth |
| 46 | averageWidth minCode maxCode direction encoding overHang' |
47 | 47 | classVariableNames:'' |
48 | 48 | poolDictionaries:'' |
49 | 49 | privateIn:DeviceWorkstation |
… |
… |
|
5578 | 5578 | ^ info |
5579 | 5579 | ! |
5580 | 5580 | |
| 5581 | fontDetailMetricsOf:fontId userInputString:aString |
| 5582 | "return a average font Width and overHang for a specified character fonts metrics |
| 5583 | info object" |
| 5584 | |
| 5585 | |info| |
| 5586 | |
| 5587 | info := DeviceWorkstation::DeviceFontMetrics new. |
| 5588 | info |
| 5589 | avgWidth:(self widthOf:aString inFont:fontId) |
| 5590 | overHang:(self overHangOf:aString inFont:fontId). |
| 5591 | |
| 5592 | ^ info |
| 5593 | ! |
| 5594 | |
5581 | 5595 | fontResolutionOf:fontId |
5582 | 5596 | "return the resolution (as dpiX @ dpiY) of the font - this is usually the displays resolution, |
5583 | 5597 | but due to errors in some XServer installations, some use 75dpi fonts on higher |
… |
… |
|
5892 | 5906 | "return the width in pixels of a string in a specific font" |
5893 | 5907 | |
5894 | 5908 | ^ self widthOf:aString from:1 to:(aString size) inFont:aFontId |
| 5909 | ! |
| 5910 | |
| 5911 | overHangOf:aString from:index1 to:index2 inFont:aFontId |
| 5912 | "return the overHang in pixels of a substring in a specific font" |
| 5913 | |
| 5914 | ^ self subclassResponsibility |
| 5915 | ! |
| 5916 | |
| 5917 | overHangOf:aString inFont:aFontId |
| 5918 | "return the overHang in pixels of a string in a specific font" |
| 5919 | |
| 5920 | ^ self overHangOf:aString from:1 to:(aString size) inFont:aFontId |
5895 | 5921 | ! ! |
5896 | 5922 | |
5897 | 5923 | !DeviceWorkstation methodsFor:'grabbing'! |
… |
… |
|
8482 | 8508 | encoding := encodingArg. |
8483 | 8509 | ! |
8484 | 8510 | |
8485 | | averageWidth |
8486 | | "return the averageWidth" |
8487 | | |
8488 | | ^ averageWidth |
| 8511 | ascent:ascentArg descent:descentArg maxAscent:maxAscentArg maxDescent:maxDescentArg |
| 8512 | minWidth:minWidthArg maxWidth:maxWidthArg avgWidth:avgWidthArg minCode:minCodeArg maxCode:maxCodeArg |
| 8513 | direction:directionArg encoding:encodingArg overHang:overHangArg |
| 8514 | "set corresponding instance variables" |
| 8515 | |
| 8516 | ascent := ascentArg. |
| 8517 | descent := descentArg. |
| 8518 | maxAscent := maxAscentArg. |
| 8519 | maxDescent := maxDescentArg. |
| 8520 | minWidth := minWidthArg. |
| 8521 | maxWidth := maxWidthArg. |
| 8522 | averageWidth := avgWidthArg. |
| 8523 | minCode := minCodeArg. |
| 8524 | maxCode := maxCodeArg. |
| 8525 | direction := directionArg. |
| 8526 | encoding := encodingArg. |
| 8527 | overHang := overHangArg. |
8489 | 8528 | ! |
8490 | 8529 | |
8491 | 8530 | descent |
… |
… |
|
8494 | 8533 | ^ descent |
8495 | 8534 | ! |
8496 | 8535 | |
| 8536 | maxAscent |
| 8537 | "return the maxAscent" |
| 8538 | |
| 8539 | ^ maxAscent |
| 8540 | ! |
| 8541 | |
| 8542 | maxDescent |
| 8543 | "return the maxDescent" |
| 8544 | |
| 8545 | ^ maxDescent |
| 8546 | ! |
| 8547 | |
| 8548 | minWidth |
| 8549 | "return the minWidth" |
| 8550 | |
| 8551 | ^ minWidth |
| 8552 | ! |
| 8553 | |
| 8554 | maxWidth |
| 8555 | "return the maxWidth" |
| 8556 | |
| 8557 | ^ maxWidth |
| 8558 | ! |
| 8559 | |
| 8560 | averageWidth |
| 8561 | "return the averageWidth" |
| 8562 | |
| 8563 | ^ averageWidth |
| 8564 | ! |
| 8565 | |
| 8566 | minCode |
| 8567 | ^ minCode ? 0 |
| 8568 | ! |
| 8569 | |
| 8570 | maxCode |
| 8571 | ^ maxCode ? 16rFFFF |
| 8572 | ! |
| 8573 | |
8497 | 8574 | direction |
8498 | 8575 | "return the drawing direction (think of hebrew and arabic !!)" |
8499 | 8576 | |
… |
… |
|
8506 | 8583 | ^ encoding |
8507 | 8584 | ! |
8508 | 8585 | |
8509 | | maxAscent |
8510 | | "return the maxAscent" |
8511 | | |
8512 | | ^ maxAscent |
8513 | | ! |
8514 | | |
8515 | | maxCode |
8516 | | ^ maxCode ? 16rFFFF |
8517 | | ! |
8518 | | |
8519 | | maxDescent |
8520 | | "return the maxDescent" |
8521 | | |
8522 | | ^ maxDescent |
8523 | | ! |
8524 | | |
8525 | | maxWidth |
8526 | | "return the maxWidth" |
8527 | | |
8528 | | ^ maxWidth |
8529 | | ! |
8530 | | |
8531 | | minCode |
8532 | | ^ minCode ? 0 |
8533 | | ! |
8534 | | |
8535 | | minWidth |
8536 | | "return the minWidth" |
8537 | | |
8538 | | ^ minWidth |
| 8586 | overHang |
| 8587 | "return font the overHang" |
| 8588 | |
| 8589 | ^ overHang |
8539 | 8590 | ! ! |
8540 | 8591 | |
8541 | 8592 | !DeviceWorkstation class methodsFor:'documentation'! |
diff -r b99e94212cb5 -r d97ece7b69c3 WinWorkstation.st
a
|
b
|
|
170 | 170 | #include <stdlib.h> |
171 | 171 | #include <stdio.h> |
172 | 172 | #include <errno.h> |
| 173 | #include <assert.h> |
173 | 174 | /* #include <malloc.h> */ |
174 | 175 | /* #include <math.h> */ |
175 | 176 | /* #include <string.h> */ |
… |
… |
|
10773 | 10774 | |
10774 | 10775 | unsigned char *cp; |
10775 | 10776 | OBJ cls; |
10776 | | int i1, i2, n, l, toDisplay; |
| 10777 | SIZE size; |
| 10778 | TEXTMETRICW tmet; |
| 10779 | short maxDisplayBuffer; |
| 10780 | int i1, i2, n, l, getMetricsResult, avgWidth, toDisplay; |
10777 | 10781 | int nInstBytes; |
10778 | 10782 | |
10779 | 10783 | |
… |
… |
|
10787 | 10791 | HDC hDC; |
10788 | 10792 | HFONT hOldFont; |
10789 | 10793 | |
10790 | | /* Windows (as in 7 or newer) limits the string size for TextOut* to 3275 */ |
10791 | | const int MAX_DISPLAY_BUFFER = 3275; |
| 10794 | /* Windows (as in 7 or newer) limits the string size for TextOut* changes |
| 10795 | according to the font size! There is apparently an undocumented limit to |
| 10796 | the overall raster size. The maximum value for the raster size is 16384. */ |
| 10797 | |
| 10798 | |
| 10799 | // GetTextMetricsW gives all needed font metrics |
| 10800 | // If for any reason it does not work there is a fallback |
| 10801 | if (GetTextMetricsW(__tmpDC, &tmet)) { |
| 10802 | avgWidth = tmet.tmAveCharWidth; |
| 10803 | } else { |
| 10804 | static char *s = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzコーヒーアイスクリームケーキビールすしかき"; |
| 10805 | static int len; |
| 10806 | |
| 10807 | if (len == 0) { |
| 10808 | len = strlen(s); |
| 10809 | } |
| 10810 | assert(GetTextExtentPoint32(__tmpDC, s, len, &size) != 0 && "GetTextExtentPoint32 != 0, fix me"); |
| 10811 | avgWidth = (size.cx / (len / 2) + 1) / 2; |
| 10812 | } |
| 10813 | |
| 10814 | // Calculate the maximum buffer size for the selected font size |
| 10815 | maxDisplayBuffer = 16384 / (avgWidth + tmet.tmOverhang); |
10792 | 10816 | |
10793 | 10817 | i1 = __intVal(index1) - 1; |
10794 | 10818 | i2 = __intVal(index2) - 1; |
… |
… |
|
10841 | 10865 | cp += i1; |
10842 | 10866 | do { |
10843 | 10867 | /* TA_UPDATECP used => pX, pY ignored */ |
10844 | | if (! TextOutA(hDC, 0, 0, (char *)cp, MIN(toDisplay, MAX_DISPLAY_BUFFER))) { |
| 10868 | if (! TextOutA(hDC, 0, 0, (char *)cp, MIN(toDisplay, maxDisplayBuffer))) { |
10845 | 10869 | PRINTF(("WinWorkstation [warning]: TextOutA failed. [%d]\n", __LINE__)); |
10846 | 10870 | PRINTF(("WinWorkstation [warning]: lastError=%d x:%d y:%d len:%d leftToShow=%d\n", GetLastError(), pX, pY, l, toDisplay)); |
10847 | 10871 | goto error; |
10848 | 10872 | } |
10849 | | cp += MAX_DISPLAY_BUFFER; |
10850 | | toDisplay -= MAX_DISPLAY_BUFFER; |
| 10873 | cp += maxDisplayBuffer; |
| 10874 | toDisplay -= maxDisplayBuffer; |
10851 | 10875 | } while(toDisplay > 0); |
10852 | 10876 | } |
10853 | 10877 | goto ret; |
… |
… |
|
10869 | 10893 | w_cp += i1; |
10870 | 10894 | do { |
10871 | 10895 | /* TA_UPDATECP used => pX, pY ignored */ |
10872 | | if (! TextOutW(hDC, 0, 0, w_cp, MIN(toDisplay, MAX_DISPLAY_BUFFER))) { |
| 10896 | if (! TextOutW(hDC, 0, 0, w_cp, MIN(toDisplay, maxDisplayBuffer))) { |
10873 | 10897 | PRINTF(("WinWorkstation [warning]: TextOutW failed. [%d]\n", __LINE__)); |
10874 | 10898 | PRINTF(("WinWorkstation [warning]: lastError=%d x:%d y:%d len:%d leftToShow=%d\n", GetLastError(), pX, pY, l, toDisplay)); |
10875 | 10899 | goto error; |
10876 | 10900 | } |
10877 | | w_cp += MAX_DISPLAY_BUFFER; |
10878 | | toDisplay -= MAX_DISPLAY_BUFFER; |
| 10901 | w_cp += maxDisplayBuffer; |
| 10902 | toDisplay -= maxDisplayBuffer; |
10879 | 10903 | } while (toDisplay > 0); |
10880 | 10904 | } |
10881 | 10905 | goto ret; |
… |
… |
|
13270 | 13294 | minCode:(rawData at:8) |
13271 | 13295 | maxCode:16rFFFF "(rawData at:9)" |
13272 | 13296 | direction:nil |
13273 | | encoding:(rawData at:11). |
| 13297 | encoding:(rawData at:11) |
| 13298 | overHang:(rawData at:12). |
13274 | 13299 | ^ info |
13275 | 13300 | ! |
13276 | 13301 | |
13277 | 13302 | fontsInFamily:aFamilyName face:aFaceName filtering:filter |
13278 | 13303 | "return a set of all available fonts in aFamily/aFace on this display. |
13279 | | On WinWorkStations there is curently Face |
13280 | | But only thise matching filter (if nonNil)." |
| 13304 | On WinWorkStations there is currently Face |
| 13305 | But only these matching filter (if nonNil)." |
13281 | 13306 | |
13282 | 13307 | |allFonts fonts| |
13283 | 13308 | |
… |
… |
|
13777 | 13802 | maxDescent -> (data at:4) |
13778 | 13803 | minWidth -> (data at:5) |
13779 | 13804 | maxWidth -> (data at:6) |
13780 | | avgWidth -> (data at:7). |
13781 | | minChar -> (data at:8). |
13782 | | maxChar -> (data at:9). |
13783 | | defaultChar-> (data at:10). |
13784 | | charSet -> (data at:11). |
| 13805 | avgWidth -> (data at:7) |
| 13806 | minChar -> (data at:8) |
| 13807 | maxChar -> (data at:9) |
| 13808 | defaultChar-> (data at:10) |
| 13809 | charSet -> (data at:11) |
| 13810 | overHang -> (data at:12) |
13785 | 13811 | " |
13786 | 13812 | |
13787 | 13813 | %{ |
… |
… |
|
13819 | 13845 | static int len; |
13820 | 13846 | |
13821 | 13847 | if (len == 0) { |
13822 | | len = strlen(s); |
| 13848 | len = strlen(s); |
13823 | 13849 | } |
13824 | 13850 | GetTextExtentPoint32(__tmpDC, s, len, &size); |
13825 | 13851 | avgWidth = (size.cx / (len / 2) + 1) / 2; |
… |
… |
|
13844 | 13870 | __ArrayInstPtr(rawData)->a_element[9] = __MKSMALLINT(tmet.tmDefaultChar); /* default -> (data at:10) */ |
13845 | 13871 | t = __charSetSymbolFor(tmet.tmCharSet); |
13846 | 13872 | __ArrayInstPtr(rawData)->a_element[10]= t; __STORE(rawData, t); /* charSet -> (data at:11) */ |
13847 | | |
13848 | | DPRINTF(("textMetrics h=%x avgAsc=%d avgDesc=%d minW=%d maxW=%d avgW=%d\n", |
| 13873 | __ArrayInstPtr(rawData)->a_element[11]= __MKSMALLINT(tmet.tmOverhang); /* overHang -> (data at:12) */ |
| 13874 | |
| 13875 | DPRINTF(("textMetrics h=%x avgAsc=%d avgDesc=%d minW=%d maxW=%d avgW=%d overHang=%d\n", |
13849 | 13876 | hFont, tmet.tmAscent, tmet.tmDescent, avgWidth, tmet.tmMaxCharWidth, |
13850 | | tmet.tmAveCharWidth)); |
| 13877 | tmet.tmAveCharWidth, tmet.tmOverhang)); |
13851 | 13878 | RETURN (self); |
13852 | 13879 | } |
13853 | 13880 | RETURN (nil); |