1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "BufferEdgePad.h"
9 #include "2D.h" // for DrawTarget
10 #include "Point.h" // for IntSize
11 #include "Types.h" // for SurfaceFormat
18 void PadDrawTargetOutFromRegion(DrawTarget
* aDrawTarget
,
19 const nsIntRegion
& aRegion
) {
25 static int clamp(int x
, int min
, int max
) {
31 static void ensure_memcpy(uint8_t* dst
, uint8_t* src
, size_t n
,
32 uint8_t* bitmap
, int stride
, int height
) {
33 if (src
+ n
> bitmap
+ stride
* height
) {
34 MOZ_CRASH("GFX: long src memcpy");
37 MOZ_CRASH("GFX: short src memcpy");
39 if (dst
+ n
> bitmap
+ stride
* height
) {
40 MOZ_CRASH("GFX: long dst mempcy");
43 MOZ_CRASH("GFX: short dst mempcy");
47 static void visitor(void* closure
, VisitSide side
, int x1
, int y1
, int x2
,
49 LockedBits
* lb
= static_cast<LockedBits
*>(closure
);
50 uint8_t* bitmap
= lb
->data
;
51 const int bpp
= gfx::BytesPerPixel(lb
->format
);
52 const int stride
= lb
->stride
;
53 const int width
= lb
->size
.width
;
54 const int height
= lb
->size
.height
;
56 if (side
== VisitSide::TOP
) {
58 x1
= clamp(x1
, 0, width
- 1);
59 x2
= clamp(x2
, 0, width
- 1);
60 ensure_memcpy(&bitmap
[x1
* bpp
+ (y1
- 1) * stride
],
61 &bitmap
[x1
* bpp
+ y1
* stride
], (x2
- x1
) * bpp
,
62 bitmap
, stride
, height
);
63 memcpy(&bitmap
[x1
* bpp
+ (y1
- 1) * stride
],
64 &bitmap
[x1
* bpp
+ y1
* stride
], (x2
- x1
) * bpp
);
66 } else if (side
== VisitSide::BOTTOM
) {
68 x1
= clamp(x1
, 0, width
- 1);
69 x2
= clamp(x2
, 0, width
- 1);
70 ensure_memcpy(&bitmap
[x1
* bpp
+ y1
* stride
],
71 &bitmap
[x1
* bpp
+ (y1
- 1) * stride
], (x2
- x1
) * bpp
,
72 bitmap
, stride
, height
);
73 memcpy(&bitmap
[x1
* bpp
+ y1
* stride
],
74 &bitmap
[x1
* bpp
+ (y1
- 1) * stride
], (x2
- x1
) * bpp
);
76 } else if (side
== VisitSide::LEFT
) {
79 memcpy(&bitmap
[(x1
- 1) * bpp
+ y1
* stride
],
80 &bitmap
[x1
* bpp
+ y1
* stride
], bpp
);
84 } else if (side
== VisitSide::RIGHT
) {
87 memcpy(&bitmap
[x1
* bpp
+ y1
* stride
],
88 &bitmap
[(x1
- 1) * bpp
+ y1
* stride
], bpp
);
96 if (aDrawTarget
->LockBits(&lb
.data
, &lb
.size
, &lb
.stride
, &lb
.format
)) {
97 // we can only pad software targets so if we can't lock the bits don't pad
98 aRegion
.VisitEdges(lb
.visitor
, &lb
);
99 aDrawTarget
->ReleaseBits(lb
.data
);
104 } // namespace mozilla