;*DDK*************************************************************************/
;
; COPYRIGHT    Copyright (C) 1995 IBM Corporation
;
;    The following IBM OS/2 WARP source code is provided to you solely for
;    the purpose of assisting you in your development of OS/2 WARP device
;    drivers. You may use this code in accordance with the IBM License
;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
;    Copyright statement may not be removed.;
;*****************************************************************************/
        page    ,132
;/*****************************************************************************
;*
;* SOURCE FILE NAME = DBCSATTR.ASM
;*
;*
;* VERSION      V2.0
;*
;* DATE         11/20/90
;*
;* DESCRIPTION  This is part of the DBCS-NLS support dependent sources.
;*              This module contains the querying device fonts functions,
;*              which require special DBCS device font handling.
;*
;* FUNCTIONS    RealizeFont
;*              DeviceQueryFonts
;*              DeviceQueryFontAttributes
;*
;* NOTES        These functions are needed to be implemented when the driver
;*              uses DBCS device fonts. In the other cases,
;*              set CAPS_FONT_IMAGE_MANAGE flag to adDevCapsData array, and
;*              the Engine will do every thing for us.
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*   11/20/90                     Written by Soh Ohta [jl09057 @ ymtvm3]
;*   07/12/93              05522  Allocated memory did not freed.
;*
;*****************************************************************************/

        .386

        .XLIST

INCL_DDIMISC2       equ     1
INCL_DEV            equ     1
INCL_GPITRANSFORMS  equ     1
INCL_GRE_FONTS      equ     1
INCL_GRE_XFORMS     equ     1
INCL_GRE_DEVMISC2   equ     1
INCL_FONTFILEFORMAT equ     1
INCL_DDICOMFLAGS    equ     1

INCL_DDIFONTSTRUCS EQU 1

        OPTION  OLDSTRUCTS

        include pmgre.inc

DINCL_VIO       equ     1
DINCL_ERROR     equ     1
DINCL_ENABLE    equ     1
DINCL_BITMAP equ     1

        include driver.inc
        include fontseg.inc

KC_DBCSRSRVD2       equ     0           ; unresolved but not used.

        include fontmap.inc
        include extern.inc
        include protos.inc

        include assert.mac

        .MODEL FLAT

        ASSUME  CS:FLAT,SS:FLAT,DS:FLAT,ES:FLAT

        .LIST

        .DATA

CP_UGL_FONT     equ     850             ; UGL font codepage

        .CODE

page

;--------------------------Exported-Routine-----------------------------;
; RealizeFont
;
; Entry:
;       None
; Returns:
;       EAX = Device driver font identifier
;               (SBCS font: far pointer to font segment FOCA metrics)
;               (DBCS font: font manager font handle)
; Error Returns:
;       EAX = -1
; Registers Destroyed:
;       EAX,EBX,ECX,EDX
; Registers Preserved:
;       ESI,EDI
; History:
;   19-Sep-1991     -by-    Soh Ohta
; Use enter_driver_sem to prevent from calling pmwin back, to solve
; semaphore contention.
;   21-Jan-1992     -by-    Soh Ohta
; Add codepage validation.
;   10-Feb-1992     -by-    Soh Ohta
; Add coordinate transformation.
;   30-Jun-1992     -by-    Hide Muta
; Modified for 32 bit flat model.
;-----------------------------------------------------------------------;

DELETE_ENGINE_FONT equ 4    ; CR!!! put in pmddi.h when files unfreeze

;        check   RealizeFont,<hdc,ulCmd,pfatLogFont,pfocaEngFont,hddc,ulFunN>

RealizeFont PROC SYSCALL uses ESI EDI EBX,
                hdc     :DWORD,
                Command :DWORD,
                LogFont :DWORD,
                EngFont :DWORD,
                hddc    :DWORD,
                FunN    :DWORD
        LOCAL   fat[FATTRS] :BYTE ; coordinate transformed fattrs.

        cld

        xor     eax,eax
        test    swFlags,SW_DISPLAY_DBCS
        jz      rf_done                 ; SBCS driver compatible path.

; The font manager had been loaded, and CAPS_IMAGE_MANAGE flag was cleared.
; We should handle device font realization using font manager, because
; the Engine won't handle our device fonts anyway.

        mov     edx,hddc
        INVOKE  enter_driver_sem        ; Do not do a VisRegionCallBack
        jc      rf_exit_no_lock         ; EAX = 0 on error

