X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d8cde57b8367b4e853fbe45d88ee23cea4a301e9..594f0f5bf1355fb8d58f403d3ebacc1c1767c429:/src/os2/fontutil.cpp diff --git a/src/os2/fontutil.cpp b/src/os2/fontutil.cpp index d36dbb08f5..7fb1ff865c 100644 --- a/src/os2/fontutil.cpp +++ b/src/os2/fontutil.cpp @@ -8,6 +8,10 @@ // Copyright: (c) 1999 Vadim Zeitlin // Licence: wxWindows license /////////////////////////////////////////////////////////////////////////////// +#define DEBUG_PRINTF(NAME) { static int raz=0; \ + printf( #NAME " %i\n",raz); fflush(stdout); \ + raz++; \ + } // ============================================================================ // declarations @@ -17,10 +21,15 @@ // headers // ---------------------------------------------------------------------------- +#ifdef __GNUG__ + #pragma implementation "fontutil.h" +#endif + // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #ifndef WX_PRECOMP + #include "wx/app.h" #include "wx/string.h" #include "wx/log.h" #include "wx/intl.h" @@ -42,405 +51,470 @@ // ---------------------------------------------------------------------------- // convert to/from the string representation: format is -// facename[;charset] +// encodingid;facename[;charset] -bool wxNativeEncodingInfo::FromString(const wxString& s) +bool wxNativeEncodingInfo::FromString( + const wxString& rsStr +) { - wxStringTokenizer tokenizer(s, _T(";")); + wxStringTokenizer vTokenizer(rsStr, _T(";")); + wxString sEncid = vTokenizer.GetNextToken(); + long lEnc; - facename = tokenizer.GetNextToken(); - if ( !facename ) + if (!sEncid.ToLong(&lEnc)) + return FALSE; + encoding = (wxFontEncoding)lEnc; + facename = vTokenizer.GetNextToken(); + if (!facename) return FALSE; - wxString tmp = tokenizer.GetNextToken(); - if ( !tmp ) + wxString sTmp = vTokenizer.GetNextToken(); + + if (!sTmp) { - // default charset (don't use DEFAULT_CHARSET though because of subtle - // Windows 9x/NT differences in handling it) -// TODO: what is this for OS/2? -// charset = ANSI_CHARSET; + charset = 850; } else { - if ( wxSscanf(tmp, _T("%u"), &charset) != 1 ) + if ( wxSscanf(sTmp, _T("%u"), &charset) != 1 ) { // should be a number! return FALSE; } } - return TRUE; -} +} // end of wxNativeEncodingInfo::FromString wxString wxNativeEncodingInfo::ToString() const { - wxString s(facename); -// TODO: what is this for OS/2? -/* - if ( charset != ANSI_CHARSET ) + wxString sStr; + + sStr << (long)encoding << _T(';') << facename; + + if (charset != 850) { - s << _T(';') << charset; + sStr << _T(';') << charset; } -*/ - return s; -} + return sStr; +} // end of wxNativeEncodingInfo::ToString // ---------------------------------------------------------------------------- // helper functions // ---------------------------------------------------------------------------- -bool wxGetNativeFontEncoding(wxFontEncoding encoding, - wxNativeEncodingInfo *info) +bool wxGetNativeFontEncoding( + wxFontEncoding vEncoding +, wxNativeEncodingInfo* pInfo +) { - wxCHECK_MSG( info, FALSE, _T("bad pointer in wxGetNativeFontEncoding") ); - - if ( encoding == wxFONTENCODING_DEFAULT ) + wxCHECK_MSG(pInfo, FALSE, _T("bad pointer in wxGetNativeFontEncoding") ); + if (vEncoding == wxFONTENCODING_DEFAULT) { - encoding = wxFont::GetDefaultEncoding(); + vEncoding = wxFont::GetDefaultEncoding(); } - - switch ( encoding ) + switch (vEncoding) { -// TODO: fix this for OS2 -/* - // although this function is supposed to return an exact match, do do - // some mappings here for the most common case of "standard" encoding - case wxFONTENCODING_SYSTEM: case wxFONTENCODING_ISO8859_1: case wxFONTENCODING_ISO8859_15: - case wxFONTENCODING_CP1252: - info->charset = ANSI_CHARSET; + case wxFONTENCODING_CP1250: + pInfo->charset = 1250; break; - case wxFONTENCODING_CP1250: - info->charset = EASTEUROPE_CHARSET; + case wxFONTENCODING_ISO8859_2: + case wxFONTENCODING_CP1252: + pInfo->charset = 1252; break; - case wxFONTENCODING_CP1251: - info->charset = RUSSIAN_CHARSET; + case wxFONTENCODING_ISO8859_4: + case wxFONTENCODING_ISO8859_10: + pInfo->charset = 921; // what is baltic? break; - case wxFONTENCODING_CP1253: - info->charset = GREEK_CHARSET; + case wxFONTENCODING_ISO8859_5: + case wxFONTENCODING_CP1251: + pInfo->charset = 1251; break; - case wxFONTENCODING_CP1254: - info->charset = TURKISH_CHARSET; + case wxFONTENCODING_ISO8859_6: + pInfo->charset = 864; break; - case wxFONTENCODING_CP1255: - info->charset = HEBREW_CHARSET; + case wxFONTENCODING_ISO8859_7: + pInfo->charset = 869; break; - case wxFONTENCODING_CP1256: - info->charset = ARABIC_CHARSET; + case wxFONTENCODING_ISO8859_8: + pInfo->charset = 862; break; - case wxFONTENCODING_CP1257: - info->charset = BALTIC_CHARSET; + case wxFONTENCODING_ISO8859_9: + pInfo->charset = 857; break; - case wxFONTENCODING_CP874: - info->charset = THAI_CHARSET; + case wxFONTENCODING_ISO8859_11: + pInfo->charset = 874; // what is thai break; case wxFONTENCODING_CP437: - info->charset = OEM_CHARSET; + pInfo->charset = 437; break; -*/ + default: - // no way to translate this encoding into a Windows charset - return FALSE; - } + wxFAIL_MSG(wxT("unsupported encoding")); + // fall through + case wxFONTENCODING_SYSTEM: + pInfo->charset = 850; + break; + } return TRUE; -} +} // end of wxGetNativeFontEncoding -bool wxTestFontEncoding(const wxNativeEncodingInfo& info) +bool wxTestFontEncoding( + const wxNativeEncodingInfo& rInfo +) { - // TODO: - /* - // try to create such font - LOGFONT lf; - wxZeroMemory(lf); // all default values - - lf.lfCharSet = info.charset; - strncpy(lf.lfFaceName, info.facename, sizeof(lf.lfFaceName)); - - HFONT hfont = ::CreateFontIndirect(&lf); - if ( !hfont ) + FATTRS vLogFont; + HPS hPS; + + hPS = ::WinGetPS(HWND_DESKTOP); + + memset(&vLogFont, '\0', sizeof(FATTRS)); // all default values + vLogFont.usRecordLength = sizeof(FATTRS); + vLogFont.usCodePage = rInfo.charset; + vLogFont.lMaxBaselineExt = 0L; // Outline fonts should use 0 + vLogFont.lAveCharWidth = 0L; // Outline fonts should use 0 + vLogFont.fsFontUse = FATTR_FONTUSE_OUTLINE | // only outline fonts allowed + FATTR_FONTUSE_TRANSFORMABLE; // may be transformed + + strncpy(vLogFont.szFacename, rInfo.facename.c_str(), sizeof(vLogFont.szFacename)); + + if (!::GpiCreateLogFont( hPS + ,NULL + ,1L + ,&vLogFont + )) { - // no such font + ::WinReleasePS(hPS); return FALSE; } - - ::DeleteObject((HGDIOBJ)hfont); -*/ + ::WinReleasePS(hPS); return TRUE; -} +} // end of wxTestFontEncoding // ---------------------------------------------------------------------------- // wxFont <-> LOGFONT conversion // ---------------------------------------------------------------------------- -#if 0 -void wxFillLogFont(LOGFONT *logFont, const wxFont *font) +void wxFillLogFont( + LOGFONT* pLogFont // OS2 GPI FATTRS +, PFACENAMEDESC pFaceName +, const wxFont* pFont +) { - int ff_family; - wxString ff_face; - - switch ( font->GetFamily() ) + wxString sFace; + USHORT uWeight; + int nItalic; + + pLogFont->fsSelection = 0; + pLogFont->fsSelection = FATTR_SEL_OUTLINE; // we will alway use only outlines + pFaceName->usWeightClass = 0; + pFaceName->flOptions = 0; + switch (pFont->GetFamily()) { case wxSCRIPT: - ff_family = FF_SCRIPT; - ff_face = _T("Script"); + sFace = _T("Script"); break; case wxDECORATIVE: - ff_family = FF_DECORATIVE; - break; - case wxROMAN: - ff_family = FF_ROMAN; - ff_face = _T("Times New Roman"); + sFace = _T("Times New Roman"); break; case wxTELETYPE: case wxMODERN: - ff_family = FF_MODERN; - ff_face = _T("Courier New"); + sFace = _T("Courier New"); break; case wxSWISS: - ff_family = FF_SWISS; - ff_face = _T("Arial"); + sFace = _T("WarpSans"); break; case wxDEFAULT: default: - ff_family = FF_SWISS; - ff_face = _T("MS Sans Serif"); + sFace = _T("Helv"); } - BYTE ff_italic; - switch ( font->GetStyle() ) - { - case wxITALIC: - case wxSLANT: - ff_italic = 1; - break; - - default: - wxFAIL_MSG(wxT("unknown font slant")); - // fall through - - case wxNORMAL: - ff_italic = 0; - } - - int ff_weight; - switch ( font->GetWeight() ) + switch (pFont->GetWeight()) { default: wxFAIL_MSG(_T("unknown font weight")); - // fall through + uWeight = FWEIGHT_DONT_CARE; + break; case wxNORMAL: - ff_weight = FW_NORMAL; + uWeight = FWEIGHT_NORMAL; break; case wxLIGHT: - ff_weight = FW_LIGHT; + uWeight = FWEIGHT_LIGHT; break; case wxBOLD: - ff_weight = FW_BOLD; + uWeight = FWEIGHT_BOLD; + pLogFont->fsSelection |= FATTR_SEL_BOLD; + break; + + case wxFONTWEIGHT_MAX: + uWeight = FWEIGHT_ULTRA_BOLD; + pLogFont->fsSelection |= FATTR_SEL_BOLD; break; } + pFaceName->usWeightClass |= uWeight; -#if 0 - HDC dc = ::GetDC(NULL); - int ppInch = ::GetDeviceCaps(dc, LOGPIXELSY); - ::ReleaseDC(NULL, dc); -#else - // New behaviour: apparently ppInch varies according to Large/Small Fonts - // setting in Windows. This messes up fonts. So, set ppInch to a constant - // 96 dpi. - static const int ppInch = 96; -#endif // 0/1 - -#if wxFONT_SIZE_COMPATIBILITY - // Incorrect, but compatible with old wxWindows behaviour - int nHeight = (font->GetPointSize()*ppInch/72); -#else - // Correct for Windows compatibility - int nHeight = - (font->GetPointSize()*ppInch/72); -#endif + switch (pFont->GetStyle()) + { + case wxITALIC: + case wxSLANT: + nItalic = FTYPE_ITALIC; + pLogFont->fsSelection |= FATTR_SEL_ITALIC; + break; + + default: + wxFAIL_MSG(wxT("unknown font slant")); + // fall through - wxString facename = font->GetFaceName(); - if ( !!facename ) + case wxNORMAL: + nItalic = 0; + break; + } + pFaceName->flOptions |= nItalic; + if(pFont->GetUnderlined()) + pLogFont->fsSelection |= FATTR_SEL_UNDERSCORE; + + // + // In PM a font's height is expressed in points. A point equals + // approximately 1/72 of an inch. We'll assume for now that, + // like Windows, that fonts are 96 dpi. + // + DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L}; + HDC hDC = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE); + LONG lStart = CAPS_FAMILY; + LONG lCount = CAPS_VERTICAL_RESOLUTION; + LONG alArray[CAPS_VERTICAL_RESOLUTION]; + LONG lRes; + int nPpInch; + + + ::DevQueryCaps(hDC, lStart, lCount, alArray); + lRes = alArray[CAPS_VERTICAL_RESOLUTION-1]; + if (lRes > 0) + nPpInch = (int)(lRes/39.6); // lres is in pixels per meter + else + nPpInch = 96; + + int nHeight = (pFont->GetPointSize() * nPpInch/72); + wxString sFacename = pFont->GetFaceName(); + + if (!!sFacename) { - ff_face = facename; + sFace = sFacename; } //else: ff_face is a reasonable default facename for this font family - // deal with encoding now - wxNativeEncodingInfo info; - wxFontEncoding encoding = font->GetEncoding(); - if ( !wxGetNativeFontEncoding(encoding, &info) ) + // + // Deal with encoding now + // + wxNativeEncodingInfo vInfo; + wxFontEncoding vEncoding = pFont->GetEncoding(); + + if (!wxGetNativeFontEncoding( vEncoding + ,&vInfo + )) { - if ( !wxTheFontMapper->GetAltForEncoding(encoding, &info) ) + if ( !wxTheFontMapper->GetAltForEncoding( vEncoding + ,&vInfo + )) { - // unsupported encoding, replace with the default - info.charset = ANSI_CHARSET; + // + // Unsupported encoding, replace with the default + // + vInfo.charset = 850; } } - if ( !info.facename.IsEmpty() ) + if (!vInfo.facename.IsEmpty() ) { - // the facename determined by the encoding overrides everything else - ff_face = info.facename; + // + // The facename determined by the encoding overrides everything else + // + sFace = vInfo.facename; } - // transfer all the data to LOGFONT - logFont->lfHeight = nHeight; - logFont->lfWidth = 0; - logFont->lfEscapement = 0; - logFont->lfOrientation = 0; - logFont->lfWeight = ff_weight; - logFont->lfItalic = ff_italic; - logFont->lfUnderline = (BYTE)font->GetUnderlined(); - logFont->lfStrikeOut = 0; - logFont->lfCharSet = info.charset; - logFont->lfOutPrecision = OUT_DEFAULT_PRECIS; - logFont->lfClipPrecision = CLIP_DEFAULT_PRECIS; - logFont->lfQuality = PROOF_QUALITY; - logFont->lfPitchAndFamily = DEFAULT_PITCH | ff_family; - wxStrncpy(logFont->lfFaceName, ff_face, WXSIZEOF(logFont->lfFaceName)); -} - -wxFont wxCreateFontFromLogFont(const LOGFONT *logFont) + // + // Transfer all the data to LOGFONT + // + pLogFont->usRecordLength = sizeof(FATTRS); + wxStrcpy(pLogFont->szFacename, sFace.c_str()); + pLogFont->usCodePage = vInfo.charset; + pLogFont->fsFontUse |= FATTR_FONTUSE_OUTLINE | + FATTR_FONTUSE_TRANSFORMABLE; +} // end of wxFillLogFont + +wxFont wxCreateFontFromLogFont( + const LOGFONT* pLogFont +, const PFONTMETRICS pFM +, PFACENAMEDESC pFaceName +) { - // extract family from pitch-and-family - int lfFamily = logFont->lfPitchAndFamily; - if ( lfFamily & FIXED_PITCH ) - lfFamily -= FIXED_PITCH; - if ( lfFamily & VARIABLE_PITCH ) - lfFamily -= VARIABLE_PITCH; - - int fontFamily; - switch ( lfFamily ) - { - case FF_ROMAN: - fontFamily = wxROMAN; - break; - - case FF_SWISS: - fontFamily = wxSWISS; - break; - - case FF_SCRIPT: - fontFamily = wxSCRIPT; - break; - - case FF_MODERN: - fontFamily = wxMODERN; - break; - - case FF_DECORATIVE: - fontFamily = wxDECORATIVE; - break; + // + // Extract family from facename + // + int nFontFamily; + + if (strcmp(pLogFont->szFacename, "Times New Roman") == 0) + nFontFamily = wxROMAN; + else if (strcmp(pLogFont->szFacename, "WarpSans") == 0) + nFontFamily = wxSWISS; + else if (strcmp(pLogFont->szFacename, "Script") == 0) + nFontFamily = wxSCRIPT; + else if (strcmp(pLogFont->szFacename, "Courier New") == 0) + nFontFamily = wxMODERN; + else + nFontFamily = wxSWISS; - default: - fontFamily = wxSWISS; - } + // + // Weight and Style + // + int nFontWeight = wxNORMAL; - // weight and style - int fontWeight = wxNORMAL; - switch ( logFont->lfWeight ) + switch (pFaceName->usWeightClass) { - case FW_LIGHT: - fontWeight = wxLIGHT; + case FWEIGHT_LIGHT: + nFontWeight = wxLIGHT; break; default: - case FW_NORMAL: - fontWeight = wxNORMAL; + case FWEIGHT_NORMAL: + nFontWeight = wxNORMAL; break; - case FW_BOLD: - fontWeight = wxBOLD; + case FWEIGHT_BOLD: + nFontWeight = wxBOLD; break; } - int fontStyle = logFont->lfItalic ? wxITALIC : wxNORMAL; - - bool fontUnderline = logFont->lfUnderline != 0; + int nFontStyle; - wxString fontFace = logFont->lfFaceName; - - // font size - HDC dc = ::GetDC(NULL); - - // remember that 1pt = 1/72inch - int height = abs(logFont->lfHeight); - int fontPoints = (72*height)/GetDeviceCaps(dc, LOGPIXELSY); + if(pLogFont->fsSelection & FATTR_SEL_ITALIC) + nFontStyle = wxITALIC; + else + nFontStyle = wxNORMAL; - ::ReleaseDC(NULL, dc); + bool bFontUnderline = (pLogFont->fsSelection & FATTR_SEL_UNDERSCORE); + wxString sFontFace = pLogFont->szFacename; + int nFontPoints = pFM->lEmHeight; + wxFontEncoding vFontEncoding; - wxFontEncoding fontEncoding; - switch ( logFont->lfCharSet ) + switch (pLogFont->usCodePage) { default: wxFAIL_MSG(wxT("unsupported charset")); // fall through - case ANSI_CHARSET: - fontEncoding = wxFONTENCODING_CP1252; + case 850: + vFontEncoding = wxFONTENCODING_CP1252; break; -#ifdef __WIN32__ - case EASTEUROPE_CHARSET: - fontEncoding = wxFONTENCODING_CP1250; + case 1250: + vFontEncoding = wxFONTENCODING_CP1250; break; - case BALTIC_CHARSET: - fontEncoding = wxFONTENCODING_CP1257; + case 921: + vFontEncoding = wxFONTENCODING_CP1257; break; - case RUSSIAN_CHARSET: - fontEncoding = wxFONTENCODING_CP1251; + case 866: + vFontEncoding = wxFONTENCODING_CP1251; break; - case ARABIC_CHARSET: - fontEncoding = wxFONTENCODING_CP1256; + case 864: + vFontEncoding = wxFONTENCODING_CP1256; break; - case GREEK_CHARSET: - fontEncoding = wxFONTENCODING_CP1253; + case 869: + vFontEncoding = wxFONTENCODING_CP1253; break; - case HEBREW_CHARSET: - fontEncoding = wxFONTENCODING_CP1255; + case 862: + vFontEncoding = wxFONTENCODING_CP1255; break; - case TURKISH_CHARSET: - fontEncoding = wxFONTENCODING_CP1254; + case 857: + vFontEncoding = wxFONTENCODING_CP1254; break; - case THAI_CHARSET: - fontEncoding = wxFONTENCODING_CP437; + case 874: + vFontEncoding = wxFONTENCODING_CP437; break; -#endif - case OEM_CHARSET: - fontEncoding = wxFONTENCODING_CP437; + case 437: + vFontEncoding = wxFONTENCODING_CP437; break; } - return wxFont(fontPoints, fontFamily, fontStyle, - fontWeight, fontUnderline, fontFace, - fontEncoding); + return wxFont( nFontPoints + ,nFontFamily + ,nFontStyle + ,nFontWeight + ,bFontUnderline + ,sFontFace + ,vFontEncoding + ); +} // end of wxCreateFontFromLogFont + +int wxGpiStrcmp( + char* s0 +, char* s1 +) +{ int l0; + int l1; + int l; + int d; + int d1; + int i; + int rc; + + rc = 0; + if(s0 == NULL) + { + if(s1 == NULL) + return 0; + else + return 32; + } + else if(s1 == NULL) + return 32; + + l0 = strlen(s0); + l1 = strlen(s1); + l = l0; + if(l0 != l1) + { + rc++; + if(l1 < l0) + l = l1; + } + for(i=0;i