hkoba / tkhtml3

Tkhtml3 repository -- (mostly manual) clone from http://tkhtml.tcl.tk/fossil
http://tkhtml.tcl.tk
GNU Lesser General Public License v2.1
1 stars 1 forks source link

How are the X and Y axes of CanvasOrigin items set? #6

Open Zamy846692 opened 3 months ago

Zamy846692 commented 3 months ago

I have been studying the TkHTML 3 layout engine and the parts were the Canvas Items are actually drawn to the Canvas. However in doing so I have been unable to find out how the X and Y coordinates for the CanvasOrigin item are actually set. HtmlDrawOrigin does not have any code that sets them, and I have been unable to find any instance of those variables beings set (to anything other than zero), even though the CanvasOrigin struct does have them as members and the _primitives command does output them as having x and y set to numbers other than zero.

I am aware that the variable *pY seems to control the CanvasOrigin Y axis - but I am unsure of how it does that?

I have been trying to make some modifications to TkHTML's systems and need some clarification on this.

hkoba commented 2 months ago

Hi.

I'm not the original author of tkhtml3. That said, I guess what you are looking for is here:

https://github.com/hkoba/tkhtml3/blob/ae2e673a6abcb5c82d5b4fd426cb310993ede4c8/src/htmldraw.c#L896-L904

The struct CanvasOrigin shares the same member layout with the struct GenericItem. This is a well-known coding trick in C.

Zamy846692 commented 2 months ago

Yeah, I can confirm that that is how the CanvasOrigin struct X and Y values are set/modified, but I am still unsure which of HtmlDrawCanvas's function calls is the one that actually sets the values for CanvasOrigin, e.g. how the variable *pY actually becomes the CanvasOrigin Y-axis.

Been trying to find it for a while now with not much luck. I think it might look something like this: movePrimitivesHtmlDrawCanvasHtmlInlineContextGetLineBoxinlineLayoutDrawLinesnormalFlowLayoutNodelayoutChildrennormalFlowLayout

hkoba commented 2 months ago

Are you familiar with gdb (or any other debuggers)? If so, I recommend you to do:

  1. Insert some printf() to htmldraw.c:movePrimitives(). After line 899 seems best.
  2. Start the debugger, set breakpoint to the above printf() and run the target program.
  3. When you reach to the breakpoint, just get the backtrace. (In gdb, hit bt).
Zamy846692 commented 2 months ago