; Check command type and dispatch jobs.

 assert WORD PTR Command[2],E,0
        xor     eax,eax                 ; assumes no error / not found
        mov     bx,WORD PTR Command[0]  ; BX = RealizeFont command word

        cmp     bx,REALIZE_ENGINE_FONT
        je      rf_realize_engine_font
        cmp     bx,DELETE_ENGINE_FONT
        je      rf_delete_engine_font

        cmp     bx,REALIZE_FONT
        je      rf_realize_font
        cmp     bx,DELETE_FONT
        je      rf_delete_font

        mov     eax,GPI_ALTERROR        ; unknown command.
        jmp     rf_exit

; We are going to realize the requested engine font.
; We need not to do anything about it.

rf_realize_engine_font:
        jmp     rf_exit           ; EAX = 0 (not realized)

; We are going to realize the requested device font.
; We will call the DBCS font manager to search the font from the list of
; fonts available, and obtain the font handle corresponding to the match.

rf_realize_font:
        mov     edi,LogFont             ; EDI = logical font (FATTRS struct)
        movzx   eax,[edi].FATTRS.fat_usCodePage
        or      eax,eax
        jz      rf_codepage_ok          ; codepage is valid (null codepage)

        INVOKE  DbcsQueryCodePageVectors
        or      eax,eax
        jnz     rf_codepage_ok          ; codepage is valid.
        xor     eax,eax                 ; EAX = 0 (not found)
        jmp     rf_exit           ; codepage is invalid.

rf_codepage_ok:
        mov     eax,LogFont             ; EAX = logical font (FATTRS struct)
        mov     ecx,[edi].FATTRS.fat_lMatch
        or      ecx,ecx
        jnz     rf_have_fattrs          ; match number is specified.

        lea     edi,fat                 ; EDI   = logical font (to be filled)
        mov     esi,LogFont             ; ESI   = logical font (FATTRS struct)
        mov     ebx,hddc                ; EBX   = hddc
        INVOKE  ConvertFattrs           ; EAX = logical font (transformed)

        or      eax,eax
        jz      rf_exit                 ; EAX = 0, coordinate overflow.

rf_have_fattrs:
        INVOKE  DbcsRealizeFont
        jmp     rf_exit           ; DX:AX = font handle (fontseg) or error

; We are going to delete the specified engine font.
; We need not to do anything about it.

rf_delete_engine_font:
        jmp     rf_delete_ok

; We are going to delete the specified device font.
; The font handle which was returned at realization is passed.
; Request to close font access using this font handle.

rf_delete_font:
        mov     eax,EngFont             ; EAX = font handle (fontseg)
        or      eax,eax                 ; device default font ?
        jz      rf_delete_ok            ; yes... (see resolvec.asm)
        INVOKE  DbcsUnRealizeFont

rf_delete_ok:
        mov     eax,GPI_OK
rf_exit:
        INVOKE  leave_driver
rf_exit_no_lock:
rf_done:
        ret
RealizeFont ENDP

page

;--------------------------Exported-Routine-----------------------------;
; DeviceQueryFonts
;
; Enumerates the fonts on a device. For each font on the device the
; function returns the metrics of the the font
;
; Parameters:
;
;       lpFilter
;            The facename to match
;
;       iMetrics
;           The number of bytes of each metrics structure in the
;           lpMetrics array.
;
;       lpMetrics
;            A long pointer to an array of textmetric records
;
;       lpiFonts
;            The number of fonts for which the application wants
;            metrics. The number the application received is returned here.
;
;       All sizes are returned in world coordinates
;
; Entry:
;       None
; Exit:
;       EAX =  The number of fonts the appl didn't get. This allows the appl
;              to find out how many fonts there are by setting iFonts = 0.
; Error:
;       EAX = -1
; History:
;  Tue Jun 30          1992     -by-    Hide Muta       [jl25345@ymtvm3]
; Modified for 32 bit flat model.
;  Wed Aug 12 11:27:49 1987     -by-    Hock Lee        [hockl]
; Returned base font if needed.
;  Fri Jul 17 14:25:02 1987     -by-    Hock Lee        [hockl]
; Modified for new DDI.
;  Tue May 12 14:03:53 1987     -by-    Hock Lee        [hockl]
; Wrote it.
;-----------------------------------------------------------------------;

;       check   DeviceQueryFonts,<hdc,flCmd,pszFaceName,pfm,cbFontMetrics,pcFonts,hddc,ulFunN>

