I have this problem when drawing rectangles; when i resize the window gaps appear between the rectangles.

http://wolfshade.home.ro/test.asm

assemble and slowly resize the window and you'll see the gaps
i'm sure i saw somewhere how to fix this but don't remember where
Posted on 2006-09-11 04:55:39 by w0lfshad3
Try something like this.
; child windows 1..4
  mov temp2, 4
                fild    cxClient
                fidiv  temp2                  ; cxClient / 4      ;;; shorter than (1/4 * cxClient)
  fistp temp2 ; temp2 = ST(0), FPU stack balanced

  mov temp3, 7
                fild    cyClient
                fidiv  temp3                  ; cyClient / 7
  fistp temp3 ; temp3 = ST(0), FPU stack balanced

  mov ecx, 4
  push esi
  xor esi, esi
  push edi
  xor edi, edi
label2::
  mov i, edi

                fild i
                fimul temp2
                fistp temp1

                mov    eax, cxClient     
                sub    eax, temp1   

  push ecx
  invoke MoveWindow, , temp1, 0, eax, temp3, TRUE
  inc edi
  add esi, 4
  pop ecx
  loop label2


It's essentially the same for all other child controls.
* I wasn't sure whether you wanted a double pixel or one pixel border.. I assumed the second.
Posted on 2006-09-11 15:19:32 by arafel
Thank you, care to tell me how i would fix it for 2 pixels width? Add 1 to temp1?

I read through

                mov eax, cxClient
                sub eax, temp1

and i would get in "sub eax, temp1" "cxClient - i*cxClient/4" wich will give me the following widths: cxClient/4, cxClient/2, 3*cxClient/4, cxClient, but i need a constant width because i will use each child window as a button or something later.

You'll notice with your code when hitting one of those child windows what happends.
Posted on 2006-09-12 01:03:26 by w0lfshad3

You'll notice with your code when hitting one of those child windows what happends.


Uuups. I haven't read all the sourcecode.

Ok, second try..

; child windows 1..4

mov temp2, 4
fld1 ; 1
fild temp2 ; 4, 1
fdivp ST(1), ST(0) ; 1/4
fild cxClient ; cxClient, (1/4)
fmulp ST(1), ST(0) ; cxClient * (1/4)
fistp temp2 ; temp2 = ST(0), FPU stack balanced

mov temp3, 7
fld1 ; 1
fild temp3 ; 7, 1
fdivp ST(1), ST(0) ; 1/7
fild cyClient ; cxClient, (1/7)
fmulp ST(1), ST(0) ; cxClient * (1/7)
fistp temp3 ; temp3 = ST(0), FPU stack balanced

mov ecx, 4
push esi
xor esi, esi
push edi
xor edi, edi
label2::

          mov  eax, temp2
          imul eax, edi
          mov  temp1, eax

          cmp  edi, 3      ; in case when window's width doesn't divide equally - set last child's width manually.
          jne  @f
          mov  eax,
          sub  eax, temp1
          mov  temp2, eax
@@:
  push ecx
  invoke MoveWindow, , temp1, 0, temp2, temp3, TRUE
  inc edi
  add esi, 4
  pop ecx
  loop label2

mov eax, temp2
mov temp4, eax ; cxClient * (1/4)
Posted on 2006-09-12 03:23:49 by arafel
Thank you, it works now,

I'm wondering tough, the C code i took an example of this doesn't produce gaps and it doesn't have any "helping code", is it because asm rounds up the value and C truncs? or vice-versa (did not check and forgot if i ever knew).

Care you briefly explain where to modify to get a 1 pixel width and how come 1
width in the row of rectangles made them all have gaps?

http://wolfshade.home.ro/checker3.c

*i will step later through the C assembly, perhaps i'll get an insight of why it is happening.
Posted on 2006-09-12 08:06:41 by w0lfshad3

I'm wondering tough, the C code i took an example of this doesn't produce gaps and it doesn't have any "helping code", is it because asm rounds up the value and C truncs? or vice-versa (did not check and forgot if i ever knew).

The link doesn't work.
So I don't know how C version differs from asm version. But the way the element's width is calculated (window_width/elements_count) in that assembly code it doesn't matter whether the value is rounded up or down.