Ok I am using gdb from MSYS2 (I'm totally new to gdb) and got this, Am I doing it right? I am using this as a tutorial.

C:\Users\[USER]>gdb tclsh
GNU gdb (GDB) 13.2
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-w64-mingw32".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from tclsh...
(No debugging symbols found in tclsh)
(gdb) run C:\Users\[USER]\src\tkinterweb\tkinterweb\tkhtml\Windows\64-bit\Tkhtml30.dll
Starting program: C:\msys64\mingw64\bin\tclsh.exe C:\Users\[USER]\src\tkinterweb\tkinterweb\tkhtml\Windows\64-bit\Tkhtml30.dll
[New Thread 91912.0x16760]
[New Thread 91912.0xb98c]
[New Thread 91912.0x16e38]
invalid command name "MZ ♥   ♦   ÿÿ  ¸       @                                   €   ♫▼º♫ ´"
    while executing
"MZ ♥   ♦   ÿÿ  ¸       @                                   €   ♫▼º♫ ´ Í!¸☺LÍ!This p..."
    (file "C:\Users\[USER]\src\tkinterweb\tkinterweb\tkhtml\Windows\64-bit\Tkhtml30.dll" line 1)
[Thread 91912.0x16e38 exited with code 1]
[Thread 91912.0xb98c exited with code 1]
[Thread 91912.0x16760 exited with code 1]
[Inferior 1 (process 91912) exited with code 01]
(gdb)
hkoba commented 2 months ago

Hi.

Am I doing it right?

No. What you did wrong was the argument of run command.

In gdb tclsh.exe, the run command takes exactly same arguments as tclsh. So, you must do

  1. Write a toy tcl script to use Tkhtml as usual (say, myTclScript.tcl)
    package require Tkhtml
    pack [html .ht] -fill both -expand yes
    .ht parse -final {
     <h2>Hello</h2>
    }

    or

    package require Tkhtml
    pack [html .ht] -fill both -expand yes
    pack [text .t -height 5] -fill x -expand no
    pack [button .b -text parse -command {
     .ht parse [.t get 1.0 end-1c]
    }] -fill x -expand no
  2. Start gdb.
    gdb tclsh
  3. Set breakpoints
    (gdb) b HtmlDrawCanvas
    Function "HtmlDrawCanvas" not defined.
    Make breakpoint pending on future shared library load? (y or [n]) y
    Breakpoint 1 (HtmlDrawCanvas) pending.
  4. Start the script
    (gdb) run myTclScript.tcl

Note: in step3, probably you cannot set the breakpoint to movePrimitives because it is a static (not visible) function.

Hope this helps.

Zamy846692 commented 2 months ago

Ok I have been able to find the HtmlDrawCanvas function calls that are the ones that actually sets the values for CanvasOrigin, they are at found at: https://github.com/hkoba/tkhtml3/blob/buildable/src/htmllayout.c#L2748C5-L2748C71 and https://github.com/hkoba/tkhtml3/blob/buildable/src/htmllayout.c#L2754. The variable *pY is most likely controlled here: https://github.com/hkoba/tkhtml3/blob/buildable/src/htmllayout.c#L1469; here: https://github.com/hkoba/tkhtml3/blob/buildable/src/htmllayout.c#L1501 and here: https://github.com/hkoba/tkhtml3/blob/buildable/src/htmllayout.c#L1519.

Question about gdb breakpoints: gdb with tclsh runs just fine, but the break command doesn't seem to do anything, I can't see any differences between when I run it with them and when I run it without (I'm using a .gbd file to store the commands): With:

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from tclsh.exe...
(No debugging symbols found in tclsh.exe)
Function "HtmlDrawCanvas" not defined.
Breakpoint 1 (HtmlDrawCanvas) pending.
[New Thread 58428.0xe264]
[New Thread 58428.0x9380]
[New Thread 58428.0xe124]
C:/Users/billa/AppData/Local/Packages/PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0/LocalCache/local-packages/Python39/site-packages/tkinterweb/tkhtml/Windows/64-bit
[New Thread 58428.0x9e6c]
normalFlowLayoutBlock
A = 0, 0
normalFlowLayoutBlock
A = 0, 0
normalFlowLayoutBlock
A = 0, 0
HtmlDrawCanvas 00000000005fead0 00000000007f6f70 2 0 00000000006a8a80 movePrimitives
A: 1; X=0+2; Y=19+0 B: 1; X=2; Y=19
HtmlDrawCanvas 00000000005febe0 00000000005feab0 0 0 0000000000000000 movePrimitives
HtmlDrawCanvas 00000000005febe0 00000000005fead0 0 0 0000000000000000 movePrimitives
HtmlDrawCanvas 00000000005fefb0 00000000005febe0 0 18 0000000000000000 movePrimitives
A: 2; X=2+0; Y=-1+18 B: 2; X=2; Y=17 A: 1; X=2+0; Y=19+18 B: 1; X=2; Y=37
etc...

Without:

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from tclsh.exe...
(No debugging symbols found in tclsh.exe)
[New Thread 27228.0xe318]
[New Thread 27228.0xe6bc]
[New Thread 27228.0x9a74]
C:/Users/billa/AppData/Local/Packages/PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0/LocalCache/local-packages/Python39/site-packages/tkinterweb/tkhtml/Windows/64-bit
[New Thread 27228.0x2300]
normalFlowLayoutBlock
A = 0, 0
normalFlowLayoutBlock
A = 0, 0
normalFlowLayoutBlock
A = 0, 0
HtmlDrawCanvas 00000000005fead0 00000000007b6f70 2 0 00000000008d8a80 movePrimitives
A: 1; X=0+2; Y=19+0 B: 1; X=2; Y=19
HtmlDrawCanvas 00000000005febe0 00000000005feab0 0 0 0000000000000000 movePrimitives
HtmlDrawCanvas 00000000005febe0 00000000005fead0 0 0 0000000000000000 movePrimitives
HtmlDrawCanvas 00000000005fefb0 00000000005febe0 0 18 0000000000000000 movePrimitives
A: 2; X=2+0; Y=-1+18 B: 2; X=2; Y=17 A: 1; X=2+0; Y=19+18 B: 1; X=2; Y=37
etc...

The file:

set breakpoint pending on
b HtmlDrawCanvas
run TkHTMLscript.tcl

Many thanks!

hkoba commented 1 month ago

Hi.

Thank you for sharing your findings on CanvasOrigin with me.

As for your question about gdb breakpoints, I guess your Tkhtml30.dll does not contain the debug info.

If your DLL has the correct debug info, you can set breakpoints. Here is a captured gdb session on my environment (Fedora Linux):

vladilena(pts/3)% gdb -x gdbinit =tclsh
GNU gdb (Fedora Linux) 14.2-3.fc40
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /usr/bin/tclsh...

This GDB supports auto-downloading debuginfo from the following URLs:
  <https://debuginfod.fedoraproject.org/>
Enable debuginfod for this session? (y or [n]) y
Debuginfod has been enabled.
To make this setting permanent, add 'set debuginfod enabled on' to .gdbinit.
Downloading separate debug info for /usr/bin/tclsh8.6
--Type <RET> for more, q to quit, c to continue without paging--c                                                                   
Reading symbols from /home/hkoba/.cache/debuginfod_client/9c2fdc10cdc0bd0b061b2bc426828a5b7c71d26c/debuginfo...
Downloading separate debug info for /home/hkoba/.cache/debuginfod_client/9c2fdc10cdc0bd0b061b2bc426828a5b7c71d26c/debuginfo
Function "HtmlDrawCanvas" not defined.                                                                                              
Breakpoint 1 (HtmlDrawCanvas) pending.
Downloading separate debug info for system-supplied DSO at 0x7ffff7fc6000
Downloading separate debug info for /lib64/libtcl8.6.so                                                                             
Downloading separate debug info for /lib64/libc.so.6                                                                                
[Thread debugging using libthread_db enabled]                                                                                       
Using host libthread_db library "/lib64/libthread_db.so.1".
Downloading separate debug info for /lib64/libz.so.1
Downloading separate debug info for /home/hkoba/.cache/debuginfod_client/eb9f981a3516a0ddf50d98ddbab5fca0b8ac6e5e/debuginfo         
Downloading separate debug info for /lib64/libm.so.6                                                                                
Downloading separate debug info for /lib64/libX11.so.6                                                                              
Downloading separate debug info for /lib64/libxcb.so.1                                                                              
Downloading separate debug info for /lib64/libXau.so.6                                                                              
Downloading separate debug info for /usr/lib64/libtk8.6.so                                                                          
Downloading separate debug info for /lib64/libXft.so.2                                                                              
Downloading separate debug info for /lib64/libfontconfig.so.1                                                                       
Downloading separate debug info for /lib64/libfreetype.so.6                                                                         
Downloading separate debug info for /home/hkoba/.cache/debuginfod_client/eb5a1744ecedfa2f46a171303e0742b323f929d1/debuginfo         
Downloading separate debug info for /lib64/libXrender.so.1                                                                          
Downloading separate debug info for /lib64/libxml2.so.2                                                                             
Downloading separate debug info for /home/hkoba/.cache/debuginfod_client/9a04dd211dcbbbee58634c2d78766a207d94b8e8/debuginfo         
Downloading separate debug info for /lib64/libbz2.so.1                                                                              
Downloading separate debug info for /home/hkoba/.cache/debuginfod_client/fd3b9ae54c1ab3619ed14823f9c5e0c0e3b52b99/debuginfo         
Downloading separate debug info for /lib64/libpng16.so.16                                                                           
Downloading separate debug info for /lib64/libharfbuzz.so.0                                                                         
Downloading separate debug info for /home/hkoba/.cache/debuginfod_client/6f577b55055e61105d0adceca0af6a375a61dea3/debuginfo         
Downloading separate debug info for /lib64/libbrotlidec.so.1                                                                        
Downloading separate debug info for /home/hkoba/.cache/debuginfod_client/c670b19a84c8816f949f3b6365e6f081ea639110/debuginfo         
Downloading separate debug info for /lib64/liblzma.so.5                                                                             
Downloading separate debug info for /lib64/libglib-2.0.so.0                                                                         
Downloading separate debug info for /home/hkoba/.cache/debuginfod_client/36b60dbd02e796145a982d0151ce37202ec05649/debuginfo         
Downloading separate debug info for /lib64/libgraphite2.so.3                                                                        
Downloading separate debug info for /lib64/libbrotlicommon.so.1                                                                     
Downloading separate debug info for /lib64/libpcre2-8.so.0                                                                          
Downloading separate debug info for /home/hkoba/.cache/debuginfod_client/c4e99ea26e680e02a91b7ae05044bb378dacfc86/debuginfo         
[New Thread 0x7ffff6e006c0 (LWP 351558)]                                                                                            

Thread 1 "tclsh" hit Breakpoint 1, HtmlDrawCanvas (pCanvas=0x7fffffffc770, pCanvas2=0x5555558a1be0, x=0, y=0, pNode=0x5555558acd10)
    at ./src/htmldraw.c:1040
1040    {
(gdb) bt
#0  HtmlDrawCanvas (pCanvas=0x7fffffffc770, pCanvas2=0x5555558a1be0, x=0, y=0, pNode=0x5555558acd10) at ./src/htmldraw.c:1040
#1  0x00007ffff7a2dfc0 in HtmlInlineContextGetLineBox (pLayout=0x7fffffffd310, p=<optimized out>, flags=<optimized out>, 
    pWidth=<optimized out>, pCanvas=0x7fffffffc880, pVSpace=0x7fffffffc878, pAscent=0x7fffffffc87c) at ./src/htmlinline.c:1341
#2  0x00007ffff7a4ebca in inlineLayoutDrawLines.isra.0 (pLayout=0x7fffffffd310, pBox=0x7fffffffcb10, pContext=0x5555558ad790, 
    forceflag=1, pY=0x7fffffffc970, pNormal=0x7fffffffd2d0) at ./src/htmllayout.c:1494
#3  0x00007ffff7a2f051 in normalFlowLayout (pLayout=pLayout@entry=0x7fffffffd310, pBox=pBox@entry=0x7fffffffcb10, 
    pNode=pNode@entry=0x555555776740, pNormal=pNormal@entry=0x7fffffffd2d0) at ./src/htmllayout.c:3597
