📄 rtwin.cpp
字号:
// gaps if the letter spacing is slightly different than // the os would natively space it: if((BAD_RGB_COLOR != bgTextColor && TRANSPARENT_COLOR != bgTextColor) || curTextContainerPtr->isUnderlined() || curTextContainerPtr->isStruckOut()) { LONG32 yLowerRightScaled = lScaledLowerRightYWithOffsets; RECT updateRect; updateRect.left = xScaled; //Fix for bug 6527; when double sized, we want to // double the padding on the right edge. This // "padding" (which used to be +1 always) is // necessary when drawing a rect in Windows because // PaintRectangle draws up to, but not including, // the right edge: LONG32 additionalWidth = 1; if(lLowerRightYWithOffsets != 0) //avoid div by 0. { additionalWidth = yLowerRightScaled / lLowerRightYWithOffsets; } if(additionalWidth < 1) { additionalWidth=1; } updateRect.right = lScaledLowerRightXWithOffsets + additionalWidth; if(BAD_RGB_COLOR != bgTextColor && TRANSPARENT_COLOR != bgTextColor) { updateRect.top = yScaled; updateRect.bottom = yLowerRightScaled+1; PaintRectangle(pTextWindow, updateRect, (COLORREF)bgTextColor, pTextWindow->getMediaOpacity()); } //Do underlining manually now (due to // possible gaps if alternate font has to be // used and forced spacing is not quite as os // calculates it): if(curTextContainerPtr->isUnderlined()) { INT32 thickness = (yLowerRightScaled - yScaled) / 12; if(thickness < 1) { thickness = 1; } if(bIsBold) { thickness += (thickness/2); } updateRect.top = yLowerRightScaled-thickness+1; updateRect.bottom = yLowerRightScaled+1; //Draw the underline: PaintRectangle(pTextWindow, updateRect, (COLORREF)textColor, pTextWindow->getMediaOpacity()); } //Do strike-through manually now (due to // possible gaps if alternate font has to be // used and forced spacing is not quite as os // calculates it): if(curTextContainerPtr->isStruckOut()) { INT32 thickness = (yLowerRightScaled - yScaled) / 18; if(thickness < 1) { thickness = 1; } updateRect.top = yScaled + ((yLowerRightScaled - yScaled) / 2) + 1; updateRect.bottom = updateRect.top + thickness; //Draw the underline: PaintRectangle(pTextWindow, updateRect, (COLORREF)textColor, pTextWindow->getMediaOpacity()); } } LONG32 ulXTotalCharsOffset = 0L; BOOL bUseSameFontAsForLastChar = FALSE; do //draw each character @ offset in x from the first: { _CHAR ch = *pTextbuffer; UINT16 usCh = ch; tmpString[0] = ch; tmpStringLen = 1; if (HX_DBCS_CHARSET & ulCharset || HX_UNICODE_CHARSET & ulCharset) { if (HX_UNICODE_CHARSET & ulCharset || (UCHAR)ch >= DBCS_MIN_LEAD_BYTE_VAL) { //then ch is lead byte of a 2-byte char. pTextbuffer++; ch = *pTextbuffer; tmpString[tmpStringLen] = ch; //==trail byte. tmpStringLen++; //is a 2-byte char.#if defined(USE_FREETYPE_DIRECTLY) /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/#if defined(_MACINTOSH)// /XXXEH- need to look at possible big-VS-little-endian problem with this:#endif#endif /* USE_FREETYPE_DIRECTLY. */ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ usCh <<= 8; //move lead byte into high byte. usCh |= ch; //put trail byte into low byte. } } //XXXEH- test this DBCS stuff^^!!! //Now move in x by the amount that the // cross-platform (uniform) table says is the // width of this char: ULONG32 ulLookupCharWidth = GetCharacterWidth(usCh, ulFontFaceIndex, ulFontPointSize, bIsBold, bIsItalicized, ulCharset); if(bWindowWidthIsNotTheOriginalValue) { ulLookupCharWidth = MulDiv(ulLookupCharWidth, lWindowWidth, pTextWindow->getWidth()); } //However, we want to horizontally center the // character inside its bounding box in case its // native width is noticably different from its // cross-platform-table-assigned width: LONG32 lXPlatWidth = (LONG32)ulLookupCharWidth; SIZE charsize; BOOL bGtepSucceeded =#if defined(_WIN16) //Docs say this has an off-by-one error, // but that shouldn't be a big deal // (especially if we never release a Win16 // client ;-) GetTextExtentPoint(#else GetTextExtentPoint32(#endif hDC, tmpString, tmpStringLen, &charsize); LONG32 lCrossPlatVsNativeWidthOffset = 0L; LONG32 lNativeWidth = charsize.cx; if(bGtepSucceeded && lXPlatWidth != lNativeWidth) { //Note: we should not adjust lNativeWidth if // bWindowWidthIsNotTheOriginalValue because // that's already been accounted for in hDC's // font point size. //Note: this can be negative!: lCrossPlatVsNativeWidthOffset = (lXPlatWidth-lNativeWidth)/2; } INT32 lXStart = xScaled + lCrossPlatVsNativeWidthOffset + ulXTotalCharsOffset; INT32 lYStart = yScaled;#if defined(USE_FREETYPE_DIRECTLY) /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ // /XXXEH- add this option to RT-file's header (or // maybe user's player pref?): BOOL bDoAntialias = TRUE; tmpString[tmpStringLen] = '\0'; // /Ensure NULL terminated. LONG32 lOffscreenDepth = pHeader->biBitCount; // /XXXEH- check this!#define XXXEH_FUDGE_SCALE_FACTOR .9 /* FreeType renders at about .9x what Windows does. */#define XXXEH_ENABLE_X_INDEPENDENT_SCALING // /Fixes CROSSPLAT-TEXT-BUG-0005; offscreen bitmap's width is // always divisible by 4: INT32 lRectWidthAdjustedToDivBy4 = srcRect.Width(); lRectWidthAdjustedToDivBy4 += (4 - (lRectWidthAdjustedToDivBy4 & 0x3)) & 0x3; HX_RESULT hxrRndrText = HXR_OK; if (!bUseSameFontAsForLastChar) // /Load new font: { hxrRndrText = crossPlatTextSvcs.renderText((const char*)tmpString, pBits, lRectWidthAdjustedToDivBy4, srcRect.Height(), lOffscreenDepth, lXStart, lYStart, bDoAntialias, ftCharsetEncoding, (char*)pCurFontFaceString, bIsBold, bIsItalicized, #if defined(XXXEH_ENABLE_X_INDEPENDENT_SCALING) // /XXXEH- indep. X-scaling = new functionality // that wasn't possible in prior RealText due // to OS-API drawing of chars. This should be // tested more than just by me, and should // happen only with higher-versioned RT(?): ulScaledWidth * XXXEH_FUDGE_SCALE_FACTOR, // logical average character width#else 0,#endif ulScaledHeight * XXXEH_FUDGE_SCALE_FACTOR, //logical ht in pixels textColor); } else // /Re-use same font face and bold ital attribs: { hxrRndrText = crossPlatTextSvcs.renderTextSameFontFace((const char*)tmpString, pBits, lRectWidthAdjustedToDivBy4, srcRect.Height(), lOffscreenDepth, lXStart, lYStart, bDoAntialias, ftCharsetEncoding,#if defined(XXXEH_ENABLE_X_INDEPENDENT_SCALING) // /XXXEH- indep. X-scaling = new functionality ulScaledWidth * XXXEH_FUDGE_SCALE_FACTOR, // logical average character width#else 0,#endif ulScaledHeight * XXXEH_FUDGE_SCALE_FACTOR, //logical ht in pixels textColor); }#else TextOut(hDC, lXStart, lYStart, tmpString, tmpStringLen); //only draw this 1-2 byte char#if defined(XXXEH_TESTING_DATAURLPLAINTEXT_HANDLING2)FILE* f1 = ::fopen("c:\\LogDataURLhandling.txt", "a+");::fprintf(f1, "Draw(): just did TextOut(x=%ld, y=%ld, %c)", lXStart, lYStart, *tmpString);::fclose(f1);#endif#endif /* USE_FREETYPE_DIRECTLY. */ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ // The following code handles both media opacity // and chroma key BOOL bChromaMatch = FALSE; if (pTextWindow->isChromaKeySet()) { bChromaMatch = DoesChromaKeyMatch(textColor, pTextWindow->getChromaKey(), pTextWindow->getChromaKeyTolerance()); } if (pTextWindow->getMediaOpacity() < 255 || (bChromaMatch && pTextWindow->getChromaKeyOpacity() < 255)) { UINT32 ulOpacity = pTextWindow->getMediaOpacity(); if (bChromaMatch) { ulOpacity = pTextWindow->getChromaKeyOpacity(); bChromaKeyWasApplied = TRUE; } ApplyTextOpacity(pTextWindow, lXStart, lYStart, charsize.cx, charsize.cy, TRUE, textColor, ulOpacity); } ulXTotalCharsOffset += ulLookupCharWidth;#if defined(USE_FREETYPE_DIRECTLY) /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ // /If rendering failed, try again with next char, // otherwise re-use same font: bUseSameFontAsForLastChar = (HXR_OK == hxrRndrText);#endif /* USE_FREETYPE_DIRECTLY. */ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ } while(*(++pTextbuffer));#if 0if(GDI_ERROR != prevAlignment){ SetTextAlign(hDC, prevAlignment);}#endif }#if !defined(USE_FREETYPE_DIRECTLY) /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ /* Restore the previous font: */ SelectObject(hDC, hfontOld); DeleteObject(hfont);#endif /* USE_FREETYPE_DIRECTLY. */ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /* Restore the previous colors: */ SetTextColor(hDC, textColorOld);/* XXXXXEH> no need to do this: (right?) SetBkColor(hDC, textColorOld); <XXXXXEH. */ curTextContainerPtr->textHasChangedSinceLastDraw(FALSE); } //end "if(curTextContainerPtr->textHasChangedSinceLastDraw())". } //end "while(pos)". SetBkMode(hDC, bkModeOld); } //end "if (!bDoing... listSize ...)".#if !defined (USE_FREETYPE_DIRECTLY)// / * XXXEH-1 vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv *#if !defined(USE_DIB_SECTION) // retreive the bitmap handler HBITMAP hBM = (HBITMAP)SelectObject(hDC, hbmpOld);#endif UCHAR* pBits = NULL; LPBITMAPINFOHEADER pHeader = NULL;#if !defined(USE_DIB_SECTION) // convert HBITMAP to DIB: if (pTextWindow->m_hDIB && HXR_OK == pTextWindow->m_hDIB->GetDIBits(hDC, hBM, pBits, pHeader)) { #else //USE_DIB_SECTION: //we already have a DIB, so use it: if(pTextWindow->m_pBits) { pBits = (UCHAR*)(pTextWindow->m_pBits); pHeader = &(pTextWindow->m_BITMAPINFOHEADER);#endif CHXxRect* pDestRect = (CHXxRect*)((HXxEvent*)pVoid)->param2; CHXxRect srcRect(0, 0, lWindowWidth, lWindowHeight); LONG32 lImageOffset = 0L;#if defined(SCROLLINGVERSION_SCROLL_BY_MOVING_WINDOW) if(bDoingScrollOfRect) { if(xScrollWindowAmt>0) { srcRect.left += xScrollWindowAmt; srcRect.right += xScrollWindowAmt; } if(yScrollWindowAmt>0) { //Note: we have to subtract, not add, because DIB's origin is // bottom left, not top left: srcRect.top += yScrollWindowAmt; srcRect.bottom += yScrollWindowAmt; } } //Keep the offscreen height so we can reset it after doing the Blt(): LONG32 lSavedHeaderHeight = pHeader->biHeight; //If we're just using part of a larger offscreen area, then we need to // send an offset into the buffer that accounts for the extra vertical // lines of data (which, in Windows, byte 0 of the data is the first // byte of the LAST scan line, i.e., starts line # pBitmapInfo->biHeight): if(pHeader->biHeight != srcRect.Height()) { lImageOffset = (pHeader->biHeight - srcRect.Height() - srcRect.top) * (pHeader->biBitCount / 8) * pHeader->biWidth; if(lImageOffset > 0L) { if(srcRect.top != 0) srcRect.bottom -= srcRect.top; srcRect.top = 0; pHeader->biHeight = srcRect.Height(); pHeader->biSizeImage = WIDTHBYTES((pHeader->biWidth * pHeader->biBitCount) * pHeader->biHeight); } else { lImageOffset = 0L; } }#endif CHXxRect destRect; if (pDestRect) { destRect.SetRect(pDestRect->left, pDestRect->top, pDestRect->right, pDestRect->bottom); } else { destRect.SetRect(0, 0, lWindowWidth,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -