⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 text.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:

  Status = RtlQueryRegistryValues(RTL_REGISTRY_WINDOWS_NT,
                                  L"SysFontSubstitutes",
                                  QueryTable,
                                  &Context,
                                  NULL);
  if (NT_SUCCESS(Status))
    {
      *Count = Context.Count;
    }

  return NT_SUCCESS(Status) || STATUS_OBJECT_NAME_NOT_FOUND == Status;
}

int STDCALL
NtGdiGetFontFamilyInfo(HDC Dc,
                       LPLOGFONTW UnsafeLogFont,
                       PFONTFAMILYINFO UnsafeInfo,
                       DWORD Size)
{
  NTSTATUS Status;
  LOGFONTW LogFont;
  PFONTFAMILYINFO Info;
  DWORD Count;
  PW32PROCESS Win32Process;

  /* Make a safe copy */
  Status = MmCopyFromCaller(&LogFont, UnsafeLogFont, sizeof(LOGFONTW));
  if (! NT_SUCCESS(Status))
    {
      SetLastWin32Error(ERROR_INVALID_PARAMETER);
      return -1;
    }

  /* Allocate space for a safe copy */
  Info = ExAllocatePoolWithTag(PagedPool, Size * sizeof(FONTFAMILYINFO), TAG_GDITEXT);
  if (NULL == Info)
    {
      SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
      return -1;
    }

  /* Enumerate font families in the global list */
  IntLockGlobalFonts;
  Count = 0;
  if (! GetFontFamilyInfoForList(&LogFont, Info, &Count, Size, &FontListHead) )
    {
      IntUnLockGlobalFonts;
      ExFreePool(Info);
      return -1;
    }
  IntUnLockGlobalFonts;

  /* Enumerate font families in the process local list */
  Win32Process = PsGetCurrentProcessWin32Process();
  IntLockProcessPrivateFonts(Win32Process);
  if (! GetFontFamilyInfoForList(&LogFont, Info, &Count, Size,
                                 &Win32Process->PrivateFontListHead))
    {
      IntUnLockProcessPrivateFonts(Win32Process);
      ExFreePool(Info);
      return -1;
    }
  IntUnLockProcessPrivateFonts(Win32Process);

  /* Enumerate font families in the registry */
  if (! GetFontFamilyInfoForSubstitutes(&LogFont, Info, &Count, Size))
    {
      ExFreePool(Info);
      return -1;
    }

  /* Return data to caller */
  if (0 != Count)
    {
      Status = MmCopyToCaller(UnsafeInfo, Info,
                              (Count < Size ? Count : Size) * sizeof(FONTFAMILYINFO));
      if (! NT_SUCCESS(Status))
        {
          ExFreePool(Info);
          SetLastWin32Error(ERROR_INVALID_PARAMETER);
          return -1;
        }
    }

  ExFreePool(Info);

  return Count;
}

int
STDCALL
NtGdiEnumFonts(HDC  hDC,
                   LPCWSTR FaceName,
                   FONTENUMPROCW  FontFunc,
                   LPARAM  lParam)
{
  UNIMPLEMENTED;
  return 0;
}
FT_Glyph STDCALL
NtGdiGlyphCacheGet(
   FT_Face Face,
   INT GlyphIndex,
   INT Height)
{
   PLIST_ENTRY CurrentEntry;
   PFONT_CACHE_ENTRY FontEntry;

//   DbgPrint("CacheGet\n");

   CurrentEntry = FontCacheListHead.Flink;
   while (CurrentEntry != &FontCacheListHead)
   {
      FontEntry = (PFONT_CACHE_ENTRY)CurrentEntry;
      if (FontEntry->Face == Face &&
          FontEntry->GlyphIndex == GlyphIndex &&
          FontEntry->Height == Height)
         break;
      CurrentEntry = CurrentEntry->Flink;
   }

   if (CurrentEntry == &FontCacheListHead) {
//      DbgPrint("Miss! %x\n", FontEntry->Glyph);
/*
      Misses++;
      if (Misses>100) {
         DbgPrint ("Hits: %d Misses: %d\n", Hits, Misses);
         Hits = Misses = 0;
      }
*/
      return NULL;
   }

   RemoveEntryList(CurrentEntry);
   InsertHeadList(&FontCacheListHead, CurrentEntry);

//   DbgPrint("Hit! %x\n", FontEntry->Glyph);
/*
   Hits++;

      if (Hits>100) {
         DbgPrint ("Hits: %d Misses: %d\n", Hits, Misses);
         Hits = Misses = 0;
      }
*/
   return FontEntry->Glyph;
}

FT_Glyph STDCALL
NtGdiGlyphCacheSet(
   FT_Face Face,
   INT GlyphIndex,
   INT Height,
   FT_GlyphSlot GlyphSlot,
   FT_Render_Mode RenderMode)
{
   FT_Glyph GlyphCopy;
   INT error;
   PFONT_CACHE_ENTRY NewEntry;

//   DbgPrint("CacheSet.\n"); 

   error = FT_Get_Glyph(GlyphSlot, &GlyphCopy);
   if (error)
   {
      DbgPrint("Failure caching glyph.\n"); 
      return NULL;
   };
   error = FT_Glyph_To_Bitmap(&GlyphCopy, RenderMode, 0, 1);
   if (error)
   {
      DbgPrint("Failure rendering glyph.\n"); 
      return NULL;
   };

   NewEntry = ExAllocatePoolWithTag(PagedPool, sizeof(FONT_CACHE_ENTRY), TAG_FONT);
   if (!NewEntry)
   {
      DbgPrint("Alloc failure caching glyph.\n");
      FT_Done_Glyph(GlyphCopy);
      return NULL;
   }

   NewEntry->GlyphIndex = GlyphIndex;
   NewEntry->Face = Face;
   NewEntry->Glyph = GlyphCopy;
   NewEntry->Height = Height;

   InsertHeadList(&FontCacheListHead, &NewEntry->ListEntry);
   if (FontCacheNumEntries++ > MAX_FONT_CACHE) {
      NewEntry = (PFONT_CACHE_ENTRY)FontCacheListHead.Blink;
      FT_Done_Glyph(NewEntry->Glyph);
      RemoveTailList(&FontCacheListHead);
      ExFreePool(NewEntry);
      FontCacheNumEntries--;
   }

//   DbgPrint("Returning the glyphcopy: %x\n", GlyphCopy);

   return GlyphCopy;
}

