X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=reactos%2Fsubsystems%2Fwin32%2Fwin32k%2Fobjects%2Ffreetype.c;h=f4d17cc5f8ce4cb74f451af9ed58d809725b60d9;hp=bdda9c20cc6c4dbb241138e4599d7bf73282373b;hb=684c3d3791b92777e7de259fbc6691161f6808c7;hpb=9ae0c012618ff28617486554353ca48816cb55ac diff --git a/reactos/subsystems/win32/win32k/objects/freetype.c b/reactos/subsystems/win32/win32k/objects/freetype.c index bdda9c20cc6..f4d17cc5f8c 100644 --- a/reactos/subsystems/win32/win32k/objects/freetype.c +++ b/reactos/subsystems/win32/win32k/objects/freetype.c @@ -35,7 +35,7 @@ /** Includes ******************************************************************/ -#include +#include #include #include FT_FREETYPE_H @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -81,7 +82,7 @@ typedef struct _FONT_CACHE_ENTRY LIST_ENTRY ListEntry; int GlyphIndex; FT_Face Face; - FT_Glyph Glyph; + FT_BitmapGlyph BitmapGlyph; int Height; } FONT_CACHE_ENTRY, *PFONT_CACHE_ENTRY; static LIST_ENTRY FontCacheListHead; @@ -218,17 +219,17 @@ IntLoadSystemFonts(VOID) if (NT_SUCCESS(Status)) { - DirInfoBuffer = ExAllocatePool(PagedPool, 0x4000); + DirInfoBuffer = ExAllocatePoolWithTag(PagedPool, 0x4000, TAG_FONT); if (DirInfoBuffer == NULL) { ZwClose(hDirectory); return; } - FileName.Buffer = ExAllocatePool(PagedPool, MAX_PATH * sizeof(WCHAR)); + FileName.Buffer = ExAllocatePoolWithTag(PagedPool, MAX_PATH * sizeof(WCHAR), TAG_FONT); if (FileName.Buffer == NULL) { - ExFreePool(DirInfoBuffer); + ExFreePoolWithTag(DirInfoBuffer, TAG_FONT); ZwClose(hDirectory); return; } @@ -272,8 +273,8 @@ IntLoadSystemFonts(VOID) bRestartScan = FALSE; } - ExFreePool(FileName.Buffer); - ExFreePool(DirInfoBuffer); + ExFreePoolWithTag(FileName.Buffer, TAG_FONT); + ExFreePoolWithTag(DirInfoBuffer, TAG_FONT); ZwClose(hDirectory); } } @@ -301,7 +302,9 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics) PSECTION_OBJECT SectionObject; ULONG ViewSize = 0; LARGE_INTEGER SectionSize; +#if 0 // Wine code FT_Fixed XScale, YScale; +#endif UNICODE_STRING FontRegPath = RTL_CONSTANT_STRING(L"\\REGISTRY\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"); /* Open the font file */ @@ -394,9 +397,9 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics) FontGDI->face = Face; /* FIXME: Complete text metrics */ +#if 0 /* This (Wine) code doesn't seem to work correctly for us */ XScale = Face->size->metrics.x_scale; YScale = Face->size->metrics.y_scale; -#if 0 /* This (Wine) code doesn't seem to work correctly for us */ FontGDI->TextMetric.tmAscent = (FT_MulFix(Face->ascender, YScale) + 32) >> 6; FontGDI->TextMetric.tmDescent = (FT_MulFix(Face->descender, YScale) + 32) >> 6; FontGDI->TextMetric.tmHeight = (FT_MulFix(Face->ascender, YScale) - @@ -1349,7 +1352,7 @@ ftGdiGetRasterizerCaps(LPRASTERIZER_STATUS lprs) } -FT_Glyph APIENTRY +FT_BitmapGlyph APIENTRY ftGdiGlyphCacheGet( FT_Face Face, INT GlyphIndex, @@ -1376,10 +1379,10 @@ ftGdiGlyphCacheGet( RemoveEntryList(CurrentEntry); InsertHeadList(&FontCacheListHead, CurrentEntry); - return FontEntry->Glyph; + return FontEntry->BitmapGlyph; } -FT_Glyph APIENTRY +FT_BitmapGlyph APIENTRY ftGdiGlyphCacheSet( FT_Face Face, INT GlyphIndex, @@ -1390,6 +1393,8 @@ ftGdiGlyphCacheSet( FT_Glyph GlyphCopy; INT error; PFONT_CACHE_ENTRY NewEntry; + FT_Bitmap AlignedBitmap; + FT_BitmapGlyph BitmapGlyph; error = FT_Get_Glyph(GlyphSlot, &GlyphCopy); if (error) @@ -1397,6 +1402,7 @@ ftGdiGlyphCacheSet( DPRINT1("Failure caching glyph.\n"); return NULL; }; + error = FT_Glyph_To_Bitmap(&GlyphCopy, RenderMode, 0, 1); if (error) { @@ -1412,22 +1418,34 @@ ftGdiGlyphCacheSet( return NULL; } + BitmapGlyph = (FT_BitmapGlyph)GlyphCopy; + FT_Bitmap_New(&AlignedBitmap); + if(FT_Bitmap_Convert(GlyphSlot->library, &BitmapGlyph->bitmap, &AlignedBitmap, 4)) + { + DPRINT1("Conversion failed\n"); + FT_Done_Glyph((FT_Glyph)BitmapGlyph); + return NULL; + } + + FT_Bitmap_Done(GlyphSlot->library, &BitmapGlyph->bitmap); + BitmapGlyph->bitmap = AlignedBitmap; + NewEntry->GlyphIndex = GlyphIndex; NewEntry->Face = Face; - NewEntry->Glyph = GlyphCopy; + NewEntry->BitmapGlyph = BitmapGlyph; NewEntry->Height = Height; InsertHeadList(&FontCacheListHead, &NewEntry->ListEntry); if (FontCacheNumEntries++ > MAX_FONT_CACHE) { NewEntry = (PFONT_CACHE_ENTRY)FontCacheListHead.Blink; - FT_Done_Glyph(NewEntry->Glyph); + FT_Done_Glyph((FT_Glyph)NewEntry->BitmapGlyph); RemoveTailList(&FontCacheListHead); ExFreePool(NewEntry); FontCacheNumEntries--; } - return GlyphCopy; + return BitmapGlyph; } @@ -2103,16 +2121,17 @@ FASTCALL TextIntGetTextExtentPoint(PDC dc, PTEXTOBJ TextObj, LPCWSTR String, - int Count, - int MaxExtent, + INT Count, + ULONG MaxExtent, LPINT Fit, LPINT Dx, - LPSIZE Size) + LPSIZE Size, + FLONG fl) { PFONTGDI FontGDI; FT_Face face; FT_GlyphSlot glyph; - FT_Glyph realglyph; + FT_BitmapGlyph realglyph; INT error, n, glyph_index, i, previous; ULONGLONG TotalWidth = 0; FT_CharMap charmap, found = NULL; @@ -2179,7 +2198,11 @@ TextIntGetTextExtentPoint(PDC dc, for (i = 0; i < Count; i++) { - glyph_index = FT_Get_Char_Index(face, *String); + if (fl & GTEF_INDICES) + glyph_index = *String; + else + glyph_index = FT_Get_Char_Index(face, *String); + if (!(realglyph = ftGdiGlyphCacheGet(face, glyph_index, TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight))) { @@ -2208,7 +2231,7 @@ TextIntGetTextExtentPoint(PDC dc, TotalWidth += delta.x; } - TotalWidth += realglyph->advance.x >> 10; + TotalWidth += realglyph->root.advance.x >> 10; if (((TotalWidth + 32) >> 6) <= MaxExtent && NULL != Fit) { @@ -2226,7 +2249,7 @@ TextIntGetTextExtentPoint(PDC dc, Size->cx = (TotalWidth + 32) >> 6; Size->cy = (TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight < 0 ? - TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight : TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight); - Size->cy = EngMulDiv(Size->cy, IntGdiGetDeviceCaps(dc, LOGPIXELSY), 72); + Size->cy = EngMulDiv(Size->cy, dc->ppdev->gdiinfo.ulLogPixelsY, 72); return TRUE; } @@ -3133,12 +3156,11 @@ GreExtTextOutW( int error, glyph_index, n, i; FT_Face face; FT_GlyphSlot glyph; - FT_Glyph realglyph; - FT_BitmapGlyph realglyph2; + FT_BitmapGlyph realglyph; LONGLONG TextLeft, RealXStart; ULONG TextTop, previous, BackgroundLeft; FT_Bool use_kerning; - RECTL DestRect, MaskRect; + RECTL DestRect, MaskRect, DummyRect = {0, 0, 0, 0}; POINTL SourcePoint, BrushOrigin; HBITMAP HSourceGlyph; SURFOBJ *SourceGlyphSurf; @@ -3153,8 +3175,6 @@ GreExtTextOutW( BOOLEAN Render; POINT Start; BOOL DoBreak = FALSE; - HPALETTE hDestPalette; - PPALETTE ppalDst; USHORT DxShift; // TODO: Write test-cases to exactly match real Windows in different @@ -3174,9 +3194,6 @@ GreExtTextOutW( pdcattr = dc->pdcattr; - if (pdcattr->ulDirty_ & DIRTY_TEXT) - DC_vUpdateTextBrush(dc); - if ((fuOptions & ETO_OPAQUE) || pdcattr->jBkMode == OPAQUE) { if (pdcattr->ulDirty_ & DIRTY_BACKGROUND) @@ -3210,13 +3227,6 @@ GreExtTextOutW( IntLPtoDP(dc, (POINT *)lprc, 2); } - psurf = dc->dclevel.pSurface; - if (!psurf) - { - goto fail; - } - SurfObj = &psurf->SurfObj; - Start.x = XStart; Start.y = YStart; IntLPtoDP(dc, &Start, 1); @@ -3245,8 +3255,13 @@ GreExtTextOutW( DestRect.right += dc->ptlDCOrig.x; DestRect.bottom += dc->ptlDCOrig.y; + DC_vPrepareDCsForBlit(dc, DestRect, NULL, DestRect); + + if (pdcattr->ulDirty_ & DIRTY_BACKGROUND) + DC_vUpdateBackgroundBrush(dc); + IntEngBitBlt( - &psurf->SurfObj, + &dc->dclevel.pSurface->SurfObj, NULL, NULL, dc->rosdc.CombinedClip, @@ -3258,6 +3273,7 @@ GreExtTextOutW( &BrushOrigin, ROP3_TO_ROP4(PATCOPY)); fuOptions &= ~ETO_OPAQUE; + DC_vFinishBlit(dc, NULL); } else { @@ -3400,7 +3416,7 @@ GreExtTextOutW( TextWidth += delta.x; } - TextWidth += realglyph->advance.x >> 10; + TextWidth += realglyph->root.advance.x >> 10; previous = glyph_index; TempText++; @@ -3422,19 +3438,24 @@ GreExtTextOutW( TextTop = YStart; BackgroundLeft = (RealXStart + 32) >> 6; - /* Create the xlateobj */ - hDestPalette = psurf->hDIBPalette; - if (!hDestPalette) hDestPalette = pPrimarySurface->devinfo.hpalDefault; - ppalDst = PALETTE_LockPalette(hDestPalette); - EXLATEOBJ_vInitialize(&exloRGB2Dst, &gpalRGB, ppalDst, 0, 0, 0); - EXLATEOBJ_vInitialize(&exloDst2RGB, ppalDst, &gpalRGB, 0, 0, 0); - PALETTE_UnlockPalette(ppalDst); + /* Lock blit with a dummy rect */ + DC_vPrepareDCsForBlit(dc, DummyRect, NULL, DummyRect); + + psurf = dc->dclevel.pSurface ; + SurfObj = &psurf->SurfObj ; + EXLATEOBJ_vInitialize(&exloRGB2Dst, &gpalRGB, psurf->ppal, 0, 0, 0); + EXLATEOBJ_vInitialize(&exloDst2RGB, psurf->ppal, &gpalRGB, 0, 0, 0); + + if ((fuOptions & ETO_OPAQUE) && (dc->pdcattr->ulDirty_ & DIRTY_BACKGROUND)) + DC_vUpdateBackgroundBrush(dc) ; + + if(dc->pdcattr->ulDirty_ & DIRTY_TEXT) + DC_vUpdateTextBrush(dc) ; /* * The main rendering loop. */ - for (i = 0; i < Count; i++) { if (fuOptions & ETO_GLYPH_INDEX) @@ -3475,28 +3496,15 @@ GreExtTextOutW( } DPRINT("TextLeft: %d\n", TextLeft); DPRINT("TextTop: %d\n", TextTop); - - if (realglyph->format == ft_glyph_format_outline) - { - DPRINT1("Should already be done\n"); -// error = FT_Render_Glyph(glyph, RenderMode); - error = FT_Glyph_To_Bitmap(&realglyph, RenderMode, 0, 0); - if (error) - { - DPRINT1("WARNING: Failed to render glyph!\n"); - goto fail2; - } - } - realglyph2 = (FT_BitmapGlyph)realglyph; - - DPRINT("Advance: %d\n", realglyph->advance.x); + DPRINT("Advance: %d\n", realglyph->root.advance.x); if (fuOptions & ETO_OPAQUE) { DestRect.left = BackgroundLeft; - DestRect.right = (TextLeft + (realglyph->advance.x >> 10) + 32) >> 6; + DestRect.right = (TextLeft + (realglyph->root.advance.x >> 10) + 32) >> 6; DestRect.top = TextTop + yoff - ((face->size->metrics.ascender + 32) >> 6); DestRect.bottom = TextTop + yoff + ((32 - face->size->metrics.descender) >> 6); + MouseSafetyOnDrawStart(dc->ppdev, DestRect.left, DestRect.top, DestRect.right, DestRect.bottom); IntEngBitBlt( &psurf->SurfObj, NULL, @@ -3509,34 +3517,30 @@ GreExtTextOutW( &dc->eboBackground.BrushObject, &BrushOrigin, ROP3_TO_ROP4(PATCOPY)); + MouseSafetyOnDrawEnd(dc->ppdev); BackgroundLeft = DestRect.right; + } - DestRect.left = ((TextLeft + 32) >> 6) + realglyph2->left; - DestRect.right = DestRect.left + realglyph2->bitmap.width; - DestRect.top = TextTop + yoff - realglyph2->top; - DestRect.bottom = DestRect.top + realglyph2->bitmap.rows; + DestRect.left = ((TextLeft + 32) >> 6) + realglyph->left; + DestRect.right = DestRect.left + realglyph->bitmap.width; + DestRect.top = TextTop + yoff - realglyph->top; + DestRect.bottom = DestRect.top + realglyph->bitmap.rows; - bitSize.cx = realglyph2->bitmap.width; - bitSize.cy = realglyph2->bitmap.rows; - MaskRect.right = realglyph2->bitmap.width; - MaskRect.bottom = realglyph2->bitmap.rows; + bitSize.cx = realglyph->bitmap.width; + bitSize.cy = realglyph->bitmap.rows; + MaskRect.right = realglyph->bitmap.width; + MaskRect.bottom = realglyph->bitmap.rows; /* * We should create the bitmap out of the loop at the biggest possible * glyph size. Then use memset with 0 to clear it and sourcerect to * limit the work of the transbitblt. - * - * FIXME: DIB bitmaps should have an lDelta which is a multiple of 4. - * Here we pass in the pitch from the FreeType bitmap, which is not - * guaranteed to be a multiple of 4. If it's not, we should expand - * the FreeType bitmap to a temporary bitmap. */ - HSourceGlyph = EngCreateBitmap(bitSize, realglyph2->bitmap.pitch, - (realglyph2->bitmap.pixel_mode == ft_pixel_mode_grays) ? - BMF_8BPP : BMF_1BPP, BMF_TOPDOWN, - realglyph2->bitmap.buffer); + HSourceGlyph = EngCreateBitmap(bitSize, realglyph->bitmap.pitch, + BMF_8BPP, BMF_TOPDOWN, + realglyph->bitmap.buffer); if ( !HSourceGlyph ) { DPRINT1("WARNING: EngLockSurface() failed!\n"); @@ -3568,7 +3572,7 @@ GreExtTextOutW( DestRect.right = lprc->right + dc->ptlDCOrig.x; DoBreak = TRUE; } - + MouseSafetyOnDrawStart(dc->ppdev, DestRect.left, DestRect.top, DestRect.right, DestRect.bottom); IntEngMaskBlt( SurfObj, SourceGlyphSurf, @@ -3579,6 +3583,7 @@ GreExtTextOutW( (PPOINTL)&MaskRect, &dc->eboText.BrushObject, &BrushOrigin); + MouseSafetyOnDrawEnd(dc->ppdev) ; EngUnlockSurface(SourceGlyphSurf); EngDeleteSurface((HSURF)HSourceGlyph); @@ -3590,7 +3595,7 @@ GreExtTextOutW( if (NULL == Dx) { - TextLeft += realglyph->advance.x >> 10; + TextLeft += realglyph->root.advance.x >> 10; DPRINT("new TextLeft: %d\n", TextLeft); } else @@ -3608,9 +3613,9 @@ GreExtTextOutW( String++; } - IntUnLockFreeType; + DC_vFinishBlit(dc, NULL) ; EXLATEOBJ_vCleanup(&exloRGB2Dst); EXLATEOBJ_vCleanup(&exloDst2RGB); if (TextObj != NULL) @@ -3626,6 +3631,7 @@ fail2: fail: if (TextObj != NULL) TEXTOBJ_UnlockText(TextObj); + DC_UnlockDc(dc); return FALSE; @@ -4243,16 +4249,17 @@ NtGdiGetGlyphIndicesW( IntLockFreeType; face = FontGDI->face; + if (DefChar == 0xffff && FT_IS_SFNT(face)) + { + TT_OS2 *pOS2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2); + DefChar = (pOS2->usDefaultChar ? FT_Get_Char_Index(face, pOS2->usDefaultChar) : 0); + } + for (i = 0; i < cwc; i++) { - Buffer[i] = FT_Get_Char_Index(face, UnSafepwc[i]); + Buffer[i] = FT_Get_Char_Index(face, UnSafepwc[i]); // FIXME: unsafe! if (Buffer[i] == 0) { - if (DefChar == 0xffff && FT_IS_SFNT(face)) - { - TT_OS2 *pOS2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2); - DefChar = (pOS2->usDefaultChar ? FT_Get_Char_Index(face, pOS2->usDefaultChar) : 0); - } Buffer[i] = DefChar; } }