DeviceQueryFonts PROC SYSCALL uses ESI EDI EBX,
                hdc       :DWORD,
                Options   :DWORD,
                lpFilter  :DWORD,
                lpMetrics :DWORD,
                iMetrics  :DWORD,
                lpiFonts  :DWORD,
                hddc      :DWORD,
                FunN      :DWORD
        LOCAL   iFonts    :WORD,        ; number of fonts requested
                iFontsFound :WORD,      ; number of fonts matched
                iFontsCopied :WORD,     ; number of fonts copied
                cFonts    :WORD,        ; number of font provided by device
                lpFonts   :DWORD,       ; address of list of device fonts
  lpFontsSave :DWORD, ;; V2.1MUT01
                MatchNum  :DWORD,
                FontPSave :DWORD

        cld
        INVOKE  enter_driver_sem        ; Do not do a VisRegionCallBack
        mov     eax,-1                  ; assume error
        jc      dgf_exit_no_lock

        test    swFlags,SW_DISPLAY_DBCS
        jnz     dqf_dbcs_pass           ; DBCS driver compatible path.

; SBCS environment.
; now that DCR 23915 is implemented we don't have any fonts that we manage
; so return 0 fonts left and 0 fonts returned.

dqf_no_fonts:
        mov     edi,lpiFonts
        xor     eax,eax
        stosd
        jmp     dqf_exit


; DBCS environment.
; The font manager had been loaded, and CAPS_IMAGE_MANAGE flag was cleared.
; We should return the list of device font using font manager.
; Query the the list of fonts which are provided by font manager.

dqf_dbcs_pass:
        mov     eax,Options
        .errnz  FM_PUBLIC  - QUERY_PUBLIC_FONTS
        .errnz  FM_PRIVATE - QUERY_PRIVATE_FONTS

        INVOKE  DbcsGetFontList         ; list allocated --> EAX
        jc      dqf_error               ; error on processing
        jcxz    dqf_no_fonts            ; no fonts.

        mov     cFonts,cx               ; number of font provided
        mov     lpFonts,eax             ; address of list of device fonts
        mov     lpFontsSave,eax  ;; V2.1MUT01

; We have now the list of device fonts available.
; Walk through the list and seach requested fonts.

        mov     edi,lpiFonts
        mov     ax,[edi]
        mov     iFonts,ax               ; number of fonts requested
        mov     iFontsFound,0           ; number of fonts matched
        mov     iFontsCopied,0          ; number of fonts copied

search_device_font:
        mov     esi,lpFonts             ; ESI --> FMFONTINFO32 struct

        mov     eax,[esi].fmfont32_lMatch
        mov     MatchNum,eax            ; get lMatch value

        mov     esi,[esi].fmfont32_pFont  ; ESI --> fontseg (FOCAFONT)
        mov     FontPSave,esi

        mov     ecx,lpFilter            ; is there a facename filter ?
        jcxz    same_facename           ; no, always match
        mov     edi,ecx

        lea     esi,[esi].FOCAFONT.ff_fmMetrics.foca_szFacename
                                            ; ESI --> facename
        mov     ecx,FACESIZE                ; CX = ASCIIZ string max length
        INVOKE  szcomp                      ; compare facenames
        jnz     next_device_font

same_facename:
        inc     iFontsFound
        cmp     iFonts,0                ; only return the number of fonts ?
        je      next_device_font        ; copy is not needed.
        mov     ax,iFontsCopied         ; number of already copied fonts
        cmp     iFonts,ax               ; is request satisfied ?
        jbe     next_device_font        ; yes, copy is not needed.

; Copy foca metrics to font metrics, with device to world coordinate
; transformation (COM_* flags, optional).

        mov     ecx,iMetrics            ; ECX = memory block size
        jcxz    next_device_font        ; no room to copy...

        mov     eax,FunN                ; EAX = transform options (COM_* flags)
        mov     ebx,hddc                ; EBX --> offset to ddc
        mov     esi,FontPSave           ; ESI --> fontseg (FOCAFONT)
        mov     edi,lpMetrics           ; EDI --> font metrics memory block
        INVOKE  ConvertFontMetrics
        or      eax,eax
        jnz     dqf_error_freeseg       ; error on conversion

        inc     iFontsCopied
        add     lpMetrics,ecx           ; advance buffer address

