Jump to content

ObjectCreateInterface callback


ahmet
 Share

Recommended Posts

Hello, I am trying to make a custom text renderer using DirectWrite. According to this I have made a custom renderer using ObjectFromTag.

Global $oMyRenderer = ObjectFromTag("MyRenderer_", $tagIDWriteTextRenderer, $tStruct, False, False, True, $sIID_IDWriteTextRenderer)

This renderer is then used in subcalssed Draw method of IDWriteTextLayout.

;create IDWriteTextLayout object
Local $oDW_Layout = _DWrite_Factory_CreateTextLayout($oDW_Factory, $sString, $oDW_Format, 300, 450) ;max width, max height
;replace Draw method of $oDW_Layout with our own so that custom text renderer can be used
Local $hLayoutDrawCallback_New = DllCallbackRegister("Draw", "long", "ptr;ptr;ptr;float;float") ;Draw hresult(struct*;struct*;float;float)-https://docs.microsoft.com/en-us/windows/win32/api/dwrite/nf-dwrite-idwritetextlayout-draw
Local $pLayoutDrawCallback_New = DllCallbackGetPtr($hLayoutDrawCallback_New)
Local $pDW_Layout = Ptr($oDW_Layout())
$pTextLayout_Draw_Original = ReplaceVTableFuncPtr($pDW_Layout, (56 + 3 - 1) * 4, $pLayoutDrawCallback_New)

Right now I am having two issues. First one is as it seems there is some issue with pointers.

Func MyRenderer_DrawGlyphRun($pSelf, $pClientDrawingContext, $fBaselineOriginX, $fBaselineOriginY, $iMeasuringMode, $pGlyphRun, $pGlyphRunDescription, $pClientDrawingEffect)   ; Ret: long  Par: struct*;float;float;uint;struct*;struct*;struct*
    ConsoleWrite("MyRenderer_DrawGlyphRun()" & @CRLF & @CRLF)
    ConsoleWrite(@TAB & "x:" & $fBaselineOriginX & ", y:" & $fBaselineOriginY & @CRLF)
    ConsoleWrite(@TAB & "$pClientDrawingEffect=" & $pClientDrawingEffect & @CRLF)
    $tData = DllStructCreate($tagDWRITE_GLYPH_RUN_DESCRIPTION, $pGlyphRun)
    If @error Then
        ConsoleWrite(@TAB & "!DllStructCreate error:" & @error & ", ptr=" & $pGlyphRun & @CRLF)
    Else
        ConsoleWrite(@TAB & "FontEmSize:" & DllStructGetData($tData, "FontEmSize") & @CRLF)
    EndIf
    Return 0 ; S_OK = 0x00000000
EndFunc   ;==>MyRenderer_DrawGlyphRun

For $pGlyphRunI keep getting 0. Same situation happens with MyRenderer_DrawUnderline and pointers there. If the default renderer is used in subclassed Draw method then text draws fine. Floating point values are fine. I have checked tag generation in ObjectFromTag. That looks good.

Func Draw($pSelf, $oClientDrawingContext, $oRenderer, $fOriginX, $fOriginY)
    ConsoleWrite("Draw called" & @CRLF)
    ConsoleWrite("x=" & $fOriginX & ",y=" & $fOriginY & @CRLF)
    $aResult = DllCallAddress("long", $pTextLayout_Draw_Original, "ptr", $pSelf, "ptr", $oClientDrawingContext, "ptr", $oMyRenderer, "float", $fOriginX, "float", $fOriginY)
;~  If @error Then MsgBox(0,"Error at draw",@error)
    ;uncomment next line to see text
    $aResult = DllCallAddress("long", $pTextLayout_Draw_Original, "ptr", $pSelf, "ptr", $oClientDrawingContext, "ptr", $oRenderer, "float", $fOriginX, "float", $fOriginY)

;~  Return $aResult[0]
EndFunc   ;==>Draw

Maybe I have done something wrong in those callbacks.

Second issue I am having is with *clientDrawingContext. I am not sure whether I should define that and then use in custom renderer. Microsoft's documentation says "clientDrawingContext Type: void* The application-defined drawing context passed to IDWriteTextLayout::Draw".

