Bug 1885602 - Part 4: Implement navigating to the settings from the menu header for...
[gecko.git] / gfx / 2d / BufferEdgePad.cpp
blob69f508f7886a9c377bfd836b6de84337292b8fea
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
13 #include "nsRegion.h"
15 namespace mozilla {
16 namespace gfx {
18 void PadDrawTargetOutFromRegion(DrawTarget* aDrawTarget,
19 const nsIntRegion& aRegion) {
20 struct LockedBits {
21 uint8_t* data;
22 IntSize size;
23 int32_t stride;
24 SurfaceFormat format;
25 static int clamp(int x, int min, int max) {
26 if (x < min) x = min;
27 if (x > max) x = max;
28 return x;
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");
36 if (src < bitmap) {
37 MOZ_CRASH("GFX: short src memcpy");
39 if (dst + n > bitmap + stride * height) {
40 MOZ_CRASH("GFX: long dst mempcy");
42 if (dst < bitmap) {
43 MOZ_CRASH("GFX: short dst mempcy");
47 static void visitor(void* closure, VisitSide side, int x1, int y1, int x2,
48 int y2) {
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) {
57 if (y1 > 0) {
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) {
67 if (y1 < height) {
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) {
77 if (x1 > 0) {
78 while (y1 != y2) {
79 memcpy(&bitmap[(x1 - 1) * bpp + y1 * stride],
80 &bitmap[x1 * bpp + y1 * stride], bpp);
81 y1++;
84 } else if (side == VisitSide::RIGHT) {
85 if (x1 < width) {
86 while (y1 != y2) {
87 memcpy(&bitmap[x1 * bpp + y1 * stride],
88 &bitmap[(x1 - 1) * bpp + y1 * stride], bpp);
89 y1++;
94 } lb;
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);
103 } // namespace gfx
104 } // namespace mozilla