Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/gfx/skia/skia/src/core/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 11 kB image not shown  

Quelle  SkMask.h   Sprache: C

 
/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#ifndef SkMask_DEFINED
#define SkMask_DEFINED

#include "include/core/SkColorPriv.h"
#include "include/core/SkRect.h"
#include "include/private/SkColorData.h"
#include "include/private/base/SkAssert.h"
#include "include/private/base/SkTemplates.h"

#include <cstddef>
#include <cstdint>
#include <memory>

/** \class SkMask
    SkMask is used to describe alpha bitmaps, either 1bit, 8bit, or
    the 3-channel 3D format. These are passed to SkMaskFilter objects.
*/

struct SkMask {
    enum Format : uint8_t {
        kBW_Format, //!< 1bit per pixel mask (e.g. monochrome)
        kA8_Format, //!< 8bits per pixel mask (e.g. antialiasing)
        k3D_Format, //!< 3 8bit per pixl planes: alpha, mul, add
        kARGB32_Format,         //!< SkPMColor
        kLCD16_Format,          //!< 565 alpha for r/g/b
        kSDF_Format,            //!< 8bits representing signed distance field
    };

    enum {
        kCountMaskFormats = kSDF_Format + 1
    };

    SkMask(const uint8_t* img, const SkIRect& bounds, uint32_t rowBytes, Format format)
        : fImage(img), fBounds(bounds), fRowBytes(rowBytes), fFormat(format) {}
    uint8_t const * const fImage;
    const SkIRect fBounds;
    const uint32_t fRowBytes;
    const Format fFormat;

    static bool IsValidFormat(uint8_t format) { return format < kCountMaskFormats; }

    /** Returns true if the mask is empty: i.e. it has an empty bounds.
     */

    bool isEmpty() const { return fBounds.isEmpty(); }

    /** Return the byte size of the mask, assuming only 1 plane.
        Does not account for k3D_Format. For that, use computeTotalImageSize().
        If there is an overflow of 32bits, then returns 0.
    */

    size_t computeImageSize() const;

    /** Return the byte size of the mask, taking into account
        any extra planes (e.g. k3D_Format).
        If there is an overflow of 32bits, then returns 0.
    */

    size_t computeTotalImageSize() const;

    /** Returns the address of the byte that holds the specified bit.
        Asserts that the mask is kBW_Format, and that x,y are in range.
        x,y are in the same coordiate space as fBounds.
    */

    const uint8_t* getAddr1(int x, int y) const {
        SkASSERT(kBW_Format == fFormat);
        SkASSERT(fBounds.contains(x, y));
        SkASSERT(fImage != nullptr);
        return fImage + ((x - fBounds.fLeft) >> 3) + (y - fBounds.fTop) * fRowBytes;
    }

    /** Returns the address of the specified byte.
        Asserts that the mask is kA8_Format, and that x,y are in range.
        x,y are in the same coordiate space as fBounds.
    */

    const uint8_t* getAddr8(int x, int y) const {
        SkASSERT(kA8_Format == fFormat || kSDF_Format == fFormat);
        SkASSERT(fBounds.contains(x, y));
        SkASSERT(fImage != nullptr);
        return fImage + x - fBounds.fLeft + (y - fBounds.fTop) * fRowBytes;
    }

    /**
     *  Return the address of the specified 16bit mask. In the debug build,
     *  this asserts that the mask's format is kLCD16_Format, and that (x,y)
     *  are contained in the mask's fBounds.
     */

    const uint16_t* getAddrLCD16(int x, int y) const {
        SkASSERT(kLCD16_Format == fFormat);
        SkASSERT(fBounds.contains(x, y));
        SkASSERT(fImage != nullptr);
        const uint16_t* row = (const uint16_t*)(fImage + (y - fBounds.fTop) * fRowBytes);
        return row + (x - fBounds.fLeft);
    }

    /**
     *  Return the address of the specified 32bit mask. In the debug build,
     *  this asserts that the mask's format is 32bits, and that (x,y)
     *  are contained in the mask's fBounds.
     */

    const uint32_t* getAddr32(int x, int y) const {
        SkASSERT(kARGB32_Format == fFormat);
        SkASSERT(fBounds.contains(x, y));
        SkASSERT(fImage != nullptr);
        const uint32_t* row = (const uint32_t*)(fImage + (y - fBounds.fTop) * fRowBytes);
        return row + (x - fBounds.fLeft);
    }

    /**
     *  Returns the address of the specified pixel, computing the pixel-size
     *  at runtime based on the mask format. This will be slightly slower than
     *  using one of the routines where the format is implied by the name
     *  e.g. getAddr8 or getAddr32.
     *
     *  x,y must be contained by the mask's bounds (this is asserted in the
     *  debug build, but not checked in the release build.)
     *
     *  This should not be called with kBW_Format, as it will give unspecified
     *  results (and assert in the debug build).
     */

    const void* getAddr(int x, int y) const;

    /** Iterates over the coverage values along a scanline in a given SkMask::Format. Provides
     *  constructor, copy constructor for creating
     *  operator++, operator-- for iterating over the coverage values on a scanline
     *  operator>>= to add row bytes
     *  operator* to get the coverage value at the current location
     *  operator< to compare two iterators
     */

    template <Format F> struct AlphaIter;
};

template <> struct SkMask::AlphaIter<SkMask::kBW_Format> {
    AlphaIter(const uint8_t* ptr, int offset) : fPtr(ptr), fOffset(7 - offset) {}
    AlphaIter(const AlphaIter& that) : fPtr(that.fPtr), fOffset(that.fOffset) {}
    AlphaIter& operator++() {
        if (0 < fOffset ) {
            --fOffset;
        } else {
            ++fPtr;
            fOffset = 7;
        }
        return *this;
    }
    AlphaIter& operator--() {
        if (fOffset < 7) {
            ++fOffset;
        } else {
            --fPtr;
            fOffset = 0;
        }
        return *this;
    }
    AlphaIter& operator>>=(uint32_t rb) {
        fPtr = SkTAddOffset<const uint8_t>(fPtr, rb);
        return *this;
    }
    uint8_t operator*() const { return ((*fPtr) >> fOffset) & 1 ? 0xFF : 0; }
    bool operator<(const AlphaIter& that) const {
        return fPtr < that.fPtr || (fPtr == that.fPtr && fOffset > that.fOffset);
    }
    const uint8_t* fPtr;
    int fOffset;
};

template <> struct SkMask::AlphaIter<SkMask::kA8_Format> {
    AlphaIter(const uint8_t* ptr) : fPtr(ptr) {}
    AlphaIter(const AlphaIter& that) : fPtr(that.fPtr) {}
    AlphaIter& operator++() { ++fPtr; return *this; }
    AlphaIter& operator--() { --fPtr; return *this; }
    AlphaIter& operator>>=(uint32_t rb) {
        fPtr = SkTAddOffset<const uint8_t>(fPtr, rb);
        return *this;
    }
    uint8_t operator*() const { return *fPtr; }
    bool operator<(const AlphaIter& that) const { return fPtr < that.fPtr; }
    const uint8_t* fPtr;
};

template <> struct SkMask::AlphaIter<SkMask::kARGB32_Format> {
    AlphaIter(const uint32_t* ptr) : fPtr(ptr) {}
    AlphaIter(const AlphaIter& that) : fPtr(that.fPtr) {}
    AlphaIter& operator++() { ++fPtr; return *this; }
    AlphaIter& operator--() { --fPtr; return *this; }
    AlphaIter& operator>>=(uint32_t rb) {
        fPtr = SkTAddOffset<const uint32_t>(fPtr, rb);
        return *this;
    }
    uint8_t operator*() const { return SkGetPackedA32(*fPtr); }
    bool operator<(const AlphaIter& that) const { return fPtr < that.fPtr; }
    const uint32_t* fPtr;
};

template <> struct SkMask::AlphaIter<SkMask::kLCD16_Format> {
    AlphaIter(const uint16_t* ptr) : fPtr(ptr) {}
    AlphaIter(const AlphaIter& that) : fPtr(that.fPtr) {}
    AlphaIter& operator++() { ++fPtr; return *this; }
    AlphaIter& operator--() { --fPtr; return *this; }
    AlphaIter& operator>>=(uint32_t rb) {
        fPtr = SkTAddOffset<const uint16_t>(fPtr, rb);
        return *this;
    }
    uint8_t operator*() const {
        unsigned packed = *fPtr;
        unsigned r = SkPacked16ToR32(packed);
        unsigned g = SkPacked16ToG32(packed);
        unsigned b = SkPacked16ToB32(packed);
        return (r + g + b) / 3;
    }
    bool operator<(const AlphaIter& that) const { return fPtr < that.fPtr; }
    const uint16_t* fPtr;
};

///////////////////////////////////////////////////////////////////////////////

struct SkMaskBuilder : public SkMask {
    SkMaskBuilder() : SkMask(nullptr, {0}, 0, SkMask::Format::kBW_Format) {}
    SkMaskBuilder(const SkMaskBuilder&) = delete;
    SkMaskBuilder(SkMaskBuilder&&) = default;
    SkMaskBuilder& operator=(const SkMaskBuilder&) = delete;
    SkMaskBuilder& operator=(SkMaskBuilder&& that) {
        this->image() = that.image();
        this->bounds() = that.bounds();
        this->rowBytes() = that.rowBytes();
        this->format() = that.format();
        that.image() = nullptr;
        return *this;
    }

    SkMaskBuilder(uint8_t* img, const SkIRect& bounds, uint32_t rowBytes, Format format)
        : SkMask(img, bounds, rowBytes, format) {}

    uint8_t*& image() { return *const_cast<uint8_t**>(&fImage); }
    SkIRect& bounds() { return *const_cast<SkIRect*>(&fBounds); }
    uint32_t& rowBytes() { return *const_cast<uint32_t*>(&fRowBytes); }
    Format& format() { return *const_cast<Format*>(&fFormat); }

    /** Returns the address of the byte that holds the specified bit.
        Asserts that the mask is kBW_Format, and that x,y are in range.
        x,y are in the same coordiate space as fBounds.
    */

    uint8_t* getAddr1(int x, int y) {
        return const_cast<uint8_t*>(this->SkMask::getAddr1(x, y));
    }

    /** Returns the address of the specified byte.
        Asserts that the mask is kA8_Format, and that x,y are in range.
        x,y are in the same coordiate space as fBounds.
    */

    uint8_t* getAddr8(int x, int y) {
        return const_cast<uint8_t*>(this->SkMask::getAddr8(x, y));
    }

    /**
     *  Return the address of the specified 16bit mask. In the debug build,
     *  this asserts that the mask's format is kLCD16_Format, and that (x,y)
     *  are contained in the mask's fBounds.
     */

    uint16_t* getAddrLCD16(int x, int y) {
        return const_cast<uint16_t*>(this->SkMask::getAddrLCD16(x, y));
    }

    /**
     *  Return the address of the specified 32bit mask. In the debug build,
     *  this asserts that the mask's format is 32bits, and that (x,y)
     *  are contained in the mask's fBounds.
     */

    uint32_t* getAddr32(int x, int y) {
        return const_cast<uint32_t*>(this->SkMask::getAddr32(x, y));
    }

    /**
     *  Returns the address of the specified pixel, computing the pixel-size
     *  at runtime based on the mask format. This will be slightly slower than
     *  using one of the routines where the format is implied by the name
     *  e.g. getAddr8 or getAddr32.
     *
     *  x,y must be contained by the mask's bounds (this is asserted in the
     *  debug build, but not checked in the release build.)
     *
     *  This should not be called with kBW_Format, as it will give unspecified
     *  results (and assert in the debug build).
     */

    void* getAddr(int x, int y) {
        return const_cast<void*>(this->SkMask::getAddr(x, y));
    }

    enum AllocType {
        kUninit_Alloc,
        kZeroInit_Alloc,
    };
    static uint8_t* AllocImage(size_t bytes, AllocType = kUninit_Alloc);
    static void FreeImage(void* image);

    enum CreateMode {
        kJustComputeBounds_CreateMode,      //!< compute bounds and return
        kJustRenderImage_CreateMode,        //!< render into preallocate mask
        kComputeBoundsAndRenderImage_CreateMode  //!< compute bounds, alloc image and render into it
    };

    /**
     *  Returns initial destination mask data padded by radiusX and radiusY
     */

    static SkMaskBuilder PrepareDestination(int radiusX, int radiusY, const SkMask& src);
};

/**
 *  \using SkAutoMaskImage
 *
 *  Stack class used to manage the fImage buffer in a SkMask.
 *  When this object loses scope, the buffer is freed with SkMask::FreeImage().
 */

using SkAutoMaskFreeImage = std::unique_ptr<uint8_t, SkFunctionObject<SkMaskBuilder::FreeImage>>;

#endif

Messung V0.5
C=94 H=95 G=94

¤ Dauer der Verarbeitung: 0.31 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.