HRESULT DrawUnderline(
       void                   *clientDrawingContext,
       FLOAT                  baselineOriginX,
       FLOAT                  baselineOriginY,
  [in] DWRITE_UNDERLINE const *underline,
       IUnknown               *clientDrawingEffect
);

I am attaching full script here. DirectWrite UDF can be downloaded from https://autoit.de/wcf/attachment/82843-direct2d-7z/.

_DWrite_IDWriteTextRenderer.au3

Link to comment
Share on other sites

I don't have alot of time to look at this and try to glean what you're trying to do.  I will say that theres got to be easier ways to do whatever it is that you're attempting.  You've departed so far from the typical style of writing in autoit that you'd honestly be better off just learning a different one.  I'm not saying not to continue but i've found doing things outside of the box to be an exercise if futility at best.  

All that I mind dllcallback functions don't just automatically work if you just send them out.  The dll usually has a declaration for that function but not a body... the callbackregister is basically saying "hey I have a function body for your declaration".  That function body needs to match the signature of the declaration, in otherwords the parameters and return type have to match.  Like I said I havn't done a deep dive into what you're doing here but the callbacks arent' just a free floating function that materializes out of thin air.  <~~~~~~at least to the best of my understanding

If you're interested in an easy to learn graphics library check out gdi+ or this...  https://www.raylib.com/

I havn't used raylib on autoit but I believe that they have an autoit build? I know they make mention of it on their website somewhere.  Once you get it up and running you can do some pretty cool stuff with it.  I used it to make a simple tic tac toe game for the purposes of building an unbeatable ai.  It works pretty good.  Kinda a pita to get in the mindset of doing all the draw calls and input grabs etc in one while loop but it seems much easier than the deep weeds that you're currently in. Good luck

 

Edit: I'd also like to add that a callback function usually gets called by a function within the dll that you're registering to and by registering your basically populating the variable in that dll that is uninitialized otherwise.  Callbacks typically return bool so that that calling function knows when to stop calling it.  Besides that not every function ends up on the vtable.  The only functions that end up in the vtable are purely virtual.   Not every dll is a com object.   A com object is essentially a service that runs on your machine constantly and it's whole point is to field queries to produce objects that have reference counters in them so that the service knows when a particular object is free and can be cleaned up.  It's alot more complicated than that but that's the gist of it. 

 

Edited by markyrocks
Link to comment
Share on other sites

Have you verified that your callback object is working properly before you start replacing the vtable functions? Ie. that the original Microsoft code works in a 1-1 AutoIt translation.

Link to comment
Share on other sites

@markyrocks it is nice exercise at least.

@LarsJ I did have trouble with one method from vtable, others method I have not tested. The method I had trouble was DrawTextLayout from ID2D1RenderTarget. Definition says 

void DrawTextLayout(
       D2D1_POINT_2F          origin,
  [in] IDWriteTextLayout      *textLayout,
  [in] ID2D1Brush             *defaultFillBrush,
       D2D1_DRAW_TEXT_OPTIONS options
);

Based on the post I had to change AutoIt's definition to 

"DrawTextLayout none(float;float;struct*;struct*;uint);" & _;DrawTextLayout none(struct;struct*;struct*;uint);"- This is original
...
;Following would be new callbacek then
Local $hRenderer_DrawTextLayout_New = DllCallbackRegister("DrawTextLayout", "none", "ptr;float;float;ptr;ptr;uint")

Right now I had to change DrawGlyphRun and DrawUnderline definition and I am able to access structures

Global Const $tagIDWriteTextRenderer = $tagIDWritePixelSnapping & _
        "DrawGlyphRun hresult(struct*;float;float;uint;ptr;ptr;struct*);" & _;DrawGlyphRun hresult(struct*;float;float;uint;struct*;struct*;struct*)_-ORIGINAL
        "DrawUnderline hresult(struct*;float;float;ptr;struct*);" & _;DrawUnderline hresult(struct*;float;float;struct*;struct*)-ORIGINAL
        "DrawStrikethrough hresult(struct*;float;float;struct*;struct*);" & _
        "DrawInlineObject hresult(struct*;float;float;struct*;bool;bool;struct*);"

