2017-06-15 6 views
2

Je suis sur le point de remplacer le code de dessin d'un ancien composant de GDI + UniScribe par Direct2D et DirectWrite (les successeurs). Jusqu'à présent, la transition était simple car la plupart du temps, tout ce que je devais faire était de remplacer les appels au Canvas (classe TCanvas) par une instance FDirect2DCanvas personnalisée (classe TDirect2DCanvas, à partir de l'unité Direct2D). Malheureusement, il ne semble pas si simple d'essayer de dessiner un glyphe à partir d'une instance de TImageList sur le FDirect2DCanvas car la méthode draw est uniquement destinée à TCanvas et non au TCustomCanvas plutôt général (qui est l'ancêtre de TCanvas et de TCanvas). TDirect2DCanvas).Dessin d'un glyphe TImageList dans un TDirect2DCanvas

Une solution pour ce dilemme consisterait à dessiner le glyphe TImageList dans une image bitmap temporaire et à dessiner cela dans le TDirect2DCanvas. Cependant, je crains que cela ne ralentisse probablement la performance du dessin.

Quelqu'un a-t-il déjà fait cela jusqu'à présent? Quelles options ai-je?

Répondre

2

Si vous regardez comment dessiner des objets graphiques à TDirect2DCanvas est implémenté, vous constaterez qu'il parcourt cette routine.

procedure TDirect2DCanvas.StretchDraw(const Rect: TRect; Graphic: TGraphic; 
    Opacity: Byte); 
var 
    D2DBitmap: ID2D1Bitmap; 
    D2DRect: TD2DRectF; 
    Bitmap: TBitmap; 
begin 
    Bitmap := TBitmap.Create; 
    try 
    Bitmap.Assign(Graphic); 

    D2DBitmap := CreateBitmap(Bitmap); 

    D2DRect.Left := Rect.Left; 
    D2DRect.Right := Rect.Right; 
    D2DRect.Top := Rect.Top; 
    D2DRect.Bottom := Rect.Bottom; 
    RenderTarget.DrawBitmap(D2DBitmap, @D2DRect, Opacity/255); 
    finally 
    Bitmap.Free; 
    end; 
end; 

Nous allons unpick les étapes:

  1. Créer une image bitmap temporaire.
  2. Copiez le graphique dans cette image bitmap.
  3. Créez un ID2D1Bitmap et copiez le bitmap temporaire dans celui-ci.
  4. Dessinez ce ID2D1Bitmap sur la cible de rendu.

Cela semble déjà très inefficace. Certes, il serait irritant d'appeler cette fonction en passant dans un TBitmap et d'en faire une copie sans raison valable.

Ce genre de chose est difficile à éviter lorsque vous essayez de fusionner deux cadres graphiques distincts. Votre liste d'images est basée sur GDI, et donc liée à la friction lorsque vous essayez de l'envoyer à un canevas Direct2D. Il n'y a tout simplement pas moyen de passer des bitmaps GDI directement à un canevas Direct2D, ils doivent d'abord être convertis en bitmaps Direct2D.

Si la performance est ce qui compte pour vous, vous ne devriez pas partir d'une liste d'images. Cela entraînera inévitablement des coûts lorsque vous extrayez le bitmap de la liste d'images GDI, puis le convertissez en l'objet Direct2D équivalent, ID2D1Bitmap.

Afin d'obtenir des performances optimales, ne travaillez pas avec les listes d'images. Extrayez chaque image de la liste d'images et utilisez TDirect2DCanvas.CreateBitmap pour obtenir une image bitmap Direct2D, ID2D1Bitmap. Stockez-les plutôt que la liste d'images. Ensuite, lorsque vous avez besoin de dessiner, appelez DrawBitmap sur RenderTarget, en passant un ID2D1Bitmap.