#include #include #include #include #include #include #include #include #include #include #include "fonttest.h" #include "gcp.h" #include "dialogs.h" // #include "resource.h" BOOL bJustify = FALSE; BOOL bListGFLI = FALSE; BOOL bShadowText = FALSE; BOOL bGTEExt = FALSE; BOOL bGCP = FALSE; BOOL bDprintf = FALSE; BOOL bUseKern = FALSE; BOOL bOutString = FALSE; BOOL bUseLPCaret = FALSE; BOOL bUseLPorder = FALSE; BOOL bUseLPdx = FALSE; BOOL bUseGI = FALSE; int iMaxWidth = -1; int iMaxGTEExtWidth = -1; BOOL bReturn_nFit = TRUE; BOOL bPdxPdy = FALSE; extern HWND hwndMode; #define TA_CENTER_ONLY 4 // TA_CENTER==6, TA_RIGHT=2, clever huh! /*****************************************************************************/ void RunExtents(void) { } /*****************************************************************************/ INT_PTR CALLBACK GcpDlgProc( HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ) { case WM_INITDIALOG: { char sz[10] ; CheckDlgButton( hdlg, IDD_LPDX, bUseLPdx ); CheckDlgButton( hdlg, IDD_GI, bUseGI ); CheckDlgButton( hdlg, IDD_SHADOW, bShadowText ); CheckDlgButton( hdlg, IDD_GFLI, bListGFLI ); CheckDlgButton( hdlg, IDD_GCPDPRINTF, bDprintf ); CheckDlgButton( hdlg, IDD_KERNSTRING, bUseKern ); CheckDlgButton( hdlg, IDD_OUTSTRING, bOutString ); CheckDlgButton( hdlg, IDD_JUSTIFY, bJustify ); CheckDlgButton( hdlg, IDD_LPCARET, bUseLPCaret ); CheckDlgButton( hdlg, IDD_LPORDER, bUseLPorder ); wsprintf( sz, "%ld", iMaxWidth ); SetDlgItemText( hdlg, IDD_MAXWIDTH, sz ); return TRUE; } case WM_CLOSE: EndDialog( hdlg, FALSE ); return TRUE; case WM_COMMAND: switch( LOWORD( wParam ) ) { case IDOK: { UINT bTranslated ; int i; i = (int)GetDlgItemInt( hdlg, IDD_MAXWIDTH, &bTranslated, TRUE ); if ( !bTranslated ) { MessageBox(hdlg, "Error in Translation of MaxWidth", NULL, MB_OK ); break; } iMaxWidth = i ; bUseLPorder = IsDlgButtonChecked( hdlg, IDD_LPORDER ); bJustify = IsDlgButtonChecked( hdlg, IDD_JUSTIFY ); bUseLPdx = IsDlgButtonChecked( hdlg, IDD_LPDX) ; bUseLPCaret = IsDlgButtonChecked( hdlg, IDD_LPCARET) ; bUseGI = IsDlgButtonChecked( hdlg, IDD_GI ); bShadowText = IsDlgButtonChecked( hdlg, IDD_SHADOW); bListGFLI = IsDlgButtonChecked( hdlg, IDD_GFLI); bDprintf = IsDlgButtonChecked( hdlg, IDD_GCPDPRINTF ); bUseKern = IsDlgButtonChecked( hdlg, IDD_KERNSTRING ); bOutString = IsDlgButtonChecked( hdlg, IDD_OUTSTRING); bGCP = bUseLPdx | bUseGI; #if 0 if ( (dwRGBTextExt == dwRGBText) || (dwRGBTextExt == dwRGBBackground)) { InvalidateRect( hwndMode, NULL, TRUE ); SendMessage( hwndMain, WM_COMMAND, IDM_SETTEXTEXTCOLOR, 0); } #endif } case IDCANCEL: EndDialog( hdlg, (wParam == IDOK) ); return TRUE; } break; } return FALSE; } /*****************************************************************************/ void doGCP(HDC hdc, int x, int y, LPVOID lpszString, int cbString) { LPSTR lpszStringA = lpszString; LPWSTR lpszStringW = lpszString; DWORD oldColour ; UINT oldMode ; DWORD limitGTE ; DWORD limitGCP ; HBRUSH hbr ; RECT rc ; GCP_RESULTS gcp; DWORD dwFlags ; UINT *pOrder = NULL; LPWSTR pGlyphs = NULL; int *pdx = NULL; PSTR pOutStrA = NULL; PWSTR pOutStrW = NULL; LPSTR lpszOrigA = lpszString; LPWSTR lpszOrigW = lpszString; int *pCaret = NULL; LPINT ReallpDx = NULL; UINT oldAlign; DWORD wETO2 = wETO; oldAlign = SetTextAlign(hdc, wTextAlign); if (bShadowText) { GenExtTextOut( hdc, x, y, 0, NULL, lpszString, cbString, NULL); } if ( bUseLPdx ) { pdx = (int *)LocalAlloc( LPTR, sizeof(int) * cbString ); if ( !pdx ) dprintf( "ERROR: Cant create pdx" ); } if ( bUseLPorder ) { pOrder = (UINT *)LocalAlloc( LPTR, sizeof(int) * cbString ); if ( !pOrder ) dprintf( "ERROR: Cant create pOrder" ); } if ( bUseLPCaret ) { pCaret = (int *)LocalAlloc( LPTR, sizeof(int) * cbString ); if ( !pCaret ) dprintf( "ERROR: Cant create pCaret" ); } if ( bOutString ) { pOutStrA = (PSTR)LocalAlloc( LPTR, sizeof(char) * cbString ); pOutStrW = (PWSTR)LocalAlloc( LPTR, sizeof(WCHAR) * cbString ); if ( !pOutStrA || !pOutStrW ) dprintf( "ERROR: Cant create pOutStr" ); } if ( bUseGI) { pGlyphs = LocalAlloc( LPTR, sizeof(pGlyphs[0]) * cbString ); if ( !pGlyphs ) dprintf( "ERROR: Cant create pGlyphs" ); } { SIZE size; if (!isCharCodingUnicode) GetTextExtentPointA(hdc, lpszStringA, cbString, &size); else GetTextExtentPointW(hdc, lpszStringW, cbString, &size); limitGTE = (DWORD)((USHORT)size.cx | (size.cy << 16)); } dwFlags = GetFontLanguageInfo(hdc); if (bListGFLI) dprintf("GetFontLanguageInfo = %8.8lx", dwFlags); if (!bUseKern) dwFlags &= ~GCP_USEKERNING; if (bJustify) dwFlags |= GCP_JUSTIFY; if (dwFlags & 0x8000) { dprintf("ERROR in GetFontLanguageInfo"); limitGCP = 0L; gcp.lpDx = NULL; gcp.nGlyphs = cbString; } else { if ( iMaxWidth != -1 ) dwFlags |= GCP_MAXEXTENT; gcp.lStructSize = sizeof(gcp); if (!isCharCodingUnicode) gcp.lpOutString = pOutStrA ?(LPSTR)pOutStrA :NULL; else gcp.lpOutString = pOutStrW ?(LPSTR)pOutStrW :NULL; gcp.lpOrder = pOrder ?(UINT far *)pOrder :NULL; gcp.lpCaretPos = pCaret ?(int far *)pCaret :NULL; gcp.lpClass = NULL; gcp.lpGlyphs = pGlyphs ? pGlyphs : NULL; gcp.lpDx = pdx ? (int far *)pdx :NULL; gcp.nMaxFit = 2; gcp.nGlyphs = cbString; if (!isCharCodingUnicode) limitGCP = GetCharacterPlacementA(hdc, lpszStringA, cbString, iMaxWidth, (LPGCP_RESULTSA)&gcp, dwFlags ); else limitGCP = GetCharacterPlacementW(hdc, lpszStringW, cbString, iMaxWidth, (LPGCP_RESULTSW)&gcp, dwFlags ); if (limitGCP == 0) dprintf( "Error: GCP returned NULL, using ETO normally" ); else { ReallpDx = gcp.lpDx; // avoid fonttest drawing bug! if ( (iMaxWidth == -1) && (limitGTE != limitGCP) && !(dwFlags | (GCP_USEKERNING | GCP_JUSTIFY)) ) { dprintf( "ERROR: GTExt Limits: H:%d, W:%d", HIWORD(limitGTE), LOWORD(limitGTE)); dprintf( " GCP Limits: H:%d, W:%d", HIWORD(limitGCP), LOWORD(limitGCP)); } if ( gcp.lpGlyphs ) { wETO2 |= ETO_GLYPH_INDEX ; lpszStringA = (LPSTR)gcp.lpGlyphs; lpszStringW = (LPWSTR)gcp.lpGlyphs; } else if (gcp.lpOutString) { lpszStringA = (LPSTR)gcp.lpOutString; lpszStringW = (LPWSTR)gcp.lpOutString; } cbString = gcp.nMaxFit ; if (bDprintf) { UINT i; dprintf( "idx:str=glyf:dx: caret:order:outstring"); for (i=0; inGlyphs; pBits = LocalAlloc( LMEM_FIXED, nGlyphs*sizeof(int)); for (x=0,i=0; ilpDx[i]; } // // do the first character // switch ( ((wTextAlign & TA_RTLREADING)?1:0) + ((gcp->lpClass[0] == GCPCLASS_HEBREW) ?2:0)) { case 0: dprintf("1st latin,LtoR"); gcp->lpCaretPos[0] = 0; break; case 1: dprintf("1st latin,RtoL"); gcp->lpCaretPos[0] = pBits[gcp->lpOrder[0]]; break; case 2: dprintf("1st hebrew,LtoR"); if (gcp->lpOrder[0] == nGlyphs-1) gcp->lpCaretPos[0] = Width; else gcp->lpCaretPos[0] = pBits[gcp->lpOrder[0]+1]; break; case 3: dprintf("1st hebrew,RtoL"); gcp->lpCaretPos[0] = Width; break; } //NOLASTINGCP//nGlyphs--; //NOLASTINGCP// //NOLASTINGCP//if (nGlyphs) //NOLASTINGCP// { //NOLASTINGCP// // //NOLASTINGCP// // do the last character //NOLASTINGCP// // //NOLASTINGCP// switch ( ((wTextAlign & TA_RTLREADING)?1:0) + //NOLASTINGCP// ((gcp->lpClass[nGlyphs] == GCPCLASS_HEBREW) ?2:0)) //NOLASTINGCP// { //NOLASTINGCP// case 0: //NOLASTINGCP// dprintf("last latin,LtoR"); //NOLASTINGCP// gcp->lpCaretPos[nGlyphs] = Width; //NOLASTINGCP// break; //NOLASTINGCP// //NOLASTINGCP// case 1: //NOLASTINGCP// dprintf("last latin,RtoL"); //NOLASTINGCP// gcp->lpCaretPos[nGlyphs] = pBits[gcp->lpOrder[nGlyphs]+1]; //NOLASTINGCP// break; //NOLASTINGCP// //NOLASTINGCP// case 2: //NOLASTINGCP// dprintf("last hebrew,LtoR"); //NOLASTINGCP// gcp->lpCaretPos[nGlyphs] = pBits[gcp->lpOrder[nGlyphs]]; //NOLASTINGCP// break; //NOLASTINGCP// //NOLASTINGCP// case 3: //NOLASTINGCP// dprintf("last hebrew,RtoL"); //NOLASTINGCP// gcp->lpCaretPos[nGlyphs] = 0; //NOLASTINGCP// break; //NOLASTINGCP// } // // do middle characters // for (i=1; ilpOrder[i]; if (gcp->lpClass[i] == GCPCLASS_HEBREW) { if( ++x == (int)nGlyphs ) { gcp->lpCaretPos[i] = Width; continue; } } gcp->lpCaretPos[i] = pBits[x]; } //NOLASTINGCP// } LocalFree((HANDLE)pBits); } ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// void doGcpCaret(HWND hwnd) { HDC hdc; int *pCaret; LPWSTR pGlyphsLoc; int *pdx; char *pClass; UINT *pOrder; int nString ; int i; HFONT hFont, hFontOld; GCP_RESULTS gcp; DWORD dwFlags ; int height, h; char sz[8]; TEXTMETRIC tm; if( hwndMode != hwndString ) { dprintf( "Only available in String mode"); return ; } nString = lstrlen(szStringA); dprintf( szStringA); hFont = CreateFontIndirectWrapperA( &elfdvA ); if( !hFont ) { dprintf( "Couldn't create font" ); return; } hdc = GetDC( hwnd ); hFontOld = SelectObject( hdc, hFont ); SetDCMapMode( hdc, wMappingMode ); SetBkMode( hdc, OPAQUE ); SetBkColor( hdc, dwRGBBackground ); SetTextAlign( hdc, wTextAlign & TA_RTLREADING); SetTextColor( hdc, dwRGBText ); pCaret = (int *)LocalAlloc(LMEM_FIXED, nString*2); pdx = (int *)LocalAlloc(LMEM_FIXED, nString*2); pGlyphsLoc = LocalAlloc(LMEM_FIXED, nString*sizeof(pGlyphsLoc[0])); pOrder = (UINT*)LocalAlloc(LMEM_FIXED, nString*2); pClass = (char*)LocalAlloc(LMEM_FIXED, nString); gcp.lStructSize = sizeof(gcp); gcp.lpOutString = NULL; gcp.lpOrder = pOrder; gcp.lpCaretPos = pCaret; gcp.lpClass = pClass; gcp.lpGlyphs = pGlyphsLoc; gcp.lpDx = pdx; gcp.nGlyphs = nString; gcp.nMaxFit = 2; dwFlags = GetFontLanguageInfo(hdc) | GCP_DIACRITIC |GCP_LIGATE |GCP_GLYPHSHAPE | GCP_REORDER; dwFlags = GetCharacterPlacement(hdc, szStringA, nString, 0, (LPGCP_RESULTS)&gcp, dwFlags); dprintf( "gcp returned w=%d, h=%d",LOWORD(dwFlags),HIWORD(dwFlags)); ExtTextOut(hdc,10,10,ETO_GLYPH_INDEX,NULL,(LPSTR)pGlyphsLoc,gcp.nGlyphs,pdx); GetTextMetrics(hdc, &tm); if (tm.tmCharSet == HEBREW_CHARSET) doCaretPos(hdc, &gcp, (int)LOWORD(dwFlags)); SelectObject(hdc, GetStockObject(SYSTEM_FONT)); GetTextMetrics(hdc, &tm); height = (h = 10 + HIWORD(dwFlags)) + tm.tmHeight;; SetTextAlign(hdc, TA_CENTER); for (i=0; i