I have tried to access objects used in those callbacks using ObjCreateInterface. It did create objects, but I have not done anything with them yet, but it looks promising.

Link to comment
Share on other sites

To access the structure create a struct tag that is the same as the struct your receiving and create the new struct at the pointer that you receive and you should be able to view the underlying data.  i.e DllStructCreate("relevant tag", pointer)  creating a struct in this method doesn't alter the underlying data.

Link to comment
Share on other sites

That is how I am doing it now. initial issue was that I was getting 0 as the pointer. Cause of that issue was in the definition of DrawUnderline which was

"DrawUnderline hresult(struct*;float;float;struct*;struct*)"

 After replacing that with following I am able to use DllStructCreate successfully.

"DrawUnderline hresult(struct*;float;float;ptr;struct*);";there is ptr at fourth pos instead struct*

As it seems struct* does work for objects, but I need to do more tests.

Edited by ahmet
Link to comment
Share on other sites

@LarsJ since I have been having issues while trying to create objects from pointers from callback I went back I checked how does original Draw code works when called from AutoIt. Definition says

HRESULT Draw(
  void                *clientDrawingContext,
  IDWriteTextRenderer *renderer,
  FLOAT               originX,
  FLOAT               originY
);

VTable entry from AutoIt is " Draw hresult(struct*;struct*;float;float); ". I tried changng it to " Draw hresult(ptr;ptr;float;float); but I could not see any difference. My code for registering callback is

$hLayoutDrawCallback_New = DllCallbackRegister("Draw", "long", "ptr;ptr;ptr;float;float")

Two floats I get as expected. I can not create CliendDrawingContext and Renderer object. I tried to create Renderer object with following code

Func Draw($pSelf, $pClientDrawingContext, $pRenderer, $fOriginX, $fOriginY)
    ConsoleWrite("Draw called" & @CRLF)
    ConsoleWrite("x=" & $fOriginX & ",y=" & $fOriginY & @CRLF)
    ConsoleWrite("$pClientDrawingContext=" & $pClientDrawingContext & @CRLF)
    ConsoleWrite("$pRenderer=" & $pRenderer & @CRLF)
    
    ;$oRenderer=ObjCreateInterface($pRenderer,$sIID_IDWriteTextRenderer,$tagIDWriteTextRenderer);attempt to create renderer object
    
    ;$pTextLayout_Draw_Original - address to original Draw method
    $aResult = DllCallAddress("long", $pTextLayout_Draw_Original, "ptr", $pSelf, "ptr", $pClientDrawingContext, "ptr", $pRenderer, "float", $fOriginX, "float", $fOriginY)
 EndFunc

When I call original Draw code from my callback then the text gets drawn as expected. Pointer to $pClientDrawingContext shows 0 at the console. Am I creating object correctly?

Link to comment
Share on other sites

I'll take a closer look, but I cannot promise a quick answer, because I don't have much time for AutoIt programming at the moment.

Link to comment
Share on other sites

I did some more tests. Now I subclassed DrawRectangle from ID2D1HwndRenderTarget. I was able to access brush methods there. Methods are being called via DllCallAddress.

Addresses are obtained using technique from ReplaceVTableFuncPtr. I was able to get and set brush opacity using this method. One question remains regarding this. Is there some other way of obtaining object from pointer inside callback? If try to use ObjCreateInterface then the script crashes with STATUS_ACCESS_VIOLATION.

Func DrawRectangle($pSelf, $fLeft, $fTop, $fRight, $fBottom, $pBrush, $fWidth, $pStyle)
    ConsoleWrite("Draw rectangle caught" & @CRLF)