#4  0x00007ffff7a335f8 in normalFlowLayoutBlock (pLayout=0x7fffffffd310, pBox=0x7fffffffce90, pNode=0x555555776740, 
    pY=0x7fffffffccf0, pContext=<optimized out>, pNormal=0x7fffffffd2d0) at ./src/htmllayout.c:2704
#5  0x00007ffff7a2e578 in normalFlowLayoutNode (pLayout=pLayout@entry=0x7fffffffd310, pBox=pBox@entry=0x7fffffffce90, 
    pNode=0x555555776740, pY=pY@entry=0x7fffffffccf0, pContext=pContext@entry=0x5555558ad710, pNormal=pNormal@entry=0x7fffffffd2d0)
    at ./src/htmllayout.c:3284
#6  0x00007ffff7a2ebc2 in layoutChildren (pLayout=pLayout@entry=0x7fffffffd310, pBox=pBox@entry=0x7fffffffce90, 
    pNode=pNode@entry=0x555555776640, pY=pY@entry=0x7fffffffccf0, pContext=pContext@entry=0x5555558ad710, 
    pNormal=pNormal@entry=0x7fffffffd2d0) at ./src/htmllayout.c:2922
#7  0x00007ffff7a2f025 in normalFlowLayout (pLayout=pLayout@entry=0x7fffffffd310, pBox=pBox@entry=0x7fffffffce90, 
    pNode=pNode@entry=0x555555776640, pNormal=pNormal@entry=0x7fffffffd2d0) at ./src/htmllayout.c:3592
