Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/2d/BufferEdgePad.cpp
Line
Count
Source (jump to first uncovered line)
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/. */
6
7
#include "BufferEdgePad.h"
8
9
#include "2D.h" // for DrawTarget
10
#include "Point.h" // for IntSize
11
#include "Types.h" // for SurfaceFormat
12
13
#include "nsRegion.h"
14
15
namespace mozilla {
16
namespace gfx {
17
18
void
19
PadDrawTargetOutFromRegion(DrawTarget* aDrawTarget, const nsIntRegion &aRegion)
20
{
21
  struct LockedBits {
22
    uint8_t *data;
23
    IntSize size;
24
    int32_t stride;
25
    SurfaceFormat format;
26
    static int clamp(int x, int min, int max)
27
0
    {
28
0
      if (x < min)
29
0
        x = min;
30
0
      if (x > max)
31
0
        x = max;
32
0
      return x;
33
0
    }
34
35
    static void ensure_memcpy(uint8_t *dst, uint8_t *src, size_t n, uint8_t *bitmap, int stride, int height)
36
0
    {
37
0
        if (src + n > bitmap + stride*height) {
38
0
            MOZ_CRASH("GFX: long src memcpy");
39
0
        }
40
0
        if (src < bitmap) {
41
0
            MOZ_CRASH("GFX: short src memcpy");
42
0
        }
43
0
        if (dst + n > bitmap + stride*height) {
44
0
            MOZ_CRASH("GFX: long dst mempcy");
45
0
        }
46
0
        if (dst < bitmap) {
47
0
            MOZ_CRASH("GFX: short dst mempcy");
48
0
        }
49
0
    }
50
51
0
    static void visitor(void *closure, VisitSide side, int x1, int y1, int x2, int y2) {
52
0
      LockedBits *lb = static_cast<LockedBits*>(closure);
53
0
      uint8_t *bitmap = lb->data;
54
0
      const int bpp = gfx::BytesPerPixel(lb->format);
55
0
      const int stride = lb->stride;
56
0
      const int width = lb->size.width;
57
0
      const int height = lb->size.height;
58
0
59
0
      if (side == VisitSide::TOP) {
60
0
        if (y1 > 0) {
61
0
          x1 = clamp(x1, 0, width - 1);
62
0
          x2 = clamp(x2, 0, width - 1);
63
0
          ensure_memcpy(&bitmap[x1*bpp + (y1-1) * stride], &bitmap[x1*bpp + y1 * stride], (x2 - x1) * bpp, bitmap, stride, height);
64
0
          memcpy(&bitmap[x1*bpp + (y1-1) * stride], &bitmap[x1*bpp + y1 * stride], (x2 - x1) * bpp);
65
0
        }
66
0
      } else if (side == VisitSide::BOTTOM) {
67
0
        if (y1 < height) {
68
0
          x1 = clamp(x1, 0, width - 1);
69
0
          x2 = clamp(x2, 0, width - 1);
70
0
          ensure_memcpy(&bitmap[x1*bpp + y1 * stride], &bitmap[x1*bpp + (y1-1) * stride], (x2 - x1) * bpp, bitmap, stride, height);
71
0
          memcpy(&bitmap[x1*bpp + y1 * stride], &bitmap[x1*bpp + (y1-1) * stride], (x2 - x1) * bpp);
72
0
        }
73
0
      } else if (side == VisitSide::LEFT) {
74
0
        if (x1 > 0) {
75
0
          while (y1 != y2) {
76
0
            memcpy(&bitmap[(x1-1)*bpp + y1 * stride], &bitmap[x1*bpp + y1*stride], bpp);
77
0
            y1++;
78
0
          }
79
0
        }
80
0
      } else if (side == VisitSide::RIGHT) {
81
0
        if (x1 < width) {
82
0
          while (y1 != y2) {
83
0
            memcpy(&bitmap[x1*bpp + y1 * stride], &bitmap[(x1-1)*bpp + y1*stride], bpp);
84
0
            y1++;
85
0
          }
86
0
        }
87
0
      }
88
0
89
0
    }
90
  } lb;
91
92
  if (aDrawTarget->LockBits(&lb.data, &lb.size, &lb.stride, &lb.format)) {
93
    // we can only pad software targets so if we can't lock the bits don't pad
94
    aRegion.VisitEdges(lb.visitor, &lb);
95
    aDrawTarget->ReleaseBits(lb.data);
96
  }
97
}
98
99
} // namespace gfx
100
} // namespace mozilla