void CValueAxis::RecalcRect(RECT& rect) { HDC hdc = ::GetDC(NULL); HFONT hFont; if (m_spTickFont != NULL) { CComPtr<IFont> pFont; m_spTickFont->QueryInterface(IID_IFont, (void**)&pFont); pFont->get_hFont(&hFont); } else { hFont = (HFONT)::GetStockObject(DEFAULT_GUI_FONT); } HFONT hOldFont = (HFONT)::SelectObject(hdc, hFont); int nCharWidth; GetCharWidth32(hdc, UINT('8'), UINT('8'), &nCharWidth); ::SelectObject(hdc, hOldFont); ::ReleaseDC(NULL, hdc); CopyRect(&m_rect, &rect); m_rect.right = min(m_rect.left + (m_bShowAxis ? nCharWidth * m_iWholeDigits + 8 : 0), rect.right); rect.left = m_rect.right; }
inline void calculateTTFGlyphWidth(HDC hdc, UINT glyph, int &width) { #if defined(Q_WS_WINCE) GetCharWidth32(hdc, glyph, glyph, &width); #else if (ptrGetCharWidthI) ptrGetCharWidthI(hdc, glyph, 1, 0, &width); #endif }
bool MakeBitFont(const iStringT& face_name, sint32 siz, LONG style, const iStringT& fname) { iStringT pngName = fname+_T(".png"); printf("%s (%s) : ",face_name.CStr(),fname.CStr()); /* if (iFile::Exists(pngName)){ printf("Already exists. Skiped...\n"); return false; }*/ HFONT hFont = CreateFont(siz,0,0,0, style, FALSE, FALSE, FALSE, RUSSIAN_CHARSET, OUT_RASTER_PRECIS, CLIP_STROKE_PRECIS, NONANTIALIASED_QUALITY, DEFAULT_PITCH, face_name.CStr()); iMemoryDC memDC(iSize(4096,128)); memDC.SetFont(hFont); // calculate widths for whole table int *fntW = new int[0xFFFF]; if (!GetCharWidth32(memDC,0,0xFFFF,fntW)) { printf("Error: 0x%X\n",GetLastError()); return false; } // calculate total width of all required characters int tw=0; for (uint32 cc=0; cc<CHS_COUNT; ++cc) { for (uint32 xx=CHARSET_TABLES[cc][0]; xx<=CHARSET_TABLES[cc][1]; ++xx) tw += (fntW[xx]); } // Prepare text metrics and dib TEXTMETRIC tm; GetTextMetrics(memDC,&tm); memDC.Resize(iSize(tw,tm.tmHeight+3)); memDC.m_Dib.Fill(cColorBlack, BLEND_SRCCOPY); memDC.SetFont(hFont); memDC.SetTextBkMode(TRANSPARENT); int px=0; for (cc=0; cc<CHS_COUNT; ++cc) { for (uint32 xx=CHARSET_TABLES[cc][0]; xx<=CHARSET_TABLES[cc][1]; ++xx) { ComposeCharacter(memDC, xx, px, fntW[xx]); px += (fntW[xx]); } } iDibColorChannel::FillChannel(memDC.m_Dib, Channel_Alpha, 0xFF); if (!iDibSaver::SavePNG(memDC.m_Dib,pngName)){ printf("Error! Unable to save png file!\n"); return false; } printf("Done!\n"); return true; }
//Define our load() function- loads up the font and gets it ready for use bool DIZ_FONT::load() { //Declare font handles for the font we want to use and whatever's currently in use HFONT font, oldFont; //Generate display lists for our font starting with our base value base = glGenLists(255); //Create a new font using our specified font info font = CreateFont( info.height, info.width, info.escAng, info.orientation, info.weight, info.italic, info.underline, info.strikeout, info.charSet, info.outPrecis, info.clipPrecis, info.outQuality, info.family, info.font); //Select our new font to use in our Device Context oldFont = (HFONT)SelectObject(*hDC, font); //Check what type of font we want if (info.type == DIZ_FONT_BITMAP) { //If we want a Bitmap font, create that wglUseFontBitmaps( *hDC, //Device Context to get the font from 32, //Starting character we want to use 96, //How many characters to create base); //Start point of our display lists //Since this font type doesn't retrieve glyph metrics, it can be handy to retrieve some character info anyway GetCharWidth32(*hDC, 0, 255, info.charWidths); }else if (info.type == DIZ_FONT_OUTLINE) { //Or if we want an Outline font, create that wglUseFontOutlines( *hDC, //Device Context to get the font from 0, //Start character 255, //Number of characters to create base, //Starting display list info.deviation, //Our deviation from the true outline info.thickness, //Thickness (Z-direction) of font info.outlineType, //Type of outline to create gmf); //GMF info array } //Now that we're done, set the Device's font back to whatever it was before SelectObject(*hDC, oldFont); //Then delete the object we created DeleteObject(font); //And exit return true; }
void initGLBitmapFont(u8 firstGlyph, u8 lastGlyph) { beginGL(); SelectObject (dcHandle, GetStockObject (SYSTEM_FONT) ); font.nglyph = lastGlyph-firstGlyph+1; font.widths = new unsigned int [font.nglyph]; GLuint listBase = glGenLists(font.nglyph); font.firstGlyph = firstGlyph; font.listBase = listBase - firstGlyph; GetCharWidth32( dcHandle, font.firstGlyph, lastGlyph, (LPINT) font.widths ); wglUseFontBitmaps(dcHandle, font.firstGlyph, font.nglyph, listBase); endGL(); }
BOOL IsUnicodeFullWidth( IN WCHAR wch ) { if (0x20 <= wch && wch <= 0x7e) /* ASCII */ return FALSE; else if (0x3041 <= wch && wch <= 0x3094) /* Hiragana */ return TRUE; else if (0x30a1 <= wch && wch <= 0x30f6) /* Katakana */ return TRUE; else if (0x3105 <= wch && wch <= 0x312c) /* Bopomofo */ return TRUE; else if (0x3131 <= wch && wch <= 0x318e) /* Hangul Elements */ return TRUE; else if (0xac00 <= wch && wch <= 0xd7a3) /* Korean Hangul Syllables */ return TRUE; else if (0xff01 <= wch && wch <= 0xff5e) /* Fullwidth ASCII variants */ return TRUE; else if (0xff61 <= wch && wch <= 0xff9f) /* Halfwidth Katakana variants */ return FALSE; else if ( (0xffa0 <= wch && wch <= 0xffbe) || (0xffc2 <= wch && wch <= 0xffc7) || (0xffca <= wch && wch <= 0xffcf) || (0xffd2 <= wch && wch <= 0xffd7) || (0xffda <= wch && wch <= 0xffdc) ) /* Halfwidth Hangule variants */ return FALSE; else if (0xffe0 <= wch && wch <= 0xffe6) /* Fullwidth symbol variants */ return TRUE; else if (0x4e00 <= wch && wch <= 0x9fa5) /* Han Ideographic */ return TRUE; else if (0xf900 <= wch && wch <= 0xfa2d) /* Han Ideographic Compatibility */ return TRUE; else { #if 0 /* * Hack this block for I don't know FONT of Console Window. * * If you would like perfect result from IsUnicodeFullWidth routine, * then you should enable this block and * you should know FONT of Console Window. */ INT Width; TEXTMETRIC tmi; /* Unknown character */ GetTextMetricsW(hDC, &tmi); if (IS_ANY_DBCS_CHARSET(tmi.tmCharSet)) tmi.tmMaxCharWidth /= 2; GetCharWidth32(hDC, wch, wch, &Width); if (Width == tmi.tmMaxCharWidth) return FALSE; else if (Width == tmi.tmMaxCharWidth*2) return TRUE; #else ULONG MultiByteSize; RtlUnicodeToMultiByteSize(&MultiByteSize, &wch, sizeof(WCHAR)); if (MultiByteSize == 2) return TRUE ; else return FALSE ; #endif } ASSERT(FALSE); return FALSE; #if 0 ULONG MultiByteSize; RtlUnicodeToMultiByteSize(&MultiByteSize, &wch, sizeof(WCHAR)); if (MultiByteSize == 2) return TRUE ; else return FALSE ; #endif }
bool osd_font_windows::get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs) { // create a dummy DC to work with HDC dummyDC = CreateCompatibleDC(NULL); HGDIOBJ oldfont = SelectObject(dummyDC, m_font); // get the text metrics TEXTMETRIC metrics = { 0 }; GetTextMetrics(dummyDC, &metrics); // get the width of this character ABC abc; if (!GetCharABCWidths(dummyDC, chnum, chnum, &abc)) { abc.abcA = 0; abc.abcC = 0; GetCharWidth32(dummyDC, chnum, chnum, reinterpret_cast<LPINT>(&abc.abcB)); } width = abc.abcA + abc.abcB + abc.abcC; // determine desired bitmap size int bmwidth = (50 + abc.abcA + abc.abcB + abc.abcC + 50 + 31) & ~31; int bmheight = 50 + metrics.tmHeight + 50; // describe the bitmap we want BYTE bitmapinfodata[sizeof(BITMAPINFOHEADER)+2 * sizeof(RGBQUAD)] = { 0 }; BITMAPINFO &info = *reinterpret_cast<BITMAPINFO *>(bitmapinfodata); info.bmiHeader.biSize = sizeof(info.bmiHeader); info.bmiHeader.biWidth = bmwidth; info.bmiHeader.biHeight = -bmheight; info.bmiHeader.biPlanes = 1; info.bmiHeader.biBitCount = 1; info.bmiHeader.biCompression = BI_RGB; info.bmiHeader.biSizeImage = 0; info.bmiHeader.biXPelsPerMeter = GetDeviceCaps(dummyDC, HORZRES) / GetDeviceCaps(dummyDC, HORZSIZE); info.bmiHeader.biYPelsPerMeter = GetDeviceCaps(dummyDC, VERTRES) / GetDeviceCaps(dummyDC, VERTSIZE); info.bmiHeader.biClrUsed = 0; info.bmiHeader.biClrImportant = 0; RGBQUAD col1 = info.bmiColors[0]; RGBQUAD col2 = info.bmiColors[1]; col1.rgbBlue = col1.rgbGreen = col1.rgbRed = 0x00; col2.rgbBlue = col2.rgbGreen = col2.rgbRed = 0xff; // create a DIB to render to BYTE *bits; HBITMAP dib = CreateDIBSection(dummyDC, &info, DIB_RGB_COLORS, reinterpret_cast<VOID **>(&bits), NULL, 0); if (dib) { HGDIOBJ oldbitmap = SelectObject(dummyDC, dib); // clear the bitmap int rowbytes = bmwidth / 8; memset(bits, 0, rowbytes * bmheight); // now draw the character WCHAR tempchar = chnum; SetTextColor(dummyDC, RGB(0xff, 0xff, 0xff)); SetBkColor(dummyDC, RGB(0x00, 0x00, 0x00)); ExtTextOutW(dummyDC, 50 + abc.abcA, 50, ETO_OPAQUE, NULL, &tempchar, 1, NULL); // characters are expected to be full-height rectangle actbounds; actbounds.min_y = 50; actbounds.max_y = 50 + metrics.tmHeight - 1; // determine the actual left of the character for (actbounds.min_x = 0; actbounds.min_x < rowbytes; actbounds.min_x++) { BYTE *offs = bits + actbounds.min_x; UINT8 summary = 0; for (int y = 0; y < bmheight; y++) summary |= offs[y * rowbytes]; if (summary != 0) { actbounds.min_x *= 8; if (!(summary & 0x80)) actbounds.min_x++; if (!(summary & 0xc0)) actbounds.min_x++; if (!(summary & 0xe0)) actbounds.min_x++; if (!(summary & 0xf0)) actbounds.min_x++; if (!(summary & 0xf8)) actbounds.min_x++; if (!(summary & 0xfc)) actbounds.min_x++; if (!(summary & 0xfe)) actbounds.min_x++; break; } } // determine the actual right of the character for (actbounds.max_x = rowbytes - 1; actbounds.max_x >= 0; actbounds.max_x--) { BYTE *offs = bits + actbounds.max_x; UINT8 summary = 0; for (int y = 0; y < bmheight; y++) summary |= offs[y * rowbytes]; if (summary != 0) { actbounds.max_x *= 8; if (summary & 0x7f) actbounds.max_x++; if (summary & 0x3f) actbounds.max_x++; if (summary & 0x1f) actbounds.max_x++; if (summary & 0x0f) actbounds.max_x++; if (summary & 0x07) actbounds.max_x++; if (summary & 0x03) actbounds.max_x++; if (summary & 0x01) actbounds.max_x++; break; } } // allocate a new bitmap if (actbounds.max_x >= actbounds.min_x && actbounds.max_y >= actbounds.min_y) { bitmap.allocate(actbounds.max_x + 1 - actbounds.min_x, actbounds.max_y + 1 - actbounds.min_y); // copy the bits into it for (int y = 0; y < bitmap.height(); y++) { UINT32 *dstrow = &bitmap.pix32(y); UINT8 *srcrow = &bits[(y + actbounds.min_y) * rowbytes]; for (int x = 0; x < bitmap.width(); x++) { int effx = x + actbounds.min_x; dstrow[x] = ((srcrow[effx / 8] << (effx % 8)) & 0x80) ? rgb_t(0xff, 0xff, 0xff, 0xff) : rgb_t(0x00, 0xff, 0xff, 0xff); } } // set the final offset values xoffs = actbounds.min_x - (50 + abc.abcA); yoffs = actbounds.max_y - (50 + metrics.tmAscent); } // de-select the font and release the DC SelectObject(dummyDC, oldbitmap); DeleteObject(dib); } SelectObject(dummyDC, oldfont); DeleteDC(dummyDC); return bitmap.valid(); }
CDrawContext::FontInfo * CDrawContext::GetFont( const FontDef &fdef ) // // Create a font. If the font already exists in our map of fonts then we use that // if the font does not exist then we create it. { FontInfo **ppInfo = m_mapFonts.Lookup( fdef ); if( ppInfo ) { return (*ppInfo); } LOGFONT lf = {0}; (void)_tcscpy( lf.lfFaceName, fdef.m_szFontName ); lf.lfWeight = fdef.m_nWeight; lf.lfHeight = fdef.m_nSizePixels; lf.lfItalic = fdef.m_bItalic; lf.lfUnderline = fdef.m_bUnderline; lf.lfStrikeOut = fdef.m_bStrike; lf.lfQuality = DRAFT_QUALITY; lf.lfCharSet = fdef.m_cCharSet; lf.lfOutPrecision = OUT_TT_ONLY_PRECIS; FontInfo *pInfo = new FontInfo; pInfo->hFont = CreateFontIndirect( &lf ); // // Get and store the widths of the individual characters, these are used // later when calculating the lengths of text in pixels. HGDIOBJ hFontOld = ::SelectObject( m_hdc, pInfo->hFont ); // // Store some extra bits and pieces. TEXTMETRIC tm; GetTextMetrics( m_hdc, &tm ); pInfo->m_nBaseline = tm.tmAscent; pInfo->m_nLineSpace = tm.tmHeight + tm.tmExternalLeading; if( fdef.m_bUnderline ) pInfo->m_nLineSpace++; ABC abcWids[ countof( pInfo->m_nWidths ) ]; memset( abcWids, 0, sizeof( abcWids ) ); if( GetCharABCWidths( m_hdc, 0, countof( pInfo->m_nWidths ) - 1, abcWids ) ) { ABC *pABC = &abcWids[0]; int *parrWidths = pInfo->m_nWidths; if( tm.tmOverhang ) { int *parrOverhang = pInfo->m_nOverhang; for( UINT n = 0; n < countof( pInfo->m_nWidths ) ; n++, pABC++ ) { *parrWidths++ = ( pABC->abcA + pABC->abcB + pABC->abcC ); *parrOverhang++ = pABC->abcC; } } else { for( UINT n = 0; n < countof( pInfo->m_nWidths ) ; n++, pABC++ ) { *parrWidths++ = ( pABC->abcA + pABC->abcB + pABC->abcC ); } memset( pInfo->m_nOverhang, 0, sizeof( pInfo->m_nOverhang ) ); } } else { int *parrWidths = pInfo->m_nWidths; if( !GetCharWidth32( m_hdc, 0, 255, parrWidths ) ) { SIZE size; TCHAR ch = 0; for( UINT n = 0; n < 255; n++ ) { ch = (TCHAR)n; GetTextExtentPoint32( m_hdc, &ch, 1, &size ); *parrWidths++ = size.cx; } } memset( pInfo->m_nOverhang, 0, sizeof( pInfo->m_nOverhang ) ); } ::SelectObject( m_hdc, hFontOld ); // // And finally add the font to our cache. if( pInfo->hFont ) m_arrObjToDelete.Add( pInfo->hFont ); m_mapFonts.SetAt( fdef, pInfo ); return pInfo; }
void CreateFontData(HDC hDC, int& width, int& height, unsigned char*& texels, float characterData[257]) { // Get the height of the font. TEXTMETRIC metric; GetTextMetrics(hDC, &metric); height = (int)metric.tmHeight; // Compute the width needed for all 256 characters, taking into account // the extra pixel we place at the left side of each character's image. width = 0; for (int i = 0; i < 256; i++) { int charWidth; GetCharWidth32(hDC, i, i, &charWidth); width += (charWidth + 1); } texels = new unsigned char[width*height]; // The character data stores textures coordinates in the x-direction. float const dx = 1.0f/width; int start = 0; characterData[0] = 0.5f*dx; RECT r; r.left = 0; r.top = 0; r.right = 4*metric.tmHeight; r.bottom = 2*metric.tmHeight; for (int i = 0; i < 256; ++i) { wchar_t msg[256]; wsprintf(msg, L"character %d", i); TextOut(hDC, 768, 3*height, msg, static_cast<int>(wcslen(msg))); // Determine how many bytes wide the character will be. int charWidth; GetCharWidth32(hDC, i, i, &charWidth); // Place a blank pixel at the start of each character. ++charWidth; int end = start + charWidth; characterData[i+1] = (end + 0.5f)*dx; // Clear the background. FillRect(hDC, &r, nullptr); // Draw the character. wchar_t cChar = static_cast<wchar_t>(i); TextOut(hDC, 1, 0, &cChar, 1); // Grab the character's pixel data from the screen and store it in the // appropriate texels. for (int row = 0; row < height; ++row) { for (int col = 0; col < charWidth; ++ col) { COLORREF kColor = GetPixel(hDC, col, height - row); texels[width*row + start + col] = GetRValue(kColor); } } start += charWidth; } }