#8  0x00007ffff7a335f8 in normalFlowLayoutBlock (pLayout=0x7fffffffd310, pBox=0x7fffffffd210, pNode=0x555555776640, 
    pY=0x7fffffffd070, pContext=<optimized out>, pNormal=0x7fffffffd2d0) at ./src/htmllayout.c:2704
#9  0x00007ffff7a2e578 in normalFlowLayoutNode (pLayout=pLayout@entry=0x7fffffffd310, pBox=pBox@entry=0x7fffffffd210, 
    pNode=0x555555776640, pY=pY@entry=0x7fffffffd070, pContext=pContext@entry=0x5555558ad690, pNormal=pNormal@entry=0x7fffffffd2d0)
    at ./src/htmllayout.c:3284
#10 0x00007ffff7a2ebc2 in layoutChildren (pLayout=pLayout@entry=0x7fffffffd310, pBox=pBox@entry=0x7fffffffd210, 
--Type <RET> for more, q to quit, c to continue without paging--c
    pNode=pNode@entry=0x555555776440, pY=pY@entry=0x7fffffffd070, pContext=pContext@entry=0x5555558ad690, 
    pNormal=pNormal@entry=0x7fffffffd2d0) at ./src/htmllayout.c:2922
#11 0x00007ffff7a2f025 in normalFlowLayout (pLayout=pLayout@entry=0x7fffffffd310, pBox=pBox@entry=0x7fffffffd210, 
    pNode=pNode@entry=0x555555776440, pNormal=pNormal@entry=0x7fffffffd2d0) at ./src/htmllayout.c:3592