;~  ConsoleWrite("Left=" & $fLeft & @CRLF)
;~  ConsoleWrite("Top=" & $fTop & @CRLF)
;~  ConsoleWrite("Right=" & $fRight & @CRLF)
;~  ConsoleWrite("Bottom=" & $fBottom & @CRLF)
;~  ConsoleWrite("Width=" & $fWidth & @CRLF)
;~  ConsoleWrite("style=" & $pStyle & @CRLF)
;~  ConsoleWrite("brush=" & $pBrush & @CRLF)

    ;$tagID2D1SolidColorBrush=
    ;"GetFactory none(ptr*)"
    ;"SetOpacity none(float);" & _2nd
    ;"SetTransform none(struct*);" & _
    ;"GetOpacity float();" & _4th
    ;"GetTransform none(struct*);"
    ;"SetColor none(struct*);" & _
    ;"GetColor ptr(struct*);"
    $ptest=DllStructCreate("ptr", $pBrush)
;~  ConsoleWrite("$pZeroPointer=" & DllStructGetData($ptest, 1)+0*4 & @CRLF)

    $firstPointer=DllStructGetData($ptest,1)
    Local $pPointers=DllStructCreate("ptr[10]",$firstPointer);get pointers to method addresses
    If @error Then MsgBox(0,"DllStructCreate 3 error",@error)
    ;print all pointers to console
    For $i=1 To 10
        $pointer=DllStructGetData($pPointers,1,$i);
        ;$pointer2=DllStructGetData(DllStructCreate("ptr", $pointer), 1)
        ConsoleWrite($i & "=" & $pointer & @CRLF)
    Next

    ;get current opcity
    $pGetOpacity=DllStructGetData($pPointers,1,7);4+3 from IUnknown
    $aRet=DllCallAddress("float",$pGetOpacity,"ptr",$pBrush)
    If @error Then
        MsgBox(0,"DllCallAddress 2 error",@error)
    Else
        MsgBox(0,"Opacity",$aRet[0])
    EndIf

    ;set new opacity value
    Local $pSetOpacity = DllStructGetData($pPointers,1,5);2+3 from IUnknown
    ConsoleWrite("$pSetOpacity=" & $pSetOpacity & @CRLF)
    $aRet=DllCallAddress("none",$pSetOpacity,"ptr",$pBrush,"float",1);SetOpacity
    If @error Then MsgBox(0,"Error",@error)

    ;get current opacity value
    $aRet=DllCallAddress("float",$pGetOpacity,"ptr",$pBrush)
    MsgBox(0,"New opacity",$aRet[0])

;~  $oTest=ObjCreateInterface($pBrush,$sIID_ID2D1SolidColorBrush,$tagID2D1SolidColorBrush)
;~  MsgBox(0,"","Done")
    DllCallAddress("none",$pDrawRectangle_Old,"ptr",$pSelf,"float",$fLeft,"float",$fTop,"float",$fRight,"float",$fBottom,"ptr[10]",$pBrush,"float",$fWidth,"ptr",$pStyle)
EndFunc

I was not able to access render object inside Draw callback from above post using this technique. I will try to find some other method that has two pointers to objects as consecutive parameters and try with that.

_DWrite_Drawrectangle_Subclass.au3 Direct2DConstants.au3

Edited by ahmet
Added attacments
Link to comment
Share on other sites

I have made some helper functions regarding getting vTable pointers.

;returns pointers to all vTable entries
Func ObjGetVTablePointers($pVTable, $sdTagDescription, ByRef $aMethods, ByRef $tMethods)
    $tBasePointer = DllStructCreate("ptr", $pVTable)
    $pBasePointer = DllStructGetData($tBasePointer, 1)
    $aMethods=Split_dTag($sdTagDescription)
    $iNumOfMethods=UBound($aMethods)
    $tMethods = DllStructCreate("ptr[" & $iNumOfMethods & "]", $pBasePointer)
EndFunc   ;==>ObjGetVTablePointers

;searches for position of specific vTable entry at the vTable pointers
Func dTagGetIndex($adTag,$sMethodName)
    $iPos=_ArraySearch($adTag,$sMethodName)
    If @error Then
        MsgBox(0,"ArraySearch error",@error)
    Else
        Return $iPos+1
    EndIf
EndFunc

