📄 dglwgl.c
字号:
LeaveCriticalSection(&CriticalSection);#endif // SUCCESS. return TRUE;cleanup_and_return_with_error: // Relase all interfaces before returning.#ifdef _USE_GLD3_WGL _gldDriver.DestroyDrawable(dgl);#else // _USE_GLD3_WGL RELEASE(dgl->lpDev3); RELEASE(dgl->lpDepth4); RELEASE(dgl->lpBack4); if (glb.bDirectDrawPersistant && glb.bDirectDrawPrimary) ; else RELEASE(dgl->lpFront4);#undef DDLOG_CRITICAL_OR_WARN#endif // _USE_GLD3_WGL // Mark context as not being able to render dgl->bCanRender = FALSE;#ifdef GLD_THREADS // Release serialized access if (glb.bMultiThreaded) LeaveCriticalSection(&CriticalSection);#endif return FALSE;}// ***********************************************************************// ***********************************************************************// Support for bitmap fonts.// ***********************************************************************// ***********************************************************************/********************************************************************************* InvertGlyphBitmap.**** Invert the bitmap so that it suits OpenGL's representation.** Each row starts on a double word boundary.*******************************************************************************/static void InvertGlyphBitmap( int w, int h, DWORD *fptr, DWORD *tptr){ int dWordsInRow = (w+31)/32; int i, j; DWORD *tmp = tptr; if (w <= 0 || h <= 0) { return; } tptr += ((h-1)*dWordsInRow); for (i = 0; i < h; i++) { for (j = 0; j < dWordsInRow; j++) { *(tptr + j) = *(fptr + j); } tptr -= dWordsInRow; fptr += dWordsInRow; }}// ***********************************************************************/***************************************************************************** * wglUseFontBitmaps * * Converts a subrange of the glyphs in a GDI font to OpenGL display * lists. * * Extended to support any GDI font, not just TrueType fonts. (DaveM) * *****************************************************************************/BOOL APIENTRY _GLD_WGL_EXPORT(UseFontBitmapsA)( HDC hDC, DWORD first, DWORD count, DWORD listBase){ int i, ox, oy, ix, iy; int w, h; int iBufSize, iCurBufSize = 0; DWORD *bitmapBuffer = NULL; DWORD *invertedBitmapBuffer = NULL; BOOL bSuccessOrFail = TRUE; BOOL bTrueType = FALSE; TEXTMETRIC tm; GLYPHMETRICS gm; RASTERIZER_STATUS rs; MAT2 mat; SIZE size; RECT rect; HDC hDCMem; HBITMAP hBitmap; BITMAPINFO bmi; HFONT hFont; // Validate SciTech DirectGL license if (!dglValidate()) return FALSE; // Set up a unity matrix. ZeroMemory(&mat, sizeof(mat)); mat.eM11.value = 1; mat.eM22.value = 1; // Test to see if selected font is TrueType or not ZeroMemory(&tm, sizeof(tm)); if (!GetTextMetrics(hDC, &tm)) { ddlogMessage(DDLOG_ERROR, "DGL_UseFontBitmaps: Font metrics error\n"); return (FALSE); } bTrueType = (tm.tmPitchAndFamily & TMPF_TRUETYPE) ? TRUE : FALSE; // Test to see if TRUE-TYPE capabilities are installed // (only necessary if TrueType font selected) ZeroMemory(&rs, sizeof(rs)); if (bTrueType) { if (!GetRasterizerCaps (&rs, sizeof (RASTERIZER_STATUS))) { ddlogMessage(DDLOG_ERROR, "DGL_UseFontBitmaps: Raster caps error\n"); return (FALSE); } if (!(rs.wFlags & TT_ENABLED)) { ddlogMessage(DDLOG_ERROR, "DGL_UseFontBitmaps: No TrueType caps\n"); return (FALSE); } } // Trick to get the current font handle hFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT)); SelectObject(hDC, hFont); // Have memory device context available for holding bitmaps of font glyphs hDCMem = CreateCompatibleDC(hDC); SelectObject(hDCMem, hFont); SetTextColor(hDCMem, RGB(0xFF, 0xFF, 0xFF)); SetBkColor(hDCMem, 0); for (i = first; (DWORD) i < (first + count); i++) { // Find out how much space is needed for the bitmap so we can // Set the buffer size correctly. if (bTrueType) { // Use TrueType support to get bitmap size of glyph iBufSize = GetGlyphOutline(hDC, i, GGO_BITMAP, &gm, 0, NULL, &mat); if (iBufSize == GDI_ERROR) { bSuccessOrFail = FALSE; break; } } else { // Use generic GDI support to compute bitmap size of glyph w = tm.tmMaxCharWidth; h = tm.tmHeight; if (GetTextExtentPoint32(hDC, (LPCTSTR)&i, 1, &size)) { w = size.cx; h = size.cy; } iBufSize = w * h; // Use DWORD multiple for compatibility iBufSize += 3; iBufSize /= 4; iBufSize *= 4; } // If we need to allocate Larger Buffers, then do so - but allocate // An extra 50 % so that we don't do too many mallocs ! if (iBufSize > iCurBufSize) { if (bitmapBuffer) { __wglFree(bitmapBuffer); } if (invertedBitmapBuffer) { __wglFree(invertedBitmapBuffer); } iCurBufSize = iBufSize * 2; bitmapBuffer = (DWORD *) __wglMalloc(iCurBufSize); invertedBitmapBuffer = (DWORD *) __wglMalloc(iCurBufSize); if (bitmapBuffer == NULL || invertedBitmapBuffer == NULL) { bSuccessOrFail = FALSE; break; } } // If we fail to get the Glyph data, delete the display lists // Created so far and return FALSE. if (bTrueType) { // Use TrueType support to get bitmap of glyph if (GetGlyphOutline(hDC, i, GGO_BITMAP, &gm, iBufSize, bitmapBuffer, &mat) == GDI_ERROR) { bSuccessOrFail = FALSE; break; } // Setup glBitmap parameters for current font glyph w = gm.gmBlackBoxX; h = gm.gmBlackBoxY; ox = gm.gmptGlyphOrigin.x; oy = gm.gmptGlyphOrigin.y; ix = gm.gmCellIncX; iy = gm.gmCellIncY; } else { // Use generic GDI support to create bitmap of glyph ZeroMemory(bitmapBuffer, iBufSize); if (i >= tm.tmFirstChar && i <= tm.tmLastChar) { // Only create bitmaps for actual font glyphs hBitmap = CreateBitmap(w, h, 1, 1, NULL); SelectObject(hDCMem, hBitmap); // Make bitmap of current font glyph SetRect(&rect, 0, 0, w, h); DrawText(hDCMem, (LPCTSTR)&i, 1, &rect, DT_LEFT | DT_BOTTOM | DT_SINGLELINE | DT_NOCLIP); // Make copy of bitmap in our local buffer ZeroMemory(&bmi, sizeof(bmi)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = w; bmi.bmiHeader.biHeight = -h; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 1; bmi.bmiHeader.biCompression = BI_RGB; GetDIBits(hDCMem, hBitmap, 0, h, bitmapBuffer, &bmi, 0); DeleteObject(hBitmap); } else { // Otherwise use empty display list for non-existing glyph iBufSize = 0; } // Setup glBitmap parameters for current font glyph ox = 0; oy = tm.tmDescent; ix = w; iy = 0; } // Create an OpenGL display list. _GLD_glNewList((listBase + i), GL_COMPILE); // Some fonts have no data for the space character, yet advertise // a non-zero size. if (0 == iBufSize) { _GLD_glBitmap(0, 0, 0.0f, 0.0f, (GLfloat) ix, (GLfloat) iy, NULL); } else { // Invert the Glyph data. InvertGlyphBitmap(w, h, bitmapBuffer, invertedBitmapBuffer); // Render an OpenGL bitmap and invert the origin. _GLD_glBitmap(w, h, (GLfloat) ox, (GLfloat) (h-oy), (GLfloat) ix, (GLfloat) iy, (GLubyte *) invertedBitmapBuffer); } // Close this display list. _GLD_glEndList(); } if (bSuccessOrFail == FALSE) { ddlogMessage(DDLOG_ERROR, "DGL_UseFontBitmaps: Get glyph failed\n"); _GLD_glDeleteLists((i+listBase), (i-first)); } // Release resources used DeleteObject(hFont); DeleteDC(hDCMem); if (bitmapBuffer) __wglFree(bitmapBuffer); if (invertedBitmapBuffer) __wglFree(invertedBitmapBuffer); return(bSuccessOrFail);}// ***********************************************************************BOOL APIENTRY _GLD_WGL_EXPORT(UseFontBitmapsW)( HDC a, DWORD b, DWORD c, DWORD d){ // Validate license if (!dglValidate()) return FALSE; return _GLD_WGL_EXPORT(UseFontBitmapsA)(a, b, c, d);}// ***********************************************************************// ***********************************************************************// Support for outline TrueType fonts.// ***********************************************************************// ***********************************************************************void * __wglRealloc( void *oldPtr, size_t newSize){ void *newPtr = NULL; if (newSize != 0) { newPtr = (void *) GlobalAlloc(GPTR, newSize); if (oldPtr && newPtr) { DWORD oldSize = GlobalSize(oldPtr); memcpy(newPtr, oldPtr, (oldSize <= newSize ? oldSize : newSize)); GlobalFree(oldPtr); } } else if (oldPtr) { GlobalFree(oldPtr); } if (newPtr == NULL) { return NULL; /* XXX out of memory error */ } return newPtr;}// ***********************************************************************/***************************************************************************** * wglUseFontOutlinesW * * Converts a subrange of the glyphs in a TrueType font to OpenGL display * lists. *****************************************************************************/BOOL APIENTRY _GLD_WGL_EXPORT(UseFontOutlinesW)( IN HDC hDC, IN DWORD first, IN DWORD count, IN DWORD listBase, IN FLOAT chordalDeviation, IN FLOAT extrusion, IN INT format, OUT LPGLYPHMETRICSFLOAT lpgmf){ return _GLD_WGL_EXPORT(UseFontOutlinesA)(hDC, first, count, listBase, chordalDeviation, extrusion, format, lpgmf);}/***************************************************************************** * wglUseFontOutlinesA * * Converts a subrange of the glyphs in a TrueType font to OpenGL display * lists. *****************************************************************************/BOOL APIENTRY _GLD_WGL_EXPORT(UseFontOutlinesA)( IN HDC hDC, IN DWORD first, IN DWORD count, IN DWORD listBase, IN FLOAT chordalDeviation, IN FLOAT extrusion, IN INT format, OUT LPGLYPHMETRICSFLOAT glyphMetricsFloatArray) { DWORD glyphIndex; UCHAR* glyphBuf; DWORD glyphBufSize; /* * Flush any previous OpenGL errors. This allows us to check for * new errors so they can be reported via the function return value. */ while (_GLD_glGetError() != GL_NO_ERROR) ; /* * Make sure that the current font can be sampled accurately. */ hNewFont = CreateHighResolutionFont(hDC); if (!hNewFont) return FALSE; hOldFont = SelectObject(hDC, hNewFont); if (!hOldFont) return FALSE; /* * Preallocate a buffer for the outline data, and track its size: */ glyphBuf = (UCHAR*) __wglMalloc(glyphBufSize = 10240); if (!glyphBuf) return FALSE; /*WGL_STATUS_NOT_ENOUGH_MEMORY*/ /* * Process each glyph in the given range: */ for (glyphIndex = first; glyphIndex - first < count; ++glyphIndex) { GLYPHMETRICS glyphMetrics; DWORD glyphSize; static MAT2 matrix = { {0, 1}, {0, 0}, {0, 0}, {0, 1} }; LPGLYPHMETRICSFLOAT glyphMetricsFloat = &glyphMetricsFloatArray[glyphIndex - first]; /* * Determine how much space is needed to store the glyph's * outlines. If our glyph buffer isn't large enough, * resize it. */ glyphSize = GetGlyphOutline( hDC, glyphIndex, GGO_NATIVE, &glyphMetrics, 0, NULL, &matrix ); if (glyphSize < 0) return FALSE; /*WGL_STATUS_FAILURE*/ if (glyphSize > glyphBufSize) { __wglFree(glyphBuf); glyphBuf = (UCHAR*) __wglMalloc(glyphBufSize = glyphSize); if (!glyphBuf) return FALSE; /*WGL_STATUS_NOT_ENOUGH_MEMORY*/ } /* * Get the glyph's outlines. */ if (GetGlyphOutline( hDC, glyphIndex, GGO_NATIVE, &glyphMetrics, glyphBufSize, glyphBuf, &matrix ) < 0) { __wglFree(glyphBuf); return FALSE; /*WGL_STATUS_FAILURE*/ } glyphMetricsFloat->gmfBlackBoxX = (FLOAT) glyphMetrics.gmBlackBoxX * ScaleFactor; glyphMetricsFloat->gmfBlackBoxY = (FLOAT) glyphMetrics.gmBlackBoxY * ScaleFactor; glyphMetricsFloat->gmfptGlyphOrigin.x = (FLOAT) glyphMetrics.gmptGlyphOrigin.x * ScaleFactor; glyphMetricsFloat->gmfptGlyphOrigin.y = (FLOAT) glyphMetrics.gmptGlyphOrigin.y * ScaleFactor; glyphMetricsFloat->gmfCellIncX = (FLOAT) glyphMetrics.gmCellIncX * ScaleFactor; glyphMetricsFloat->gmfCellIncY = (FLOAT) glyphMetrics.gmCellIncY * ScaleFactor; /* * Turn the glyph into a display list: */ if (!MakeDisplayListFromGlyph( (glyphIndex - first) + listBase, glyphBuf, glyphSize, glyphMetricsFloat, chordalDeviation + ScaleFactor, extrusion, format)) { __wglFree(glyphBuf); return FALSE; /*WGL_STATUS_FAILURE*/ } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -