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

📄 text.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
      {
         DPRINT1("WARNING: Could not set the charmap!\n");
      }
   }

   Render = IntIsFontRenderingEnabled();
   if (Render)
      RenderMode = IntGetFontRenderMode(&TextObj->logfont.elfEnumLogfontEx.elfLogFont);
   else
      RenderMode = FT_RENDER_MODE_MONO;

   error = FT_Set_Pixel_Sizes(
      face,
      TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfWidth,
      /* FIXME should set character height if neg */
      (TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight < 0 ?
      - TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight :
      TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight == 0 ? 11 : TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight));
   if (error)
   {
      DPRINT1("Error in setting pixel sizes: %u\n", error);
      IntUnLockFreeType;
      goto fail;
   }

   /*
    * Process the vertical alignment and determine the yoff.
    */

   if (dc->Dc_Attr.lTextAlign & TA_BASELINE)
      yoff = 0;
   else if (dc->Dc_Attr.lTextAlign & TA_BOTTOM)
      yoff = -face->size->metrics.descender >> 6;
   else /* TA_TOP */
      yoff = face->size->metrics.ascender >> 6;

   use_kerning = FT_HAS_KERNING(face);
   previous = 0;

   /*
    * Process the horizontal alignment and modify XStart accordingly.
    */

   if (dc->Dc_Attr.lTextAlign & (TA_RIGHT | TA_CENTER))
   {
      ULONGLONG TextWidth = 0;
      LPCWSTR TempText = String;
      int Start;

      /*
       * Calculate width of the text.
       */

      if (NULL != Dx)
      {
         Start = Count < 2 ? 0 : Count - 2;
         TextWidth = Count < 2 ? 0 : (Dx[Count - 2] << 6);
      }
      else
      {
         Start = 0;
      }
      TempText = String + Start;

      for (i = Start; i < Count; i++)
      {
         if (fuOptions & ETO_GLYPH_INDEX)
           glyph_index = *TempText;
         else
           glyph_index = FT_Get_Char_Index(face, *TempText);

         if (!(realglyph = NtGdiGlyphCacheGet(face, glyph_index,
         TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight)))
         {
             error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
             if (error)
             {
                DPRINT1("WARNING: Failed to load and render glyph! [index: %u]\n", glyph_index);
             }

             glyph = face->glyph;
             realglyph = NtGdiGlyphCacheSet(face, glyph_index, 
                TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight, glyph, RenderMode);
             if (!realglyph)
             {
                 DPRINT1("Failed to render glyph! [index: %u]\n", glyph_index);
                 IntUnLockFreeType;
                 goto fail;
             }      

         }
         /* retrieve kerning distance */
         if (use_kerning && previous && glyph_index)
         {
            FT_Vector delta;
            FT_Get_Kerning(face, previous, glyph_index, 0, &delta);
            TextWidth += delta.x;
         }

         TextWidth += realglyph->advance.x >> 10;

         previous = glyph_index;
         TempText++;
      }

      previous = 0;

      if (dc->Dc_Attr.lTextAlign & TA_RIGHT)
      {
         RealXStart -= TextWidth;
      }
      else
      {
         RealXStart -= TextWidth / 2;
      }
   }

   TextLeft = RealXStart;
   TextTop = YStart;
   BackgroundLeft = (RealXStart + 32) >> 6;

   /*
    * The main rendering loop.
    */

   for (i = 0; i < Count; i++)
   {
      if (fuOptions & ETO_GLYPH_INDEX)
        glyph_index = *String;
      else
        glyph_index = FT_Get_Char_Index(face, *String);

      if (!(realglyph = NtGdiGlyphCacheGet(face, glyph_index, 
      TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight)))
      {
        error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
        if (error)
        {
           DPRINT1("Failed to load and render glyph! [index: %u]\n", glyph_index);
           IntUnLockFreeType;
           goto fail;
        }
        glyph = face->glyph;
        realglyph = NtGdiGlyphCacheSet(face, 
                                       glyph_index, 
                                       TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight, 
                                       glyph, 
                                       RenderMode);
        if (!realglyph)
        {
            DPRINT1("Failed to render glyph! [index: %u]\n", glyph_index);
            IntUnLockFreeType;
            goto fail;
        }      
      }
//      DbgPrint("realglyph: %x\n", realglyph);
//      DbgPrint("TextLeft: %d\n", TextLeft);

      /* retrieve kerning distance and move pen position */
      if (use_kerning && previous && glyph_index && NULL == Dx)
      {
         FT_Vector delta;
         FT_Get_Kerning(face, previous, glyph_index, 0, &delta);
         TextLeft += delta.x;
      }
//      DPRINT1("TextLeft: %d\n", TextLeft);
//      DPRINT1("TextTop: %d\n", TextTop);

      if (realglyph->format == ft_glyph_format_outline)
      {
         DbgPrint("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 fail;
         }
      }
      realglyph2 = (FT_BitmapGlyph)realglyph;

//      DPRINT1("Pitch: %d\n", pitch);
//      DPRINT1("Advance: %d\n", realglyph->advance.x);

      if (fuOptions & ETO_OPAQUE)
      {
         DestRect.left = BackgroundLeft;
         DestRect.right = (TextLeft + (realglyph->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);
         IntEngBitBlt(
            &BitmapObj->SurfObj,
            NULL,
            NULL,
            dc->CombinedClip,
            NULL,
            &DestRect,
            &SourcePoint,
            &SourcePoint,
            &BrushBgInst.BrushObject,
            &BrushOrigin,
            ROP3_TO_ROP4(PATCOPY));
         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;

//      DbgPrint("lrtb %d %d %d %d\n", DestRect.left, DestRect.right,
//                                     DestRect.top, DestRect.bottom);
//      DbgPrint("specified lrtb %d %d %d %d\n", SpecifiedDestRect.left, SpecifiedDestRect.right,
//                                     SpecifiedDestRect.top, SpecifiedDestRect.bottom);
//      DbgPrint ("dc->w.DCOrgX: %d\n", dc->w.DCOrgX);

      bitSize.cx = realglyph2->bitmap.width;
      bitSize.cy = realglyph2->bitmap.rows;
      MaskRect.right = realglyph2->bitmap.width;
      MaskRect.bottom = realglyph2->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);
      if ( !HSourceGlyph )
      {
        DPRINT1("WARNING: EngLockSurface() failed!\n");
        // FT_Done_Glyph(realglyph);
        IntUnLockFreeType;
        goto fail;
      }
      SourceGlyphSurf = EngLockSurface((HSURF)HSourceGlyph);
      if ( !SourceGlyphSurf )
      {
        EngDeleteSurface((HSURF)HSourceGlyph);
        DPRINT1("WARNING: EngLockSurface() failed!\n");
        IntUnLockFreeType;
        goto fail;
      }

      /*
       * Use the font data as a mask to paint onto the DCs surface using a
       * brush.
       */

      if (lprc &&
          (fuOptions & ETO_CLIPPED) &&
          DestRect.right >= SpecifiedDestRect.right + dc->w.DCOrgX)
      {
         // We do the check '>=' instead of '>' to possibly save an iteration
         // through this loop, since it's breaking after the drawing is done,
         // and x is always incremented.
         DestRect.right = SpecifiedDestRect.right + dc->w.DCOrgX;
         DoBreak = TRUE;
      }

      IntEngMaskBlt(
         SurfObj,
         SourceGlyphSurf,
         dc->CombinedClip,
         XlateObj,
         XlateObj2,
         &DestRect,
         &SourcePoint,
         (PPOINTL)&MaskRect,
         &BrushFgInst.BrushObject,
         &BrushOrigin);

      EngUnlockSurface(SourceGlyphSurf);
      EngDeleteSurface((HSURF)HSourceGlyph);

      if (DoBreak)
      {
         break;
      }

      if (NULL == Dx)
      {
         TextLeft += realglyph->advance.x >> 10;
//         DbgPrint("new TextLeft: %d\n", TextLeft);
      }
      else
      {
         TextLeft += Dx[i] << 6;
//         DbgPrint("new TextLeft2: %d\n", TextLeft);
      }
      previous = glyph_index;

      String++;
   }

   IntUnLockFreeType;

   EngDeleteXlate(XlateObj);
   EngDeleteXlate(XlateObj2);
   BITMAPOBJ_UnlockBitmap(BitmapObj);
   if(TextObj != NULL)
     TEXTOBJ_UnlockText(TextObj);
   if (hBrushBg != NULL)
   {
      BRUSHOBJ_UnlockBrush(BrushBg);
      NtGdiDeleteObject(hBrushBg);
   }
   BRUSHOBJ_UnlockBrush(BrushFg);
   NtGdiDeleteObject(hBrushFg);
   if (NULL != SafeString)
   {
      ExFreePool((void*)SafeString);
   }
   if (NULL != Dx)
   {
      ExFreePool(Dx);
   }
   DC_UnlockDc( dc );

   return TRUE;

fail:
   if ( XlateObj2 != NULL )
      EngDeleteXlate(XlateObj2);
   if ( XlateObj != NULL )
      EngDeleteXlate(XlateObj);
   if(TextObj != NULL)
     TEXTOBJ_UnlockText(TextObj);
   BITMAPOBJ_UnlockBitmap(BitmapObj);
   if (hBrushBg != NULL)
   {
      BRUSHOBJ_UnlockBrush(BrushBg);
      NtGdiDeleteObject(hBrushBg);
   }
   if (hBrushFg != NULL)
   {
      BRUSHOBJ_UnlockBrush(BrushFg);
      NtGdiDeleteObject(hBrushFg);
   }
   if (NULL != SafeString)
   {
      ExFreePool((void*)SafeString);
   }
   if (NULL != Dx)
   {
      ExFreePool(Dx);
   }
   DC_UnlockDc(dc);

   return FALSE;
}

BOOL
STDCALL
NtGdiGetAspectRatioFilterEx(HDC  hDC,
                                 LPSIZE  AspectRatio)
{
  UNIMPLEMENTED;
  return FALSE;
}

BOOL
STDCALL
NtGdiGetCharABCWidths(HDC  hDC,
                           UINT  FirstChar,
                           UINT  LastChar,
                           LPABC  abc)
{
   LPABC SafeBuffer;
   PDC dc;
   PTEXTOBJ TextObj;
   PFONTGDI FontGDI;
   FT_Face face;
   FT_CharMap charmap, found = NULL;
   UINT i, glyph_index, BufferSize;
   HFONT hFont = 0;
   NTSTATUS Status;

   if (LastChar < FirstChar)
   {
      SetLastWin32Error(ERROR_INVALID_PARAMETER);
      return FALSE;
   }

   BufferSize = (LastChar - FirstChar + 1) * sizeof(ABC);
   SafeBuffer = ExAllocatePoolWithTag(PagedPool, BufferSize, TAG_GDITEXT);
   if (SafeBuffer == NULL)
   {
      SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
      return FALSE;
   }

   dc = DC_LockDc(hDC);
   if (dc == NULL)
   {
      ExFreePool(SafeBuffer);
      SetLastWin32Error(ERROR_INVALID_HANDLE);
      return FALSE;
   }
   hFont = dc->Dc_Attr.hlfntNew;
   TextObj = TEXTOBJ_LockText(hFont);
   DC_UnlockDc(dc);

   if (TextObj == NULL)
   {
      ExFreePool(SafeBuffer);
      SetLastWin32Error(ERROR_INVALID_HANDLE);
      return FALSE;
   }

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

   face = FontGDI->face;
   if (face->charmap == NULL)
   {
      for (i = 0; i < face->num_charmaps; i++)
      {
         charmap = face->charmaps[i];
         if (charmap->encoding != 0)
         {
            found = charmap;
            break;
         }
      }

      if (!found)
      {
         DPRINT1("WARNING: Could not find desired charmap!\n");
         ExFreePool(SafeBuffer);
         SetLastWin32Error(ERROR_INVALID_HANDLE);
         return FALSE;
      }

      IntLockFreeType;
      FT_Set_Charmap(face, found);
      IntUnLockFreeType;
   }

   IntLockFreeType;
   FT_Set_Pixel_Sizes(face,
                      TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfWidth,
                      /* FIXME should set charac

⌨️ 快捷键说明

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