e.g. take for example 607px wide window , divide by four and you will see that if you:
round up - last element's width will be 1 pixel shorter than others.
round down - and last lement's width will be 3 pixel wider than others. That is, it won't fit into the window entirely. (this is what the asm version does)

Now when you do "cxClient * (i/4)" the element's offset will be wrongly calculated, hence the gaps.

For example 3rd element offset will be: 607*(2/4) = 303 (it is rounded down in your code) and 4th will be : 607*(3/4)= 455.
But the previously calculated element width is 151. So 151*3= 453. 1 pixel gap between 3rd and 4th element!


Care you briefly explain where to modify to get a 1 pixel width and how come 1
width in the row of rectangles made them all have gaps?

Decrement the offset of all elements except the first one, and once again fix the width of last element since it will be shorter now.
I am not sure I understand second part of the question.
Posted on 2006-09-12 23:48:38 by arafel
Ok, link: wolfshade.home.ro/checker3.c or wolfshade.home.ro/checker3.zip
COPY&PASTE it in another browser window. I get a weird error when supplying C code in these forums. Besides that i can't even acces the ftp with my firewall on.

EDIT(wrong not sure if its accurate at all): Anyway after more calculations i observed no matter the number now the width is never less than offsets thus the child windows overlap eachother even without the helping code. What really is happening even with rectangles is that after the rectangle is drawn the rectangle is marked invalid thus redrawn and filled with the current brush i think.
My code was producing width logic shorter than the offset logic.

I'm missing something, the code produces 2 pixel borders thus no overlap occurs.

What i was asking is how fixing the 4th element width fixes the gaps or overlaps that happend between different elements on different cxClient values, for instance 605 wich produces an overlap between 2nd and 3rd element according to the round model(and appear as a 1 pixel width if i set a brush). An overlap would occur between 3rd and 4th again for the trunc model.

For now i checked on paper assuming round(0.5) == 1 and trunc(0.5) == 0. AFAIK trunc( 0.999...) == 0 as well to PCs or at least trunc( 0.9 ).

I run numbers(cxClient==607):

1st element: offset:0 width:151.75 thus round(151.75)==152

2nd element: offset:151.75 thus round(151.75)==152 width:152 element
0+152 = 152 1st element offset (1 pixel border)

3rd element: offset:303.5 thus round(303.5)=304 width:152
152+152 = 304 2nd element offset (1 pixel border)

4th element: offset: 455.25 thus round(455.25)==455 width:152
304+152 = 456 NOT 3rd element offset (+1 == 2 pixel border or overlap?) <==========

If they were all truncated this would've been the result:

1st offset:0 width:152


2nd offset:151 width: 152
0+152=152 NOT 2nd element offset (+1 == 2 pixel border or overlap?) <=========

3rd offset:303 width: 152
151+152=303(1 pixel border)

4th offset:455 width: 152
303+152=455(1 pixel border)

with rectangles:

Ok, link: wolfshade.home.ro/checker1.c or wolfshade.home.ro/checker1.zip
COPY&PASTE it in another browser window. I get a weird error when supplying C code in these forums. Besides that i can't even acces the ftp with my firewall on.
Posted on 2006-09-13 01:59:09 by w0lfshad3
Hmm. Neither the C version calculates last element width correctly. No gaps there though.  8)


What i was asking is how fixing the 4th element width fixes the gaps or overlaps that happend between different elements on different cxClient values,

It doesn't. It fixes only the last element width, so it won't be too short or too long. It has nothing to do with gaps.
What fixes the gaps or overlaps is the method of offset calculation.
(this code:
           mov  eax, temp2
           imul eax, edi
           mov  temp1, eax)
Which is identical to its C version equivalent now that I see it.


I think you are just overcomplicating things ;).
There is a window with particular width and a number of child elemnts which have single pixel border.
Want them placed simply one next to each other and thus produce a 'double' pixel border - multiply element width by its position index to get offset.
On other hand if one pixel border is required, just make every next element overlap it's previous neighbor by one pixel.
That's it, there isn't really any more than this.
Posted on 2006-09-13 06:18:06 by arafel
Thanks, too many variables in my head, i think its clear now.

I think you are just overcomplicating things .


:D It has to be perrrfect because its my precious  :D
Posted on 2006-09-13 07:02:27 by w0lfshad3