Func Split_dTag($sdTag)
;~  ConsoleWrite("Split tag" & @CRLF)
    $aSplit = StringSplit($sdTag, ");", BitOR(1, 2))
    $iNumOfElements = UBound($aSplit)
    If $aSplit[$iNumOfElements - 1] = "" Then _ArrayDelete($aSplit, $iNumOfElements - 1)
    For $i = 0 To UBound($aSplit) - 1
        $aSplit[$i] = StringRegExpReplace($aSplit[$i], " .+", "")
    Next
    Local $aResult[UBound($aSplit)+3]=["QueryInterface","AddRef","Release"];add IUnknown
    For $i=3 To UBound($aResult)-1
        $aResult[$i]=$aSplit[$i-3]
    Next
    Return $aResult
EndFunc   ;==>Split_dTag

What I did not mention in the last post is that in order for the original DrawRctangle code to work I had to make a following code

DllCallAddress("none",$pDrawRectangle_Old,"ptr",$pSelf,"float",$fLeft,"float",$fTop,"float",$fRight,"float",$fBottom,"ptr[10]",$pBrush,"float",$fWidth,"ptr",$pStyle);ptr[10] is because $tagID2D1SolidColorBrush has 10 entries including 3 from IUnknown interface

;follwing line crashes the script
;DllCallAddress("none",$pDrawRectangle_Old,"ptr",$pSelf,"float",$fLeft,"float",$fTop,"float",$fRight,"float",$fBottom,"ptr",$pBrush,"float",$fWidth,"ptr",$pStyle)

When specifying $pBrush I had to use "ptr[10]" insetad of "ptr".

Now to the Draw method of IDWriteTextLayout (second script). I am attaching script that I am using for testing. Functions of interest are: DrawMyRenderer_DrawGlyphRun and MyRenderer_DrawUnderline. Firstly the Draw method is subclassed and then from there the subclass procedure should continue with new Renderer which is created by ObjectFromTag function. When the original renderer is used then the script finishes fine. Same is for my custom renderer if I do not process its QueryInterface as shown here. If I process QueryInterface then the script crashes, which is probably of wrong pointers.

If I do nothing inside QueryInterface then $pClientDrawingContext inside Draw function shows as zero, while inside custom renderer which is called by Draw function $pClientDrawingContext shows as other value. Here is also console output. It appears that it shows correct values for everything except for objects. I tried manually following coordinates from DrawGlyphRun once the text is drawn and they are good.

Draw called
x=20,y=40
$pClientDrawingContext=0x00000000
$pRenderer=0x05270140
1=0x6BD7EE10
2=0x6BDA4450
3=0x6BD75DA0
4=0x6BD7C660
5=0x6BD7C6E0
6=0x6BD7C790
7=0x6BE8E2B0
8=0x6BE8E5A0
9=0x6BE8E350
10=0x6BE8E300
Getting transformation matrix of original renderer
    Type(expecting pointer)=String
MyRenderer_QueryInterface()

    $sIID={D3E0E934-22A0-427E-AAE4-7D9574B59DB1}
MyRenderer_IsPixelSnappingEnabled()

MyRenderer_GetPixelsPerDip()

MyRenderer_GetCurrentTransform()

MyRenderer_DrawGlyphRun()

    $pClientDrawingContext=0x03A317A8
    x:20, y:73.767578125
    $pClientDrawingEffect=0x0100E990
    $pGlyphRun=0x0100E970
    StringLen=9
    type of $tStrigPtr is Ptr
    value of String is 0x052780E8
    Tag=struct;wchar Text[9];endstruct
    FontEmSize:36
    Text=One line 
Num of methods:92
MyRenderer_DrawGlyphRun()

    $pClientDrawingContext=0x03A317A8
    x:164.087890625, y:73.767578125
    $pClientDrawingEffect=0x0100E990
    $pGlyphRun=0x0100E970
    StringLen=1
    type of $tStrigPtr is Ptr
    value of String is 0x052780FA
    Tag=struct;wchar Text[1];endstruct
    FontEmSize:36
    Text=m
