int unicodeGetXRanges(char *utf8, int utf8Length, int *resultPtr, int resultLength) { SCRIPT_STRING_ANALYSIS ssa; HDC hdc; int i, pX; HRESULT r; if (utf8Length == 0) return 0; g_wLength = 0; hdc = CreateCompatibleDC(0); ssa = analyze(hdc, utf8, utf8Length); if (ssa != NULL) { for (i = 0; i < g_wLength; i++) { r = ScriptStringCPtoX(ssa, i, FALSE, &pX); if (FAILED(r)) pX = -1; resultPtr[2 * i] = pX; r = ScriptStringCPtoX(ssa, i, TRUE, &pX); if (FAILED(r)) pX = -1; resultPtr[(2 * i) + 1] = pX; } ScriptStringFree(&ssa); } DeleteDC(hdc); return g_wLength; }
//TODO: Double check/ensure this function is only called via the gui thread.. SIZE ProjectTreeItem::GetPreferredSize() { SIZE sz = defaultSize; if(!m_size.cx) { m_size.cy = defaultSize.cy; HDC dc = GetDC(m_parentHwnd); if(dc) { HGDIOBJ oldFont = SelectObject(dc, s_hFont); SetTextAlign(dc, TA_LEFT); loadngo::gui::NativeString title(m_pTask->GetTitle()); const TCHAR *pTitle = title; long strLen = _tcslen(pTitle); SCRIPT_STRING_ANALYSIS ssa; SecureZeroMemory(&ssa, sizeof(SCRIPT_STRING_ANALYSIS)); HRESULT hr = ScriptStringAnalyse(dc, pTitle, strLen, 0, -1, SSA_GLYPHS, 0, 0, 0, 0, 0, 0, &ssa); if(SUCCEEDED(hr)) { sz.cx = ScriptString_pSize(ssa)->cx + 20; ScriptStringFree(&ssa); m_size.cx = sz.cx > defaultSize.cx? sz.cx: defaultSize.cx; } SelectObject(dc, oldFont); ReleaseDC(m_parentHwnd, dc); } } return m_size.cx? m_size: sz; }
void unicodeMeasureString(char *utf8, int utf8Length, int *wPtr, int *hPtr) { SCRIPT_STRING_ANALYSIS ssa; HDC hdc; CONST SIZE *pSize; if (utf8Length == 0) return; hdc = CreateCompatibleDC(0); ssa = analyze(hdc, utf8, utf8Length); if (ssa != NULL) { pSize = ScriptString_pSize(ssa); if (pSize != NULL) { *wPtr = pSize->cx; *hPtr = pSize->cy; } ScriptStringFree(&ssa); } DeleteDC(hdc); }
void unicodeDrawString(char *utf8, int utf8Length, int *wPtr, int *hPtr, unsigned int *bitmapPtr) { SCRIPT_STRING_ANALYSIS ssa; HDC hdc; BITMAPINFO bi; HBITMAP hBitmap; unsigned int *dibBits; HGDIOBJ oldObj; CONST SIZE *pSize; int w = *wPtr; int h = *hPtr; unsigned int *src, *dst, *end; *wPtr = *hPtr = 0; if (utf8Length == 0) return; hdc = CreateCompatibleDC(0); ssa = analyze(hdc, utf8, utf8Length); if (ssa == NULL) goto cleanup; // create a device independent bitmap bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bi.bmiHeader.biWidth = w; bi.bmiHeader.biHeight = -h; // negative indicates top-down bitmap bi.bmiHeader.biPlanes = 1; bi.bmiHeader.biBitCount = 32; bi.bmiHeader.biCompression = BI_RGB; bi.bmiHeader.biSizeImage = 0; bi.bmiHeader.biXPelsPerMeter = 0; bi.bmiHeader.biYPelsPerMeter = 0; bi.bmiHeader.biClrUsed = 0; bi.bmiHeader.biClrImportant = 0; hBitmap = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, &dibBits, NULL, 0); if (hBitmap == NULL) goto cleanup; // attached the bitmap to the context oldObj = SelectObject(hdc, hBitmap); if (oldObj != NULL) { // set fg and bg colors and render the string SetBkColor(hdc, g_bgColor); SetTextColor(hdc, g_fgColor); ScriptStringOut(ssa, 0, 0, 0, NULL, 0, 0, FALSE); pSize = ScriptString_pSize(ssa); if (pSize != NULL) { *wPtr = pSize->cx; *hPtr = pSize->cy; } // copy pixels into Squeak's bitmap src = dibBits; dst = (int *) bitmapPtr; end = dst + (w * h); if (g_bgTransparent && (g_bgRGB != 0)) { // if g_bgTransparent was set, map g_bgRGB to 0 (transparent) while (dst < end) { *dst++ = (*src == g_bgRGB) ? 0 : *src; src++; } } else { while (dst < end) *dst++ = *src++; } SelectObject(hdc, oldObj); } ScriptStringFree(&ssa); DeleteObject(hBitmap); cleanup: DeleteDC(hdc); }
/* * This is a hack used by Chrome and WebKit to expose the fallback font used * by Uniscribe for some given text for use with custom shapers / font engines. */ static char *UniscribeFallback( const char *psz_family, uni_char_t codepoint ) { HDC hdc = NULL; HDC meta_file_dc = NULL; HENHMETAFILE meta_file = NULL; LPTSTR psz_fbuffer = NULL; char *psz_result = NULL; hdc = CreateCompatibleDC( NULL ); if( !hdc ) return NULL; meta_file_dc = CreateEnhMetaFile( hdc, NULL, NULL, NULL ); if( !meta_file_dc ) goto error; LOGFONT lf; memset( &lf, 0, sizeof( lf ) ); psz_fbuffer = ToT( psz_family ); if( !psz_fbuffer ) goto error; _tcsncpy( ( LPTSTR ) &lf.lfFaceName, psz_fbuffer, LF_FACESIZE ); free( psz_fbuffer ); lf.lfCharSet = DEFAULT_CHARSET; HFONT hFont = CreateFontIndirect( &lf ); if( !hFont ) goto error; HFONT hOriginalFont = SelectObject( meta_file_dc, hFont ); TCHAR text = codepoint; SCRIPT_STRING_ANALYSIS script_analysis; HRESULT hresult = ScriptStringAnalyse( meta_file_dc, &text, 1, 0, -1, SSA_METAFILE | SSA_FALLBACK | SSA_GLYPHS | SSA_LINK, 0, NULL, NULL, NULL, NULL, NULL, &script_analysis ); if( SUCCEEDED( hresult ) ) { hresult = ScriptStringOut( script_analysis, 0, 0, 0, NULL, 0, 0, FALSE ); ScriptStringFree( &script_analysis ); } SelectObject( meta_file_dc, hOriginalFont ); DeleteObject( hFont ); meta_file = CloseEnhMetaFile( meta_file_dc ); if( SUCCEEDED( hresult ) ) { LOGFONT log_font; log_font.lfFaceName[ 0 ] = 0; EnumEnhMetaFile( 0, meta_file, MetaFileEnumProc, &log_font, NULL ); if( log_font.lfFaceName[ 0 ] ) psz_result = FromT( log_font.lfFaceName ); } DeleteEnhMetaFile(meta_file); DeleteDC( hdc ); return psz_result; error: if( meta_file_dc ) DeleteEnhMetaFile( CloseEnhMetaFile( meta_file_dc ) ); if( hdc ) DeleteDC( hdc ); return NULL; }