From 55ef7ca5adaaf4cc8a75df3aa31d679f7780c581 Mon Sep 17 00:00:00 2001 From: Glenn Watson Date: Wed, 1 Oct 2014 08:54:24 +1000 Subject: [PATCH] Refactor background image, fix fixed attachment. Improve acid2. --- components/layout/fragment.rs | 130 +++++++++++++++------------------ tests/ref/acid2_ref_broken.png | Bin 1925 -> 2279 bytes 2 files changed, 60 insertions(+), 70 deletions(-) diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index b8006535eaa..59c256022bb 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -250,6 +250,18 @@ impl ImageFragmentInfo { Some(max_size) => Au::min(size, max_size), }) } + + /// Tile an image + pub fn tile_image(position: &mut Au, size: &mut Au, + virtual_position: Au, image_size: u32) { + let image_size = image_size as int; + let delta_pixels = geometry::to_px(virtual_position - *position); + let tile_count = (delta_pixels + image_size - 1) / image_size; + let offset = Au::from_px(image_size * tile_count); + let new_position = virtual_position - offset; + *size = *position - new_position + *size; + *position = new_position; + } } /// A fragment that represents an inline frame (iframe). This stores the pipeline ID so that the size @@ -762,78 +774,61 @@ impl Fragment { let image_width = Au::from_px(image.width as int); let image_height = Au::from_px(image.height as int); - - // Adjust bounds for `background-position` and `background-attachment`. let mut bounds = *absolute_bounds; + + // Add clip item. + // TODO: Check the bounds to see if a clip item is actually required. + let mut clip_display_item = box ClipDisplayItem { + base: BaseDisplayItem::new(bounds, self.node, level), + children: DisplayList::new(), + }; + + // Use background-attachment to get the initial virtual origin + let (virtual_origin_x, virtual_origin_y) = match background.background_attachment { + background_attachment::scroll => { + (absolute_bounds.origin.x, absolute_bounds.origin.y) + } + background_attachment::fixed => { + (Au(0), Au(0)) + } + }; + + // Use background-position to get the offset let horizontal_position = model::specified(background.background_position.horizontal, bounds.size.width - image_width); let vertical_position = model::specified(background.background_position.vertical, bounds.size.height - image_height); - // TODO: These are some situations below where it is possible - // to determine that clipping is not necessary - this is an - // optimization to make in the future. - let clip_display_item = Some(box ClipDisplayItem { - base: BaseDisplayItem::new(bounds, self.node, level), - children: DisplayList::new(), - }); + let abs_x = virtual_origin_x + horizontal_position; + let abs_y = virtual_origin_y + vertical_position; - match background.background_attachment { - background_attachment::scroll => { - bounds.origin.x = bounds.origin.x + horizontal_position; - bounds.origin.y = bounds.origin.y + vertical_position; - - // Adjust sizes for `background-repeat`. - match background.background_repeat { - background_repeat::no_repeat => { - bounds.size.width = Au::min(bounds.size.width - horizontal_position, image_width); - bounds.size.height = Au::min(bounds.size.height - vertical_position, image_height); - } - background_repeat::repeat_x => { - bounds.size.height = Au::min(bounds.size.height - vertical_position, image_height); - if horizontal_position != Au(0) { - bounds.size.width = bounds.size.width + image_width; - } - } - background_repeat::repeat_y => { - bounds.size.width = Au::min(bounds.size.width - horizontal_position, image_width); - if vertical_position != Au(0) { - bounds.size.height = bounds.size.height + image_height; - } - } - background_repeat::repeat => { - if horizontal_position != Au(0) { - bounds.size.width = bounds.size.width + image_width; - } - if vertical_position != Au(0) { - bounds.size.height = bounds.size.height + image_height; - } - } - }; + // Adjust origin and size based on background-repeat + match background.background_repeat { + background_repeat::no_repeat => { + bounds.origin.x = abs_x; + bounds.origin.y = abs_y; + bounds.size.width = image_width; + bounds.size.height = image_height; } - background_attachment::fixed => { - bounds = Rect { - origin: Point2D(horizontal_position, vertical_position), - size: Size2D(bounds.origin.x + bounds.size.width, - bounds.origin.y + bounds.size.height), - }; - - // Adjust sizes for `background-repeat`. - match background.background_repeat { - background_repeat::no_repeat => { - bounds.size.width = image_width; - bounds.size.height = image_height; - } - background_repeat::repeat_x => { - bounds.size.height = image_height; - } - background_repeat::repeat_y => { - bounds.size.width = image_width; - } - background_repeat::repeat => {} - }; + background_repeat::repeat_x => { + bounds.origin.y = abs_y; + bounds.size.height = image_height; + ImageFragmentInfo::tile_image(&mut bounds.origin.x, &mut bounds.size.width, + abs_x, image.width); } - } + background_repeat::repeat_y => { + bounds.origin.x = abs_x; + bounds.size.width = image_width; + ImageFragmentInfo::tile_image(&mut bounds.origin.y, &mut bounds.size.height, + abs_y, image.height); + } + background_repeat::repeat => { + ImageFragmentInfo::tile_image(&mut bounds.origin.x, &mut bounds.size.width, + abs_x, image.width); + ImageFragmentInfo::tile_image(&mut bounds.origin.y, &mut bounds.size.height, + abs_y, image.height); + } + }; // Create the image display item. let image_display_item = ImageDisplayItemClass(box ImageDisplayItem { @@ -843,13 +838,8 @@ impl Fragment { Au::from_px(image.height as int)), }); - match clip_display_item { - None => list.push(image_display_item), - Some(mut clip_display_item) => { - clip_display_item.children.push(image_display_item); - list.push(ClipDisplayItemClass(clip_display_item)) - } - } + clip_display_item.children.push(image_display_item); + list.push(ClipDisplayItemClass(clip_display_item)) } /// Adds the display items necessary to paint the borders of this fragment to a display list if diff --git a/tests/ref/acid2_ref_broken.png b/tests/ref/acid2_ref_broken.png index c8284fe8a2b067ed8846586cf09193c29ad83fa0..4076473cec3cbb7adf2b7d0ce275c7e62cd1496d 100644 GIT binary patch literal 2279 zcmaKuc{mhWAIB$47+DI_WKAObG9+~ogRI#nj2d)RNQf+Hh7rm#2r0X0=7x!EVN5~{ zN?DU_Y$LB_EE(Hq7da&gaD2TAT6#MS%bSfY02_ z*q-H!e;79#t7RxaW>}6Vz|18G0N@q+VFv)&xnKZ*JImbI&@pUuInUBcY)G=b=@>C0 z_z(>aLrqGBO#<;)A5exMQPugh`B?DLE87S*rIR0k($|iGQcD$6 zi;|_~;I4gRiTRSb=U~|%N3alZ z#p~F~i0Bq{`-S?;0fd0>S}!jpaBXdUn?KB?vqv)T4r^#@FQP`riC_uRlCt)hRI5ey zgra8O_D?zUEA3Oq^_lgX~*AGdb4k7U>Zo zNu|b-+|{Q(9=j9Ty4=px_nT<@rVax2j*XpBSD)GpUk>>VZFceqH;0^@+%D5Qh0Ey` zB~i^52E%NHZ!K-wA4_s}ZCz4kGQ}3OO7VUD_sh#?h&@AKx2tQ@>JfV)Q2@$qfS1oZ zQ>nt|?4=1(k!{M2F-20Riy5yx@tgMgGLA1QcUylR7kkT%S%7<6K=&$y3Z~TW$J19KIh> zpr5opcY8(r<8_4_n?3o`U}NQj0RJ~pwc262>N#s)c`le%R-mOK>KE5{Y94Q`x7#?h zxJGp%G$^ampNhx;Q`1Ak^NA)`B^PX%Hj7I-x&;{6Kkyb_nAFSpy#|j`=O{% z6syYCvQ23Y&F$^&IXE~}R}W}v(l-X6oZT8Qm!JnL}O%dagnOEYGg>nfg5yw?y5M~O3gcnsK{1=sgjv@;+NJ`nI%ulwkJ&)>z z>Nh|+Q1qve`uEp^6fDDVy1zNWIEfNa1Maq~4>NW~;qt%}shuqv_UX8V;!v+Dt+Qp_ z(Ukb2XSKCx?;x9NS|>mQbwhq?_M{SV(iyFJ+=wGE`$3)rs%l^qSbZ$Yz<|5YWo~nn zm>kaasu5q^trWw}!FF8}?#i2~-QfszzrnggjuvXO+FG586W5J`G~sY}h;&xlVyWue zx}$u2nVFfrT4jw5Gig*BLA0l9Kcc)n=zTDuvB7AdCO$s?!NH9!kov9Ul9=X2#WeFw zD=%-up!Mn83+L7Vxz;tWTl`FQlX0?3%ZA(=8_$Sh5&IiozhX@)F9#rYzvuZQZ|Hkh zzRq+^H$VM)7|t5)u!5>OYH;B$mTdC;_;^x&KHG&)vKfNIW3By1D7S}~y>3PixKMaZ z<9oUX2MZe|-ecd=paZ>RjKd3coj8&S26Kow?pM&Wokd;mKDTN|>Pt=aNa2c(j@2{C zu~d|P=3N2r>qT#c)YLsMFaPXtF_qH=0t7_K2jyxD)cu-N4Oll1`_S$z%SbX8UC3Oi2YI>fRfyt?u85`HLb# z32K_Ojr0oPNVYOdDq{An>Wh1@Kx%)3llK+tZN;*#1q3em>^Q!L70>uGd*@YuL+%O; z{&b+xf*RN`XD(`9;<-j}vu;OY2wEO^FksOZoT@B@U< zHGw-3(Nx zYn9$NmE|i4Z24dp(qAec`}f9w!SY7{>np#g=IFUi1&WOJ-W?5LLODI0exmf>as?Jt zf9fdep!HT7EKxuH@z`1J|HI1QO_xTy{4W!hDl#@V|3&Ed#pZufx-cxTsMEDfA1}}~ zP_z?>-L7fXQSdtB!sM7wTtU!(uI_H#V3c+qy{;MU)oL8MnGx`|5Z)Ld2CVRn!?u z+ee(yJ`vuKxJ{`-8>?QM}l{4jn103dY3()`xR ze)(7PojREZiW>7L>vXWCYbXF9aOSTD0tyNx0RUda4Rez_xQX?mnV{P~l6^)MM0Z4A zsl*b0L?8<(dFv??o<@VK%gQqne-U_A&SA3qjS}6(!*R$tA9Bylh)3!c�+aQ2Ca> z|1tm!T#GkWbjJihr`cY5WnwQL?=~5%9~>=sz&}OML+KTRG0bb52gPo$AKngd!7oC<;j8XttUckahs1@5DYCAvW4)T)y9Df1Sx$+Nk+3UYZGA@8nR;|Vwk4J z3YAPge)Py(PVDDiQ<7-*fbZ~XmL^B?{YPl#GD|ss(hsoVacD#&u(?}-MjcWBm8*a{GtF4uidjq~ zXDC&GjWY~dRtT9N-K@akv5A&97iM3NF;xzdoVNa0?60sZie`UV7sw6TMo2jV;~$-c zgSIq&X0wg%E_a?+hk*Gy{3eI z7(DvWa>36~niBr$V_${c-4uk<_^7gG6>9HHUD3ec}wS zes124$f2X&#Tz|zb%IMMcX(d{scI?-OkfPOl7xh^BbhtC>1w8>Wz~)RHS|FNboT_d zjIc;(HdxUl3=GzWzcM9dub;i8WWMjvjL(040dO7E+hVNARanDVU1X^1`KjnFF4?HC z9xknToJ%Rps(6zVzvNVZfjCebXR#(2QQPvEj>eW$qTdxP*QaQ`(DU#@o{SVA8f?c%c4W&hL0=u8@c< zNZD2~@^QnQJ4PYQK1ODh$JMi>*|ncWQn2%BY|$x}1CwYBA^#Nd6b4E5J@7~kTfVxXq=ymG{8 z*4SaXy;=ZBAJ6jqE&N?Wj~z7CvblhN}vSxe_t2mFxBsLLy=TlQG0 z%ym+Nh1@&siz$B!n0m9txnOf290Zj%ZCzk)m#U`uOj_}Sp*S(ODY|hr=V?MCxMa6K zh{a_t>k>kj;F9H6n4R=rjNW$ux9Ns?`Wz;NLgHPpIm7PtanJOTL~yP%^e$-b`lX%# zR2$RS$Ctd7bqC^<%TD_t6y=#%7km%Vf7*ouTzpH|0HwJjKE@e;90-%i4%eLK^`5ro z09_HoKakpZ?hBR|_vTTA%QBsFMxv;B_iEcmMHmUUDe4K~6o1;2n8R&1Elf?RVvzwy zRmfG=-@cAHy=^j5jTmfmsP4=-kfIcO4i^K_Uclx1eLUCpJBNPrth}#T!odW7h!|*T zu!~ZE>lE|{IZn&+;{QPY4TpnXt|9KUx|Z12?S|ITr>En0guwp>e%`m}mq(3=W-tu% zotszOdV=nW{)W@u{ckROdoEbJj>*V0EQkqe63kknDbN2WJHCJZQqi!Q@lHP<`E2RP zX`AD(Vyx|XWu7tegFu0_ld77d2a~>xCx@J5lhXflv1F11)8$<0k(wvD3b=9I*1Xmf Go%BycgOm>d