ALERROR rawConvertTo16bitDIB (int cxWidth, int cyHeight, RAWPIXEL *pRaw, DWORD dwFlags, HBITMAP *rethBitmap) // rawConvertTo16bitDIB // // Converts a raw image to a 16bit DIB // // cxWidth: The width of the raw image array in pixels // cyHeight: The height of the raw image array in pixels // pRaw: The actual array of raw image data. The image is a 2-dimensional // array cxWidth by cyHeight pixels. Each pixel is a 32bit value. // dwFlags: Unused // // rethBitmap: Returns a DIB. Note that depending on the graphics card, the // speed of BitBlt with this DIB will vary. For best results, convert to // a DDB before Blitting. { ALERROR error; HBITMAP hBitmap; WORD *p16BitPixel; RAWPIXEL *pRawPixel; int iScanline; // Create a destination DIB if (error = dibCreate16bitDIB(cxWidth, cyHeight, &hBitmap, &p16BitPixel)) return error; // Process each pixel in the raw bitmap by scanlines iScanline = 0; pRawPixel = pRaw; while (iScanline < cyHeight) { int i; for (i = 0; i < cxWidth; i++) { int iRed, iGreen, iBlue; // Down-sample to 5 or 6 bits iRed = (32 * rawRed(*pRawPixel)) / 256; // 5 bits of red iGreen = (64 * rawGreen(*pRawPixel)) / 256; // 6 bits of green iBlue = (32 * rawBlue(*pRawPixel)) / 256; // 5 bits of blue // Create pixel value *p16BitPixel = (((WORD)iRed) << 11) | (((WORD)iGreen) << 5) | (WORD)iBlue; // Next p16BitPixel++; pRawPixel++; } // We need to make sure that each output scan line is aligned on // a DWORD boundary. We assume here that pPixel is a pointer to // a WORD. p16BitPixel += (cxWidth % 2); iScanline++; } // Done *rethBitmap = hBitmap; return NOERROR; }
ALERROR CG16bitFont::CreateFromFont (HFONT hFont) // CreatFromFont // // Creates from a GDI font { ALERROR error; HDC hDC = CreateCompatibleDC(NULL); HFONT hOldFont = (HFONT)SelectObject(hDC, hFont); HBITMAP hTempBmp = NULL; HBITMAP hFontBmp = NULL; HBITMAP hOldBitmap; int i, y; // Get some metrics. For some reason we need to recreate the DC after // the GetTextMetrics or else the fonts won't be anti-aliased! TEXTMETRIC tm; GetTextMetrics(hDC, &tm); SelectObject(hDC, hOldFont); DeleteDC(hDC); hDC = CreateCompatibleDC(NULL); // Remember some for the whole font metrics m_Metrics.RemoveAll(); m_cyHeight = tm.tmHeight; m_cyAscent = tm.tmAscent; m_cxAveWidth = tm.tmAveCharWidth; // Create a bitmap that will contain all the font characters if (error = dibCreate16bitDIB(tm.tmMaxCharWidth, tm.tmHeight * g_iCharCount, &hFontBmp, NULL)) goto Fail; // Prepare the DC hOldBitmap = (HBITMAP)SelectObject(hDC, hFontBmp); hOldFont = (HFONT)SelectObject(hDC, hFont); SetTextColor(hDC, RGB(255,255,255)); SetBkColor(hDC, RGB(0,0,0)); SetBkMode(hDC, TRANSPARENT); // Get the name of the font that we selected char szFontName[256]; ::GetTextFace(hDC, sizeof(szFontName), szFontName); m_sTypeface = CString(szFontName); // Write each font character to the bitmap y = 0; for (i = 0; i < g_iCharCount; i++) { char chChar = (char)(g_iStartChar + i); // Blt TextOut(hDC, 0, y, &chChar, 1); // Remember some metrics CharMetrics Metrics; ABC abc; GetCharABCWidths(hDC, (BYTE)chChar, (BYTE)chChar, &abc); Metrics.cxWidth = abc.abcA + abc.abcB; Metrics.cxAdvance = abc.abcA + abc.abcB + abc.abcC; if (error = m_Metrics.AppendStruct(&Metrics, NULL)) goto Fail; #ifdef MOREDEBUG kernelDebugLogMessage("char: %d width: %d advance: %d", (int)chChar, Metrics.cxWidth, Metrics.cxAdvance); #endif // Next y += m_cyHeight; } SelectObject(hDC, hOldBitmap); // Now apply the bitmap to our image if (error = m_FontImage.CreateFromBitmap(NULL, hFontBmp, CG16bitImage::cfbDesaturateAlpha)) goto Fail; // Done DeleteObject(hFontBmp); SelectObject(hDC, hOldFont); DeleteDC(hDC); return NOERROR; Fail: if (hFontBmp) { SelectObject(hDC, hOldBitmap); DeleteObject(hFontBmp); } SelectObject(hDC, hOldFont); DeleteDC(hDC); return error; }
ALERROR dibLoadFromBlock (IReadBlock &Data, HBITMAP *rethDIB, EBitmapTypes *retiType) // dibLoadFromBlock // // Loads a DIB into memory { ALERROR error; HBITMAP hDIB; HANDLE hFileData; int iBitsOffset; BITMAPINFOHEADER bi; if (error = Data.Open()) return error; // Get information if (error = ReadDIBInfo(&Data, &hFileData, &iBitsOffset, &bi)) return error; // Return the bit-depth of the original bitmap if (retiType) { switch (bi.biBitCount) { case 1: *retiType = bitmapMonochrome; break; case 8: *retiType = bitmapAlpha; break; default: *retiType = bitmapRGB; break; } } // Calculate how much space we need for the bits DWORD dwBits = bi.biSizeImage; DWORD dwPaletteSize = dibPaletteSize(&bi); DWORD dwLen = bi.biSize + dwPaletteSize + dwBits; // Create a DIBSection if (error = dibCreate16bitDIB(bi.biWidth, bi.biHeight, &hDIB, NULL)) { GlobalFree(hFileData); return error; } // Set the bits HDC hDC = CreateCompatibleDC(NULL); SetDIBits(hDC, hDIB, 0, bi.biHeight, Data.GetPointer(iBitsOffset, -1), (BITMAPINFO *)GlobalLock(hFileData), DIB_RGB_COLORS); ::DeleteDC(hDC); GlobalUnlock(hFileData); GlobalFree(hFileData); // Done *rethDIB = hDIB; return NOERROR; }