Num of methods:92
MyRenderer_DrawGlyphRun()

    $pClientDrawingContext=0x03A317A8
    x:194.076171875, y:73.767578125
    $pClientDrawingEffect=0x0100E990
    $pGlyphRun=0x0100E970
    StringLen=5
    type of $tStrigPtr is Ptr
    value of String is 0x052780FC
    Tag=struct;wchar Text[5];endstruct
    FontEmSize:20
    Text=ore t
Num of methods:92
MyRenderer_DrawGlyphRun()

    $pClientDrawingContext=0x03A317A8
    x:237.416015625, y:73.767578125
    $pClientDrawingEffect=0x0100E990
    $pGlyphRun=0x0100E970
    StringLen=3
    type of $tStrigPtr is Ptr
    value of String is 0x05278106
    Tag=struct;wchar Text[3];endstruct
    FontEmSize:36
    Text=ext
Num of methods:92
MyRenderer_DrawGlyphRun()

    $pClientDrawingContext=0x03A317A8
    x:289.447265625, y:73.767578125
    $pClientDrawingEffect=0x0100E990
    $pGlyphRun=0x0100E970
    StringLen=1
    type of $tStrigPtr is Ptr
    value of String is 0x0527810C
    Tag=struct;wchar Text[1];endstruct
    FontEmSize:36
    Text= 
Num of methods:92
MyRenderer_DrawGlyphRun()

    $pClientDrawingContext=0x03A317A8
    x:20, y:115.1640625
    $pClientDrawingEffect=0x0100E990
    $pGlyphRun=0x0100E970
    StringLen=5
    type of $tStrigPtr is Ptr
    value of String is 0x0527810E
    Tag=struct;wchar Text[5];endstruct
    FontEmSize:36
    Text=even 
Num of methods:92
MyRenderer_DrawGlyphRun()

    $pClientDrawingContext=0x03A317A8
    x:112.056640625, y:115.1640625
    $pClientDrawingEffect=0x0100E990
    $pGlyphRun=0x0100E970
    StringLen=4
    type of $tStrigPtr is Ptr
    value of String is 0x05278118
    Tag=struct;wchar Text[4];endstruct
    FontEmSize:36
    Text=more
Num of methods:92
MyRenderer_DrawUnderline()

    $pClientDrawingContext=0x03A317A8
    x=164.087890625, y=73.767578125
    $pUnderline=0x0100E918
    width=125.359375
    $pClientDrawingEffect=0x0100E918
MyRenderer_DrawUnderline()

    $pClientDrawingContext=0x03A317A8
    x=20, y=115.1640625
    $pUnderline=0x0100E918
    width=92.056640625
    $pClientDrawingEffect=0x0100E918

 

 

_DWrite_Drawrectangle_Subclass_v2.au3 _DWrite_IDWriteTextRenderer_v2.au3

Link to comment
Share on other sites

I managed to create and use successfully Brush object in DrawRectangle method above using ObjectCreateInterface. In my previous attempt I failed because I have not been using AddRef. Now the code inside subclass is following 

Func DrawRectangle($pSelf, $pRect, $pBrush, $fWidth, $pStyle)
    ConsoleWrite("Draw rectangle caught" & @CRLF)