; Check / Fix codepage and lMatch number for this font.
; Force codepage to 0 when the font codepage is UGL font codepage.
; (DCR on JP13).

dqf_set_codepage:
        cmp     word ptr iMetrics,fm_usCodePage-fm_szFamilyname+SIZE_WORD
        jb      dqf_set_lmatch          ; codepage not requested
        cmp     [edi].fm_usCodePage,CP_UGL_FONT
        jne     dqf_set_lmatch
        mov     [edi].fm_usCodePage,0
dqf_set_lmatch:
        cmp     word ptr iMetrics,fm_lMatch-fm_szFamilyname+SIZE_DWORD
        jb      next_device_font        ; lMatch not requested
        mov     ebx,MatchNum            ; set lMatch value
        mov     [edi].fm_lMatch,ebx

next_device_font:
        add     lpFonts,size FMFONTINFO32
        dec     cFonts
        jnz     search_device_font

;;      INVOKE  DosFreeMem,lpFonts
        INVOKE  DosFreeMem,lpFontsSave ;;           


; Now all device fonts are searched, and the font metrics are copied to
; caller's memory block (if requested).

        mov     edi,lpiFonts

        movzx   ecx,iFontsCopied        ; CX = fonts returned now
        mov     [edi],ecx
        movzx   eax,iFontsFound
        sub     eax,ecx                 ; AX = fonts still to be returned
        jmp     dqf_exit

dqf_error_freeseg:
;;      INVOKE  DosFreeMem,lpFonts
        INVOKE  DosFreeMem,lpFontsSave ;;           
dqf_error:
        mov     eax,-1
dqf_exit:
        INVOKE  leave_driver
dgf_exit_no_lock:
        fw_zero <ecx>
        ret

DeviceQueryFonts ENDP

page

;--------------------------Exported-Routine-----------------------------;
; DeviceQueryFontAttributes
;
; This obtains the metrics of the currently selected font.
;
; Parameters
;       lpMetrics
;           A long pointer to a font metric block where the information
;           is to be returned.
;       iMetrics
;           The size of the data structure pointer at by lpMetrics
;       hdc
;           The DC handle.
;
; Entry:
;       None
; Returns:
;       EAX   = 1 if the function executed successfully
; Error Returns:
;       EAX   = 0
; Registers Destroyed:
;       EAX,EBX,ECX,EDX
; History:
;  Wed Aug 12 11:27:49 1987     -by-    Hock Lee        [hockl]
; Wrote it.
;  Thu Jul 16 09:22:32 1987     -by-    Hock Lee        [hockl]
; Modified for new DDI.
;  Tue Jun 30          1992     -by-    Hide Muta       [jl25345@ymtvm3]
; Modified for 32 bit flat model.
;-----------------------------------------------------------------------;

;       check   DeviceQueryFontAttributes,<hdc,cbFontMetrics,pfm,hddc,ulFunN>

DeviceQueryFontAttributes PROC SYSCALL uses ESI EDI EBX,
                hdc       :DWORD,
                iMetrics  :DWORD,
                lpMetrics :DWORD,
                hddc      :DWORD,
                FunN      :DWORD
        LOCAL   CodePage  :DWORD,
                MatchNum  :DWORD

        cld

        xor     eax,eax
        cwd
        test    swFlags,SW_DISPLAY_DBCS
        jz      dqfa_done               ; SBCS driver compatible path.

; The font manager had been loaded, and CAPS_IMAGE_MANAGE flag was cleared.
; We should return our device font attributes according to the coordinate,
; because the Engine won't handle our device fonts anyway.

        mov     edx,hddc
        INVOKE  enter_driver
        jc      dqfa_exit_no_lock       ; EAX = 0 on error

; Query match number for the specified font segment.
; note that we assume the font manager font handle == font segment.

        mov     ebx,hddc                ; EBX --> ddc
        mov     eax,[ebx].ddc_ca.ca_lCodePage
        mov     CodePage,eax            ; logical codepage id for current font

        mov     eax,[ebx].ddc_ca.ca_pFont   ; EAX = font handle (=fontseg)
        INVOKE  DbcsQueryMatchNum           ; --> EAX = match number (<0)
        or      eax,eax
        jz      dqfa_error              ; cannot find the specfied font

        mov     MatchNum,eax            ; get lMatch value

; Copy foca metrics to font metrics, with device to world coordinate
; transformation (COM_* flags, optional).


        mov     ecx,iMetrics            ; ECX = memory block size
        mov     eax,FunN                ; EAX = transform options (COM_* flags)
        mov     ebx,hddc                ; EBX --> ddc
        mov     esi,[ebx].ddc_ca.ca_pFont ; ESI --> fontseg (FOCAFONT)
        mov     edi,lpMetrics           ; EDI --> font metrics memory block
        INVOKE  ConvertFontMetrics
        inc     eax                     ; error  (-1) --> error   (0)
                                        ; success (0) --> success (1)

; Set logical codepage i  and lMatch number for this font.
; We allow any valid codepage for font realization, regardress of font
; capability for DBCS code-points. (DCR on JP13)

dqfa_set_codepage:
        cmp     iMetrics,fm_usCodePage-fm_szFamilyname+SIZE_WORD
        jb      dqfa_set_lmatch         ; codepage not requested
        mov     ebx,CodePage            ; set logical codepage id for current font
        mov     [edi].fm_usCodePage,bx
dqfa_set_lmatch:
        cmp     iMetrics,fm_lMatch-fm_szFamilyname+SIZE_DWORD
        jb      dqfa_exit               ; lMatch not requested
        mov     ebx,MatchNum            ; set lMatch value
        mov     [edi].fm_lMatch,ebx
        jmp     dqfa_exit

dqfa_error:
        mov     eax,0                   ; error.
dqfa_exit:
        INVOKE  leave_driver
dqfa_exit_no_lock:
dqfa_done:
        ret

DeviceQueryFontAttributes ENDP

page

;---------------------------Public-Routine------------------------------;
; ConvertFattrs
;
;   Copy font metrics from FATTRS, then translate it from world
;   coordinate to device coordinate.
;
; Entry:
;   ESI = FATTRS (world coordinate)
;   EDI = FATTRS (device coordinate, to be filled)
;   EBX = hddc
; Returns:
;   EAX = FATTRS (transformed)
; Error Returns:
;   EAX = 0
; Registers Destroyed:
;   EAX,EBX,ECX,EDX,ESI,EDI
; Registers Preserved:
;   EBP
; History:
;  Tue Jun 30          1992     -by-    Hide Muta       [jl25345@ymtvm3]
; Modified for 32 bit flat model.
;-----------------------------------------------------------------------;

ConvertFattrs PROC SYSCALL
        LOCAL   lpFat       :DWORD,
                ptl[(size POINTL)*2] :BYTE

        mov     lpFat,edi

; Copy FATTRS structure contents.

        cld
        mov     ecx,size FATTRS
        rep     movsb
        mov     edi,lpFat

; Get transformed sizes.

        lea     esi,ptl                   ; ESI --> &ptl[0]

        mov     eax,[edi].FATTRS.fat_lAveCharWidth
        mov     ptl[(size POINTL)*0].ptl_x,eax
        mov     ptl[(size POINTL)*0].ptl_y,0

        mov     eax,[edi].FATTRS.fat_lMaxBaselineExt
        mov     ptl[(size POINTL)*1].ptl_x,0
        mov     ptl[(size POINTL)*1].ptl_y,eax

;       check   Convert,<hdc,lSrc,lTarg,pptl,cptl,hddc,ulFunN>

        INVOKE  PFNDefConvert PTR pfnDefConvert,
                [ebx].ddc_hdc,
                CVTC_WORLD,
                CVTC_DEVICE,
                esi,
                2,
                0,
                NGreConvert

        or      eax,eax
        jz      cf_overflow             ; transform error

; Construct transformed FATTRS structure.

        mov     edi,lpFat               ; EDI --> FATTRS to be filled

        mov     eax,ptl[(size POINTL)*0].ptl_x
        sub     eax,ptl[(size POINTL)*1].ptl_x
        jo      cf_overflow
        mov     [edi].FATTRS.fat_lAveCharWidth,eax

        mov     eax,ptl[(size POINTL)*1].ptl_y
        sub     eax,ptl[(size POINTL)*0].ptl_y
        jo      cf_overflow
        mov     [edi].FATTRS.fat_lMaxBaselineExt,eax

        mov     eax,edi
        jmp     cf_exit           ; EAX --> transformed FATTRS

cf_overflow:
        xor     eax,eax           ; EAX = 0 (error)
cf_exit:
        ret
ConvertFattrs ENDP

page