#12 0x00007ffff7a335f8 in normalFlowLayoutBlock (pLayout=0x7fffffffd310, pBox=0x7fffffffd340, pNode=0x555555776440, 
    pY=0x7fffffffd2bc, pContext=<optimized out>, pNormal=0x7fffffffd2d0) at ./src/htmllayout.c:2704
#13 0x00007ffff7a38083 in HtmlLayout (pTree=0x55555575fbd0) at ./src/htmllayout.c:4009
#14 0x00007ffff7a45668 in runLayoutEngine (clientData=0x55555575fbd0) at ./src/htmltcl.c:455
#15 callbackHandler (clientData=0x55555575fbd0) at ./src/htmltcl.c:558
#16 0x00007ffff7f08cbe in TclServiceIdle () at /usr/src/debug/tcl-8.6.13-2.fc40.x86_64/generic/tclTimer.c:751
#17 0x00007ffff7ee4faa in Tcl_DoOneEvent (flags=<optimized out>) at /usr/src/debug/tcl-8.6.13-2.fc40.x86_64/generic/tclNotify.c:980
#18 0x00007ffff77843dc in MapFrame (clientData=0x5555557520c0)
    at /usr/src/debug/tk-8.6.13-3.fc40.x86_64/unix/../generic/tkFrame.c:1794
#19 0x00007ffff7f08cbe in TclServiceIdle () at /usr/src/debug/tcl-8.6.13-2.fc40.x86_64/generic/tclTimer.c:751
#20 0x00007ffff7ee50a2 in Tcl_DoOneEvent (flags=<optimized out>) at /usr/src/debug/tcl-8.6.13-2.fc40.x86_64/generic/tclNotify.c:980
#21 0x00007ffff775b6f2 in Tk_MainLoop () at /usr/src/debug/tk-8.6.13-3.fc40.x86_64/unix/../generic/tkEvent.c:2109
#22 0x00007ffff7ee87d1 in Tcl_MainEx (argc=-1, argc@entry=2, argv=<optimized out>, argv@entry=0x7fffffffd868, 
    appInitProc=appInitProc@entry=0x555555555210 <Tcl_AppInit>, interp=0x555555567370)
    at /usr/src/debug/tcl-8.6.13-2.fc40.x86_64/generic/tclMain.c:590
#23 0x0000555555555119 in main (argc=2, argv=0x7fffffffd868) at /usr/src/debug/tcl-8.6.13-2.fc40.x86_64/unix/tclAppInit.c:91
(gdb) q
A debugging session is active.

    Inferior 1 [process 351552] will be killed.

Quit anyway? (y or n) y
vladilena(pts/3)%