tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

BufferEdgePad.cpp (3508B)


      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 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;
     29    }
     30 
     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");
     35      }
     36      if (src < bitmap) {
     37        MOZ_CRASH("GFX: short src memcpy");
     38      }
     39      if (dst + n > bitmap + stride * height) {
     40        MOZ_CRASH("GFX: long dst mempcy");
     41      }
     42      if (dst < bitmap) {
     43        MOZ_CRASH("GFX: short dst mempcy");
     44      }
     45    }
     46 
     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;
     55 
     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);
     65        }
     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);
     75        }
     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++;
     82          }
     83        }
     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++;
     90          }
     91        }
     92      }
     93    }
     94  } lb;
     95 
     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);
    100  }
    101 }
    102 
    103 }  // namespace gfx
    104 }  // namespace mozilla