;---------------------------Public-Routine------------------------------;
; ConvertFontMetrics
;
;   Copy font metrics from FOCAFONT, translating foca metrics in device
;   coodinate (FOCAMETRICS) to world coordinate (FONTMETRICS).
;
; Entry:
;   ESI   = foca font    (FOCAFONT structure, same as FontSeg:0000)
;   EDI   = font metrics (FONTMETRICS)
;   EAX   = FunN (COM_* options)
;   EBX   = hddc
;   ECX   = size of font metrics memory block.
; Returns:
;   EAX   = 0
;   ECX   = number of bytes copied into the font metrics memory block.
; Error Returns:
;   EAX   = -1
; Registers Destroyed:
;   EAX,EBX,ECX,EDX,ESI
; Registers Preserved:
;   EDI,EBP
; History:
;  Tue Jun 30          1992     -by-    Hide Muta       [jl25345@ymtvm3]
; Modified for 32 bit flat model.
;-----------------------------------------------------------------------;

ConvertFontMetrics PROC SYSCALL uses EDI
        LOCAL   options       :DWORD,
                hddclo        :DWORD,
                lpFontMetrics :DWORD,
                cbFontMetrics :DWORD,
                Fm[FONTMETRICS] :BYTE

        mov     options,eax              ; keep params in safe place
        mov     hddclo,ebx
        mov     cbFontMetrics,ecx
        mov     lpFontMetrics,edi

; Copy specified foca metrics to font metrics work area.

        lea     esi,[esi].FOCAFONT.ff_fmMetrics.foca_szFamilyname
        lea     edi,Fm.fm_szFamilyname
        INVOKE  move_text_metrics       ; foca metrics --> font metrics

; Modify the copied font metrics, acoording to the options.

        mov     edi,hddclo              ; EDI --> ddc
        lea     esi,Fm                  ; ESI --> font metrics
        INVOKE  DbcsFixFontMetrics      ; fixup resolution related metrics

; If bold simulation is required for the current font, DD should return the
; values which are added one dot by bold simulation of Average Character
; Width, Max Character Increment, and Em Increment (DCR077 on JP12).

        test    [edi].ddc_ca.ca_fs,CA_BOLD
        jz      bold_simulation_done

        inc     [esi].fm_lAveCharWidth
        inc     [esi].fm_lMaxCharInc
        inc     [esi].fm_lEmInc

bold_simulation_done:

; The driver should translate parameters from device coordinate to screen
; coordinate, when COM_TRANSFORM flag is specified and DDC_UNIT_XFORM flag
; is NOT set.

        test    options,COM_TRANSFORM
        jz      transforms_done
        test    [edi].ddc_fb,DDC_UNIT_XFORM
        jnz     transforms_done

        xor     ebx,ebx                 ; EBX = 0, use current transform matrix
        lea     esi,Fm                  ; ESI --> font metrics
        INVOKE  xform_metrics,edi       ; convert to world coordinate
                                        ; stack param = hddc
        jnc     transforms_done

        mov     eax,-1                   ; transformation error!
        jmp     cfm_exit

transforms_done:

; Now copy the metrics back to the client's memory block.

        lea     esi,Fm                  ; ESI --> computed font metrics
        mov     edi,lpFontMetrics       ; EDI --> client's memory block

        mov     ecx,cbFontMetrics
        cmp     ecx,size FONTMETRICS
        jle     move_metrics
        mov     ecx,size FONTMETRICS

move_metrics:
        mov     cbFontMetrics,ecx       ; ECX = number of bytes being copied
        shr     ecx,1
        rep     movs    word ptr [edi],word ptr [esi]
        rcl     ecx,1
        rep     movs    byte ptr [edi],byte ptr [esi]

        xor     eax,eax                 ; successfully ended
        mov     ecx,cbFontMetrics       ; number of bytes copied
cfm_exit:
        ret
ConvertFontMetrics ENDP

page

;---------------------------Internal-Routine----------------------------;
;   move_text_metrics
;
;   moves the font metrics from the PFT to the text_metrics data structure
;
;   Entry:
;       esi --> input font metrics in the pft
;       edi --> target text metrics
;
;-----------------------------------------------------------------------;

 OPTION PROLOGUE:NONE
 OPTION EPILOGUE:NONE

move_text_metrics PROC SYSCALL

; do the fields which are the same
        mov     ecx,(foca_yEmHeight-foca_szFamilyname) / 2
        rep     movsw
        .errnz  (foca_yEmHeight-foca_szFamilyname)-(fm_lEmHeight-fm_szFamilyname)

