OUTLINETEXTMETRIC Structure Improperly Defined

Started by dedndave, August 30, 2011, 03:11:03 AM

Previous topic - Next topic

qWord

devae,
the struct definition on msdn is OK - in this case the problem comes from the packing, which is 8 for 32Bit windows. This cause that the TEXTMETRICA-structure has 3 padding bytes at the end. Adding an ALIGN 4 before the member OUTLINETEXTMETRICA.otmFiller and before OUTLINETEXTMETRICA.otmfsSelection should solve the problem in masm.
FPU in a trice: SmplMath
It's that simple!

dedndave

i would very much like to believe that it is an alignment or packiing issue
however, that does not explain the presence of non-zero data returned in those bytes
4A 14 00 68                   - mystery bytes (4)
02 0B 06 04 03 05 04 04 02 04 - PANOSE bytes (10)
02                            - mystery byte (1)


according to Feng Yuan, it is an issue where 32-bit structures were carried over from 16-bit OS's (win3.1)
but, if packing was the issue, these bytes would remain unaltered

what it looks like - is that MS had some extra bytes lying around and decided to use them   :lol

qWord

Quote from: dedndave on August 30, 2011, 06:57:32 PMbut, if packing was the issue, these bytes would remain unaltered
probably the function use internally a local buffer, which is then copied to your buffer.
FPU in a trice: SmplMath
It's that simple!

dedndave

i hadn't considered that   :P
in fact, they may be remnants from the font mapper - matching Panose numbers with other fonts

MichaelW

Information on Windows data alignment, including structure and union layout, is here.

I updated my attachment here to demonstrate that appending a dword alignment to the MASM32 structures causes the structure layout to exactly match the layout that the Microsoft C compilers implement.

eschew obfuscation

dedndave

ok - you guys convinced me   :bg

Feng Yuan's book gives a pretty good explanation
but, it was more fun to use otmMysteryBytes and otmMysteryByte   :P

after running additional tests, i see that these bytes are set to different values on each run

ToutEnMasm


Here what I have made to see if it work       ml /Zp4     and no problem
Quote
WndMini proc  uses ebx esi edi  hwnd:DWORD, uMsg, wParam, lParam
         Local hauteur:DWORD,largeur:DWORD,fwSizeType:DWORD
         Local Ps:PAINTSTRUCT
         align 4
         Local outline:OUTLINETEXTMETRIC
         Local bufmetric[80h]:BYTE            
         Local hdc:DWORD,haut,returnsize         
         Local rect:RECT
         Local posX:DWORD,posY:DWORD,hDcCompat,hOldFont
         Local  retour:DWORD
         ZEROLOCALES
         
   mov retour,0
   
   .if uMsg == WM_CREATE
      mov ebx,lParam
      ;mov     eax, (CREATESTRUCT  ptr [ebx]).hwnd
      ;mov     edx,(CREATESTRUCT  ptr [ebx]).hMenu
      ;suite
            ;-- la classe doit être en data      
      mov outline.otmSize,sizeof outline
      invoke CreeFont
      mov Hfont,eax   
      invoke SendMessage,hwnd,WM_SETFONT,Hfont,FALSE
           INVOKE  GetDC,hwnd
      mov hDcCompat,eax
           INVOKE  SelectObject,hDcCompat,Hfont
           mov     hOldFont,eax
      invoke GetOutlineTextMetrics,hDcCompat,0,0
      .if eax == 0
         invoke Retrieve_Error_Msg,SADR("GetOutlineTextMetrics size")
      .endif
      mov returnsize,eax
      mov edx,0
      mov ecx,sizeof outline
      div ecx      
      mov edx,eax ;sizeof outline
      invoke GetOutlineTextMetrics,hDcCompat,sizeof outline *2,addr outline
      .if eax == 0
         invoke Retrieve_Error_Msg,SADR("GetOutlineTextMetrics")
      .endif   
      ;get the adress of
      lea ebx,outline
      mov ecx,[ebx].OUTLINETEXTMETRIC.otmpFaceName
      .if ecx != -1
         mov eax,ebx
         add eax,ecx
         ;eax adress of the FaceName
      .endif
         
           INVOKE  ReleaseDC,hwnd,hDcCompat
      invoke  DeleteObject,Hfont