;~  ConsoleWrite("Left=" & $fLeft & @CRLF)
;~  ConsoleWrite("Top=" & $fTop & @CRLF)
;~  ConsoleWrite("Right=" & $fRight & @CRLF)
;~  ConsoleWrite("Bottom=" & $fBottom & @CRLF)
    ConsoleWrite("$pSelf=" & $pSelf & @CRLF)
    ConsoleWrite("Width=" & $fWidth & @CRLF)
    ConsoleWrite("style=" & $pStyle & @CRLF)
    ConsoleWrite("brush=" & $pBrush & @CRLF)
    ConsoleWrite("VarGetType($pRect)=" & VarGetType($pRect) & @CRLF)
    $tRect=DllStructCreate($tagD2D1_RECT_F,$pRect)
    ConsoleWrite("Left=" & $tRect.Left & @CRLF)
    ConsoleWrite("Top=" & $tRect.Top & @CRLF)
    ConsoleWrite("Right=" & $tRect.Right & @CRLF)
    ConsoleWrite("Bottom=" & $tRect.Bottom & @CRLF)


    $oTest=ObjCreateInterface($pBrush,$sIID_ID2D1SolidColorBrush,$tagID2D1SolidColorBrush)
    $oTest.AddRef()
    $oTest.SetColor(_D2D1_COLOR_F(1,1,0))

    $oTest2=ObjCreateInterface($pSelf,$sIID_ID2D1HwndRenderTarget,$tagID2D1HwndRenderTarget)
    $oTest2.AddRef()
    $hWnd=HWnd($oTest2.GetHWnd())
    MsgBox(0,$hGui,WinGetTitle($hWnd))
    DllCallAddress("none",$pDrawRectangle_Old,"ptr",$pSelf,"ptr",$pRect,"ptr", $pBrush, "float", $fWidth, "ptr", $pStyle)
    $oTest=0
    $oTest2=0
    ;follwing line crashes the script
    ;DllCallAddress("none",$pDrawRectangle_Old,"ptr",$pSelf,"float",$fLeft,"float",$fTop,"float",$fRight,"float",$fBottom,"ptr",$pBrush,"float",$fWidth,"ptr",$pStyle)
EndFunc   ;==>DrawRectangle

Also I reverted definition of DrawRectangle to its original form and now I am able to use it successfully. I really do not know what I did wrong earlier.

Global Const $tagID2D1RenderTarget = $tagID2D1Resource & _
        "CreateBitmap hresult(struct;struct*;uint;struct*;ptr*);" & _
        "CreateBitmapFromWicBitmap hresult(struct*;struct*;ptr*);" & _
        "CreateSharedBitmap hresult(struct*;struct*;struct*;ptr*);" & _
        "CreateBitmapBrush hresult(struct*;struct*;struct*;ptr*);" & _
        "CreateSolidColorBrush hresult(struct*;struct*;ptr*);" & _
        "CreateGradientStopCollection hresult(struct*;uint;uint;uint;ptr*);" & _
        "CreateLinearGradientBrush hresult(struct*;struct*;struct*;ptr*);" & _
        "CreateRadialGradientBrush hresult(struct*;struct*;struct*;ptr*);" & _
        "CreateCompatibleRenderTarget hresult(struct*;struct*;struct*;uint;ptr*);" & _
        "CreateLayer hresult(struct*;ptr*);" & _
        "CreateMesh hresult(ptr*);" & _
        "DrawLine none(struct;struct;struct*;float;struct*);" & _
        "DrawRectangle none(struct*;struct*;float;struct*);" & _;;DrawRectangle none(float;float;float;float;struct*;float;struct*)
        "FillRectangle none(struct*;struct*);" & _

 

_DWrite_Drawrectangle_Subclass.au3

Link to comment
Share on other sites

I managed to solve issues that I was having with the Draw method of IDWriteTextLayout. I was subclassing it instead of calling that method directly with custom text renderer as parameter. Here is an example call.

$oRender.BeginDraw()
_D2D_RenderTarget_Clear($oRender, 1, 0.9, 0.9)
$tPoint=_D2D1_POINT_2F(20,40)
$oDW_Layout.Draw($pMyContext,$oMyRenderer,20,40);>>>Here the Draw method is called, and only bounding rectangle are drawn for now
$oRender.DrawTextLayout(20,40, $oDW_Layout, $oBrush, 2);now draw text
$oRender.EndDraw(0, 0)

$oDW_Layout.Draw() does processing using custom text renderer and I can now use something for clientDrawingContext. I had to change definition of Draw in $tagIDWriteTextLayout.

Draw hresult(ptr;struct*;float;float);" & _;Draw hresult(struct*;struct*;float;float)-original

Here is an image of the output

image.png.8c27cd86ae838e952a5493dfb1ea2db3.png

I am attaching my test script and modified DirectWriteConstants.au3.

_DWrite_IDWriteTextRenderer.au3 DirectWriteConstants.au3

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...