FT_Library g_FreeTypeLibrary;
+typedef struct
+{
+ FT_Int major;
+ FT_Int minor;
+ FT_Int patch;
+} FT_Version_t;
+static FT_Version_t FT_Version;
+static DWORD FT_SimpleVersion;
+#define FT_VERSION_VALUE(major, minor, patch) (((major) << 16) | ((minor) << 8) | (patch))
+
/* special font names */
static const UNICODE_STRING g_MarlettW = RTL_CONSTANT_STRING(L"Marlett");
return FALSE;
}
+ FT_Library_Version(g_FreeTypeLibrary,&FT_Version.major,&FT_Version.minor,&FT_Version.patch);
+
+ DPRINT1("FreeType version is %d.%d.%d\n",FT_Version.major,FT_Version.minor,FT_Version.patch);
+ FT_SimpleVersion = ((FT_Version.major << 16) & 0xff0000) |
+ ((FT_Version.minor << 8) & 0x00ff00) |
+ ((FT_Version.patch ) & 0x0000ff);
+
IntLoadSystemFonts();
IntLoadFontSubstList(&g_FontSubstListHead);
} while (Entry);
}
-BOOL FASTCALL
-IntIsFontRenderingEnabled(VOID)
+static BOOL is_hinting_enabled(void)
{
- BOOL Ret = g_RenderingEnabled;
- HDC hDC;
+ static int enabled = -1;
- hDC = IntGetScreenDC();
- if (hDC)
- Ret = (NtGdiGetDeviceCaps(hDC, BITSPIXEL) > 8) && g_RenderingEnabled;
+ if (enabled == -1)
+ {
+ /* Use the >= 2.2.0 function if available */
+ FT_TrueTypeEngineType type = FT_Get_TrueType_Engine_Type(g_FreeTypeLibrary);
+ enabled = (type == FT_TRUETYPE_ENGINE_TYPE_PATENTED);
- return Ret;
+ DPRINT1("hinting is %senabled\n", enabled ? "" : "NOT ");
+ }
+ return enabled;
+}
+
+static BOOL is_subpixel_rendering_enabled( void )
+{
+ static int enabled = -1;
+ if (enabled == -1)
+ {
+ /* FreeType >= 2.8.1 offers LCD-optimezed rendering without lcd filters. */
+ if (FT_SimpleVersion >= FT_VERSION_VALUE(2, 8, 1))
+ enabled = TRUE;
+ else enabled = FALSE;
+
+ DPRINT1("subpixel rendering is %senabled\n", enabled ? "" : "NOT ");
+ }
+ return enabled;
+}
+
+BOOL FASTCALL
+IntIsFontRenderingEnabled(VOID)
+{
+ return is_hinting_enabled() && is_subpixel_rendering_enabled() && g_RenderingEnabled;
}
VOID FASTCALL
BOOL
APIENTRY
-GreExtTextOutW(
- IN HDC hDC,
+IntExtTextOutW(
+ IN PDC dc,
IN INT XStart,
IN INT YStart,
IN UINT fuOptions,
* appropriate)
*/
- DC *dc;
PDC_ATTR pdcattr;
SURFOBJ *SurfObj;
SURFACE *psurf = NULL;
return FALSE;
}
- /* NOTE: This function locks the screen DC, so it must never be called
- with a DC already locked */
Render = IntIsFontRenderingEnabled();
- // TODO: Write test-cases to exactly match real Windows in different
- // bad parameters (e.g. does Windows check the DC or the RECT first?).
- dc = DC_LockDc(hDC);
- if (!dc)
- {
- EngSetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
-
if (PATH_IsPathOpen(dc->dclevel))
{
bResult = PATH_ExtTextOut(dc,
IntLPtoDP(dc, (POINT *)lprc, 2);
}
- if (pdcattr->lTextAlign & TA_UPDATECP)
+ if (pdcattr->flTextAlign & TA_UPDATECP)
{
Start.x = pdcattr->ptlCurrent.x;
Start.y = pdcattr->ptlCurrent.y;
use_kerning = FT_HAS_KERNING(face);
previous = 0;
if ((fuOptions & ETO_OPAQUE) ||
- (pdcattr->lTextAlign & (TA_CENTER | TA_RIGHT)) ||
+ (pdcattr->flTextAlign & (TA_CENTER | TA_RIGHT)) ||
memcmp(&mat, &identityMat, sizeof(mat)) != 0 ||
plf->lfUnderline || plf->lfStrikeOut)
{
}
// Process the X and Y alignments.
- if ((pdcattr->lTextAlign & TA_CENTER) == TA_CENTER)
+ if ((pdcattr->flTextAlign & TA_CENTER) == TA_CENTER)
{
XStart64 = -DeltaX64 / 2;
YStart64 = -DeltaY64 / 2;
}
- else if ((pdcattr->lTextAlign & TA_RIGHT) == TA_RIGHT)
+ else if ((pdcattr->flTextAlign & TA_RIGHT) == TA_RIGHT)
{
XStart64 = -DeltaX64;
YStart64 = -DeltaY64;
/* Process the vertical alignment */
#define VALIGN_MASK (TA_TOP | TA_BASELINE | TA_BOTTOM)
RtlZeroMemory(vecs, sizeof(vecs));
- if ((pdcattr->lTextAlign & VALIGN_MASK) == TA_BASELINE)
+ if ((pdcattr->flTextAlign & VALIGN_MASK) == TA_BASELINE)
{
vecs[1].y = -FontGDI->tmAscent << 16; // upper left
vecs[4].y = 0; // baseline
vecs[0].y = FontGDI->tmDescent << 16; // lower left
}
- else if ((pdcattr->lTextAlign & VALIGN_MASK) == TA_BOTTOM)
+ else if ((pdcattr->flTextAlign & VALIGN_MASK) == TA_BOTTOM)
{
vecs[1].y = -FontGDI->tmHeight << 16; // upper left
vecs[4].y = -FontGDI->tmDescent << 16; // baseline
MouseSafetyOnDrawEnd(dc->ppdev);
}
- if (pdcattr->lTextAlign & TA_UPDATECP) {
+ if (pdcattr->flTextAlign & TA_UPDATECP) {
pdcattr->ptlCurrent.x = DestRect.right - dc->ptlDCOrig.x;
}
if (TextObj != NULL)
TEXTOBJ_UnlockText(TextObj);
+ return bResult;
+}
+
+
+BOOL
+APIENTRY
+GreExtTextOutW(
+ IN HDC hDC,
+ IN INT XStart,
+ IN INT YStart,
+ IN UINT fuOptions,
+ IN OPTIONAL PRECTL lprc,
+ IN LPCWSTR String,
+ IN INT Count,
+ IN OPTIONAL LPINT Dx,
+ IN DWORD dwCodePage)
+{
+ BOOL bResult;
+ DC *dc;
+
+ // TODO: Write test-cases to exactly match real Windows in different
+ // bad parameters (e.g. does Windows check the DC or the RECT first?).
+ dc = DC_LockDc(hDC);
+ if (!dc)
+ {
+ EngSetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ bResult = IntExtTextOutW( dc,
+ XStart,
+ YStart,
+ fuOptions,
+ lprc,
+ String,
+ Count,
+ Dx,
+ dwCodePage );
+
DC_UnlockDc(dc);
return bResult;