; move a bunch of words to double words
        mov     ecx,(foca_sCharSlope-foca_yEmHeight) / 2
move_in_first_doubles:
        lodsw                           ; pick up the word
        cwd                             ; store the sign extended result
        stosw
        xchg    dx,ax
        stosw
        loop    move_in_first_doubles
        .errnz  ((foca_sCharSlope-foca_yEmHeight) / 2)-((fm_sCharSlope-fm_lEmHeight) / 4)

        mov     ecx,(foca_ySubscriptXSize-foca_sCharSlope) / 2
        rep     movsw
        .errnz  (foca_ySubscriptXSize-foca_sCharSlope)-(fm_lSubscriptXSize-fm_sCharSlope)

        mov     ecx,(foca_usKerningPairs-foca_ySubscriptXSize) / 2
move_in_last_doubles:
        lodsw                           ; pick up the word
        cwd                             ; store the sign extended result
        stosw
        xchg    dx,ax
        stosw
        loop    move_in_last_doubles
        .errnz  ((foca_usKerningPairs-foca_ySubscriptXSize) / 2)-((fm_sKerningPairs-fm_lSubscriptXSize) / 4)

        movsw                           ; move the foca_usKerningPairs
        movsw                           ; move the foca_usKerningTracks
        mov     eax,-1
        stosd                           ; set the match field to -1

        ret
move_text_metrics ENDP

 OPTION PROLOGUE:PrologueDef
 OPTION EPILOGUE:EpilogueDef

page

;---------------------------Internal-Routine----------------------------;
;   WORD PASCAL   xform_metrics
;
;   Transforms the font metrics
;
;   Entry:
;       EBX  matrix to use(if bx=0 use currrent matrix)
;       ESI  target text metrics to be scaled
;
;   Note:
;       All sizes are returned in world coordinates
;
;   Returns:
;         CF = 0,
;
;   Error Returns:
;         CF = 1
;-----------------------------------------------------------------------;

POINT_COUNT1        equ (foca_sCharSlope-foca_yEmHeight)/2
POINT_COUNT2        equ (foca_usKerningPairs-foca_ySubscriptXSize)/2
POINTS_IN_METRICS   equ (POINT_COUNT1+POINT_COUNT2)

xform_metrics PROC SYSCALL,
                hddclo :DWORD
 LOCAL tmoff  :DWORD
        LOCAL   ptMetrics[(size POINTL * (POINTS_IN_METRICS+1))] :BYTE

 mov tmoff,esi

; zero out the array of metrics, the first point will be 0,0

        lea     edi,ptMetrics

        mov     ecx,(size POINTL * (POINTS_IN_METRICS+1)) / 2
        xor     eax,eax
        rep     stosw

; move back to the secord point in the array

        lea     edi,ptMetrics.size POINTL

; move the heights and widths into the point array so that we can xform
; them. The information in the metrics consists of
;   eight   ys
;   three   xs
;   one     y
;   four    points
;   two     ys

        add     esi,fm_lEmHeight

; move the first eight ys

        .errnz  ((foca_yExternalLeading-foca_yEmHeight)/2)-7
        mov     ecx,((foca_yExternalLeading-foca_yEmHeight) / 2) + 1
move_eight_ys:
        lodsw
        movsx   eax,ax
        mov     [edi].ptl_y,eax
        inc     esi
        inc     esi
        add     edi,size POINTL
        loop    move_eight_ys

; now move the three xs

        mov     ecx,((foca_xEmInc-foca_xAveCharWidth) / 2) + 1
move_three_xs:
        lodsw
        movsx   eax,ax
        mov     [edi].ptl_x,eax
        inc     esi
        inc     esi
        add     edi,size POINTL
        loop    move_three_xs

; move one more y

        lodsw
        movsx   eax,ax
        mov     [edi].ptl_y,eax
        add     edi,size POINTL

        add     esi,2+foca_ySubscriptXSize-foca_sCharSlope

        .errnz  ((foca_xEmInc-foca_xAveCharWidth)/2)-2

; now we have to move four points

        mov     ecx,((foca_ySuperscriptXOffset-foca_ySubscriptXSize)/(size POINTS))+1
move_four_points:
        lodsw
        inc     esi
        inc     esi
        movsx   eax,ax
        mov     [edi].ptl_x,eax
        add     edi,size POINTL
        lodsw
        inc     esi
        inc     esi
        movsx   eax,ax
        mov     [edi].ptl_y,eax
        add     edi,size POINTL
        loop    move_four_points     ; zeros cx

        mov     ecx,((foca_yStrikeoutPosition-foca_yUnderscoreSize)/2)+1

move_four_more_ys:

        lodsw
        inc     esi
        inc     esi
        movsx   eax,ax
        mov     [edi].ptl_y,eax
        add     edi,size POINTL
        loop    move_four_more_ys

; back to the begining

        lea     edi,ptMetrics

; if (bx == 0) transform from DEVICE to WORLD

        push    esi

        mov     esi,hddclo

;       check   Convert,<hdc,lSrc,lTarg,pptl,cptl,hddc,ulFunN>
        INVOKE  PFNDefConvert PTR pfnDefConvert,
                              [esi].ddc_hdc,
                              CVTC_DEVICE,
                              CVTC_WORLD,
                              edi,
                              POINTS_IN_METRICS+1,
                              0,
                              NGreConvert

        pop     esi

        or      eax,eax
        jz      error_xform_metrics

; zero base the points before moving them back

        mov     ecx,POINTS_IN_METRICS

        mov     eax,[edi].ptl_x        ; pick up the original x,y
        mov     ebx,[edi].ptl_y

zero_base_points:
        add     edi,SIZE POINTL
        sub     [edi].ptl_x,eax
        sub     [edi].ptl_y,ebx
        loop    zero_base_points

        jmp     points_are_xformed

error_xform_metrics:
        stc
        jmp     exit_xform_metrics

points_are_xformed:

; ok they are converted so now move them back to the metrics structure

        mov     edi,tmoff
        add     edi,fm_lEmHeight

        lea     esi,ptMetrics.size POINTL

        .errnz  fm_lXHeight-fm_lEmHeight-4
        .errnz  fm_lMaxAscender-fm_lXHeight-4
        .errnz  fm_lMaxDescender-fm_lMaxAscender-4
        .errnz  fm_lLowerCaseAscent-fm_lMaxDescender-4
        .errnz  fm_lLowerCaseDescent-fm_lLowerCaseAscent-4
        .errnz  fm_lInternalLeading-fm_lLowerCaseDescent-4
        .errnz  fm_lExternalLeading-fm_lInternalLeading-4
        .errnz  fm_lAveCharWidth-fm_lExternalLeading-4
        .errnz  fm_lMaxCharInc-fm_lAveCharWidth-4
        .errnz  fm_lEmInc-fm_lMaxCharInc-4
        .errnz  fm_lMaxBaselineExt-fm_lEmInc-4

        mov     ecx,((fm_lMaxBaselineExt-fm_lEmHeight)/4)+1
        assert  ecx,E,12

store_up_to_fm_lMaxBaselineExt:
        INVOKE  get_vector_length
        stosd
        add     esi,size POINTL
        loop    store_up_to_fm_lMaxBaselineExt

        .errnz  fm_sCharSlope-fm_lMaxBaselineExt-4

        add     edi,fm_lSubscriptXSize-fm_sCharSlope

        .errnz  fm_lSubscriptYSize-fm_lSubscriptXSize-4
        .errnz  fm_lSubscriptXOffset-fm_lSubscriptYSize-4
        .errnz  fm_lSubscriptYOffset-fm_lSubscriptXOffset-4
        .errnz  fm_lSuperscriptXSize-fm_lSubscriptYOffset-4
        .errnz  fm_lSuperscriptYSize-fm_lSuperscriptXSize-4
        .errnz  fm_lSuperscriptXOffset-fm_lSuperscriptYSize-4
        .errnz  fm_lSuperscriptYOffset-fm_lSuperscriptXOffset-4
        .errnz  fm_lUnderscoreSize-fm_lSuperscriptYOffset-4
        .errnz  fm_lUnderscorePosition-fm_lUnderscoreSize-4
        .errnz  fm_lStrikeoutSize-fm_lUnderscorePosition-4
        .errnz  fm_lStrikeoutPosition-fm_lStrikeoutSize-4

        mov     ecx,((fm_lStrikeoutPosition-fm_lSubscriptXSize)/4)+1
        assert  ecx,E,12

store_up_to_fm_lStrikeoutPosition:
        INVOKE  get_vector_length
        stosd
        add     esi,size POINTL
        loop    store_up_to_fm_lStrikeoutPosition
        clc

exit_xform_metrics:
        ret
xform_metrics ENDP

end