BOOL STDCALL
NtGdiExtTextOut(
   HDC hDC,
   INT XStart,
   INT YStart,
   UINT fuOptions,
   CONST RECT *lprc,
   LPCWSTR UnsafeString,
   UINT Count,
   CONST INT *UnsafeDx)
{
   /*
    * FIXME:
    * Call EngTextOut, which does the real work (calling DrvTextOut where
    * appropriate)
    */

   DC *dc;
   SURFOBJ *SurfObj;
   BITMAPOBJ *BitmapObj = NULL;
   int error, glyph_index, n, i;
   FT_Face face;
   FT_GlyphSlot glyph;
   FT_Glyph realglyph;
   FT_BitmapGlyph realglyph2;
   LONGLONG TextLeft, RealXStart;
   ULONG TextTop, previous, BackgroundLeft;
   FT_Bool use_kerning;
   RECTL DestRect, MaskRect, SpecifiedDestRect;
   POINTL SourcePoint, BrushOrigin;
   HBRUSH hBrushFg = NULL;
   PGDIBRUSHOBJ BrushFg = NULL;
   GDIBRUSHINST BrushFgInst;
   HBRUSH hBrushBg = NULL;
   PGDIBRUSHOBJ BrushBg = NULL;
   GDIBRUSHINST BrushBgInst;
   HBITMAP HSourceGlyph;
   SURFOBJ *SourceGlyphSurf;
   SIZEL bitSize;
   FT_CharMap found = 0, charmap;
   INT yoff;
   FONTOBJ *FontObj;
   PFONTGDI FontGDI;
   PTEXTOBJ TextObj = NULL;
   PPALGDI PalDestGDI;
   XLATEOBJ *XlateObj=NULL, *XlateObj2=NULL;
   ULONG Mode;
   FT_Render_Mode RenderMode;
   BOOLEAN Render;
   NTSTATUS Status;
   INT *Dx = NULL;
   POINT Start;
   BOOL DoBreak = FALSE;
   LPCWSTR String, SafeString = NULL;

   // 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)
   {
      SetLastWin32Error(ERROR_INVALID_HANDLE);
      return FALSE;
   }
   if (dc->IsIC)
   {
      DC_UnlockDc(dc);
      /* Yes, Windows really returns TRUE in this case */
      return TRUE;
   }

	/* Check if String is valid */
   if ((Count > 0xFFFF) || (Count > 0 && UnsafeString == NULL))
   {
      SetLastWin32Error(ERROR_INVALID_PARAMETER);
      goto fail;
   }
   if (Count > 0)
   {
      SafeString = ExAllocatePoolWithTag(PagedPool, Count * sizeof(WCHAR), TAG_GDITEXT);
      if (!SafeString)
      {
         goto fail;
      }
      Status = MmCopyFromCaller(SafeString, UnsafeString, Count * sizeof(WCHAR));
      if (! NT_SUCCESS(Status))
      {
        goto fail;
      }
   }
   String = SafeString;

   if (lprc && (fuOptions & (ETO_OPAQUE | ETO_CLIPPED)))
   {
      // At least one of the two flags were specified. Copy lprc. Once.
      Status = MmCopyFromCaller(&SpecifiedDestRect, lprc, sizeof(RECT));
      if (!NT_SUCCESS(Status))
      {
         DC_UnlockDc(dc);
         SetLastWin32Error(ERROR_INVALID_PARAMETER);
         return FALSE;
      }
      IntLPtoDP(dc, (POINT *) &SpecifiedDestRect, 2);
   }

   if (NULL != UnsafeDx && Count > 0)
   {
      Dx = ExAllocatePoolWithTag(PagedPool, Count * sizeof(INT), TAG_GDITEXT);
      if (NULL == Dx)
      {
         goto fail;
      }
      Status = MmCopyFromCaller(Dx, UnsafeDx, Count * sizeof(INT));
      if (! NT_SUCCESS(Status))
      {
         goto fail;
      }
   }

   BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
   if ( !BitmapObj )
   {
      goto fail;
   }
   SurfObj = &BitmapObj->SurfObj;
   ASSERT(SurfObj);

   Start.x = XStart; Start.y = YStart;
   IntLPtoDP(dc, &Start, 1);

   RealXStart = (Start.x + dc->w.DCOrgX) << 6;
   YStart = Start.y + dc->w.DCOrgY;

   /* Create the brushes */
   PalDestGDI = PALETTE_LockPalette(dc->w.hPalette);
   if ( !PalDestGDI )
      Mode = PAL_RGB;
   else
   {
      Mode = PalDestGDI->Mode;
      PALETTE_UnlockPalette(PalDestGDI);
   }
   XlateObj = (XLATEOBJ*)IntEngCreateXlate(Mode, PAL_RGB, dc->w.hPalette, NULL);
   if ( !XlateObj )
   {
      goto fail;
   }
   hBrushFg = NtGdiCreateSolidBrush(XLATEOBJ_iXlate(XlateObj, dc->Dc_Attr.crForegroundClr), 0);
   if ( !hBrushFg )
   {
      goto fail;
   }
   BrushFg = BRUSHOBJ_LockBrush(hBrushFg);
   if ( !BrushFg )
   {
      goto fail;
   }
   IntGdiInitBrushInstance(&BrushFgInst, BrushFg, NULL);
   if ((fuOptions & ETO_OPAQUE) || dc->Dc_Attr.jBkMode == OPAQUE)
   {
      hBrushBg = NtGdiCreateSolidBrush(XLATEOBJ_iXlate(XlateObj, dc->Dc_Attr.crBackgroundClr), 0);
      if ( !hBrushBg )
      {
         goto fail;
      }
      BrushBg = BRUSHOBJ_LockBrush(hBrushBg);
      if ( !BrushBg )
      {
         goto fail;
      }
      IntGdiInitBrushInstance(&BrushBgInst, BrushBg, NULL);
   }
   XlateObj2 = (XLATEOBJ*)IntEngCreateXlate(PAL_RGB, Mode, NULL, dc->w.hPalette);
   if ( !XlateObj2 )
   {
      goto fail;
   }

   SourcePoint.x = 0;
   SourcePoint.y = 0;
   MaskRect.left = 0;
   MaskRect.top = 0;
   BrushOrigin.x = 0;
   BrushOrigin.y = 0;

   if ((fuOptions & ETO_OPAQUE) && lprc)
   {
      DestRect.left   = SpecifiedDestRect.left   + dc->w.DCOrgX;
      DestRect.top    = SpecifiedDestRect.top    + dc->w.DCOrgY;
      DestRect.right  = SpecifiedDestRect.right  + dc->w.DCOrgX;
      DestRect.bottom = SpecifiedDestRect.bottom + dc->w.DCOrgY;
      IntLPtoDP(dc, (LPPOINT)&DestRect, 2);
      IntEngBitBlt(
         &BitmapObj->SurfObj,
         NULL,
         NULL,
         dc->CombinedClip,
         NULL,
         &DestRect,
         &SourcePoint,
         &SourcePoint,
         &BrushBgInst.BrushObject,
         &BrushOrigin,
         ROP3_TO_ROP4(PATCOPY));
      fuOptions &= ~ETO_OPAQUE;
   }
   else
   {
      if (dc->Dc_Attr.jBkMode == OPAQUE)
      {
         fuOptions |= ETO_OPAQUE;
      }
   }

   TextObj = TEXTOBJ_LockText(dc->Dc_Attr.hlfntNew);
   if(TextObj == NULL)
   {
      goto fail;
   }

   FontObj = TextObj->Font;
   ASSERT(FontObj);
   FontGDI = ObjToGDI(FontObj, FONT);
   ASSERT(FontGDI);

   IntLockFreeType;
   face = FontGDI->face;
   if (face->charmap == NULL)
   {
      DPRINT("WARNING: No charmap selected!\n");
      DPRINT("This font face has %d charmaps\n", face->num_charmaps);

      for (n = 0; n < face->num_charmaps; n++)
      {
         charmap = face->charmaps[n];
         DPRINT("found charmap encoding: %u\n", charmap->encoding);
         if (charmap->encoding != 0)
         {
            found = charmap;
            break;
         }
      }
      if (!found)
      {
         DPRINT1("WARNING: Could not find desired charmap!\n");
      }
      error = FT_Set_Charmap(face, found);
         if (error)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -