/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance"). // All rights reserved. // // This software and its documentation and related materials are owned by // the Alliance. The software may only be incorporated into application // programs owned by members of the Alliance, subject to a signed // Membership Agreement and Supplemental Software License Agreement with the // Alliance. The structure and organization of this software are the valuable // trade secrets of the Alliance and its suppliers. The software is also // protected by copyright law and international treaty provisions. Application // programs incorporating this software must include the following statement // with their copyright notices: // // This application incorporates Open Design Alliance software pursuant to a license // agreement with Open Design Alliance. // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance. // All rights reserved. // // By use of this software, its documentation or related materials, you // acknowledge and accept the above terms. /////////////////////////////////////////////////////////////////////////////// #ifndef ODEXGSBITMAPDEVICE_INCLUDED #define ODEXGSBITMAPDEVICE_INCLUDED #include "TD_PackPush.h" #include "Gs/GsBMPDevice.h" #include "Gs/GsBaseVectorizeDevice.h" #include "Gi/GiRasterImage.h" #include "UInt8Array.h" #include "RxDispatchImpl.h" /** This class encapsulates Device Independent Bitmap objects. Library: Source code provided. */ class GsDIBSection { public: /** \details Default constructor for the GsDIBSection class. */ GsDIBSection(); /** \details Destructor for the GsDIBSection class. */ virtual ~GsDIBSection(); /** \details Creates a DIB for this DIBSection object. \param xPixels [in] X pixels. \param yPixels [in] Y pixels. \param bitsPerPixel [in] Color depth. */ void createDib(int xPixels, int yPixels, int bitsPerPixel); /** \details Sets the DIB palette for this DIBSection object. \param hPalette [in] Handle of the palette. */ void setPalette(HPALETTE hPalette); /** \details Returns the size (in bytes) of the palette data of this DIBSection object. \returns Palette size in bytes. */ OdUInt32 paletteDataSize() const { return m_paletteData.size(); } /** \details Returns the DIB palette data of this DIBSection object. \param bytes [out] Receives the palette data. \remarks It is up to the caller to allocate sufficient memory for the palette data. */ void paletteData(OdUInt8* bytes) const { memcpy(bytes, m_paletteData.getPtr(), m_paletteData.size()); } /** \details Returns the specified color of the DIB palette of this DIBSection object. \param colorIndex [in] Color index in the palette. \returns ODCOLORREF value that represents color. */ ODCOLORREF color(OdUInt32 colorIndex) const { colorIndex *= 4; return ODRGBA( m_paletteData[colorIndex + 2], m_paletteData[colorIndex + 1], m_paletteData[colorIndex], m_paletteData[colorIndex + 3]); } /** \details Returns the scan line size of this DIBSection object. \returns Number of bytes between the beginning of scan line N and the beginning of scan line N+1 (taking into account any padding that is added to the end of the scan line). */ OdUInt32 scanLineSize() const; /** \details Returns the specified set of scanlines in BMP format from this RasterImage object, or the pixel data in BMP format for this RasterImage object. \param scnLines [out] Receives the scan line data. \param firstScanline [in] Index of first scanline to retrieve. \param numLines [in] Number of scanlines to retrieve. \remarks * The number of accessible scanlines is equal to value returned by pixelHeight(). * The number of accessible bytes in a scanline is equal to the value returned by scanLineSize(). * The scanline returned by firstScanline == 0 is the first scanline in the image. * The scanline returned by firstScanline == (pixelHeight() - 1) is the last scanline in the image. \remarks It us up to the caller to allocate sufficient memory for the scan line data. \remarks Implementation of this function with no arguments is optional; NULL can be returned if it is inconvenient to implement. The caller must take into account that the return value can be NULL. */ void scanLines(OdUInt8* scnLines, OdUInt32 firstScanline, OdUInt32 numLines = 1) const; /** \details Returns the specified set of scanlines in BMP format from this RasterImage object, or the pixel data in BMP format for this RasterImage object. \returns Pointer to the scan lines data. \remarks * The number of accessible scanlines is equal to value returned by pixelHeight(). * The number of accessible bytes in a scanline is equal to the value returned by scanLineSize(). * The scanline returned by firstScanline == 0 is the first scanline in the image. * The scanline returned by firstScanline == (pixelHeight() - 1) is the last scanline in the image. \remarks It us up to the caller to allocate sufficient memory for the scan line data. \remarks Implementation of this function with no arguments is optional; NULL can be returned if it is inconvenient to implement. The caller must take into account that the return value can be NULL. */ const OdUInt8* scanLines() const; /** \details Returns the handle to the device context for this DIBSection object. \returns Handle to the device context. */ HDC getHDC() const { return m_hdc; } /** \details Sets the device context for this DIBSection object. \param hDC [in] Handle to the device context. */ void setHDC(HDC hDC) { m_hdc = hDC; } /** \details Returns the image width in pixels of this DIBSection object. \returns Image width in pixels. */ OdUInt32 getDibWidth() const; /** \details Returns the image height in pixels of this DIBSection object. \returns Image height in pixels. */ OdUInt32 getDibHeight() const; /** \details Returns the color depth of this DIBSection object. \returns The "bits per pixel" value that represents color depth. */ int getBitsPerPixel() const; /** \details Computes transparency onto generated pixel data. \param pPixelData [in] Pointer to the pixel data. \param bkColor [in] Background color. */ void computeTransparency(const OdUInt8 *pPixelData, ODCOLORREF bkColor); void *m_pBits; OdUInt32 m_nSizeImage; protected: /** \details Destroys the DIB bitmap associated with this DIBSection object. */ void destroy(); protected: HBITMAP m_hbmp; HBITMAP m_hbmOld; HDC m_hdc; HPALETTE m_hPal; OdUInt8Array m_paletteData; }; /** Library: Source code provided. */ template class ExGsBitmapDevice : public OdGiRasterImage , public T { protected: /*using OdGiRasterImage::operator new; using OdGiRasterImage::operator delete;*/ /*ODRX_USING_HEAP_OPERATORS(OdGiRasterImage);*/ // 24.09.2004 GU // neither using nor ODRX_USING_HEAP_OPERATORS(OdGiRasterImage) // can't be compiled under Borland due to unknown reasons void* operator new(size_t s) { return OdGiRasterImage::operator new(s); } void operator delete(void* p) { OdGiRasterImage::operator delete(p); } void* operator new[](size_t s) { return OdGiRasterImage::operator new(s); } void operator delete[](void* p) { OdGiRasterImage::operator delete(p); } void *operator new(size_t s, void* p) { return OdGiRasterImage::operator new(s, p); } void *operator new[](size_t s, void* p) { return OdGiRasterImage::operator new(s, p); } /** \details Sets the number of bits per pixel used for colors by this BitmapDevice object. \param bitsPerPixel [in] Bits per pixel. */ void putBitPerPixel(OdUInt32 bitsPerPixel) { T::m_nColorDepth = bitsPerPixel; T::m_bColorIndexMode = (T::m_nColorDepth < 16); } public: /** \details Default constructor for the ExGsBitmapDevice class. */ ExGsBitmapDevice() { } /** \details Destructor for the ExGsBitmapDevice class. */ ~ExGsBitmapDevice() override { T::deleteContext(); } /** \details Checks whether the device supports partial updating. \returns true if the device supports partial updating, false otherwise. */ bool supportPartialUpdate() const { return OdGsBaseVectorizeDevice::supportPartialUpdate(); } /** \details Returns the color depth for this BitmapDevice object. \returns The "bits per pixel" value that represents the color depth. */ virtual int getDeviceColorDepth() const { return T::m_nColorDepth; } /** \details Returns the logical palette for this BitmapDevice object. \returns ODGSPALETTE that is an array of ODCOLORREF values. */ ODGSPALETTE getDevicePalette() { return T::m_logPalette; } /** \details Updates the specified rectangle of this BitmapDevice object. \param pUpdatedRect [in] Pointer to the rectangle to receive the region updated by this function. */ void update(OdGsDCRect* pUpdatedRect = 0) { const ODCOLORREF bkColor = T::getBackgroundColor(); const bool bTransparentBackground = (T::m_nColorDepth == 32) && (ODGETALPHA(bkColor) < 255); m_dibSection.createDib(T::width(), T::height(), T::m_nColorDepth); if (bTransparentBackground) T::setBackgroundColor(ODRGBA(255, 0, 255, 255)); T::update(pUpdatedRect); if (bTransparentBackground) { T::setBackgroundColor(ODRGBA(0, 255, 0, 255)); if (m_trpData.size() != (m_dibSection.getDibHeight() * m_dibSection.scanLineSize())) m_trpData.resize(m_dibSection.getDibHeight() * m_dibSection.scanLineSize()); ::memcpy(m_trpData.asArrayPtr(), m_dibSection.scanLines(), m_trpData.size()); T::update(pUpdatedRect); m_dibSection.computeTransparency(m_trpData.getPtr(), bkColor); T::setBackgroundColor(bkColor); } } /** \details Returns the width in pixels of the Device Independent Bitmap object. \returns Width in pixels. */ OdUInt32 pixelWidth() const override { return m_dibSection.getDibWidth(); } /** \details Returns the height in pixels of the DIBSection object. \returns Height in pixels. */ OdUInt32 pixelHeight() const override { return m_dibSection.getDibHeight(); } /** \details Retrieves the default image resolution in pixels per unit. \param xPelsPerUnit [out] Receives the pixels per unit value (x direction). \param yPelsPerUnit [out] Receives the pixels per unit value (y direction). \returns Units in which images are calculated. \remarks As implemented, this function does nothing and returns kNone. */ Units defaultResolution(double& xPelsPerUnit, double& yPelsPerUnit) const override { xPelsPerUnit = yPelsPerUnit = 0.0; return kNone; } /** \details Returns the scan line size of the DIBSection object. \returns Number of bytes between the beginning of scan line N and the beginning of scan line N+1 (taking into account any padding that is added to the end of the scan line). */ OdUInt32 scanLineSize() const override { return m_dibSection.scanLineSize(); } /** \details Returns the specified set of scanlines in BMP format from the DIBSection object, or the pixel data in BMP format for the DIBSection object. \param scnLines [out] Receives the scan line data. \param firstScanline [in] Index of first scanline to retrieve. \param numLines [in] Number of scanlines to retrieve. \remarks * The number of accessible scanlines is equal to value returned by pixelHeight(). * The number of accessible bytes in a scanline is equal to the value returned by scanLineSize(). * The scanline returned by firstScanline == 0 is the first scanline in the image. * The scanline returned by firstScanline == (pixelHeight() - 1) is the last scanline in the image. \note It us up to the caller to allocate sufficient memory for the scan line data. \note Implementation of this function with no arguments is optional; NULL can be returned if it is inconvenient to implement. The caller must take into account that the return value can be NULL. */ void scanLines(OdUInt8* pBytes, OdUInt32 index, OdUInt32 numLines = 1) const override { m_dibSection.scanLines(pBytes, index, numLines); } /** \details Returns the specified set of scanlines in BMP format from the DIBSection object, or the pixel data in BMP format for the DIBSection object. \returns Pointer to the scan lines data. \remarks * The number of accessible scanlines is equal to value returned by pixelHeight(). * The number of accessible bytes in a scanline is equal to the value returned by scanLineSize(). * The scanline returned by firstScanline == 0 is the first scanline in the image. * The scanline returned by firstScanline == (pixelHeight() - 1) is the last scanline in the image. \remarks It us up to the caller to allocate sufficient memory for the scan line data. \remarks Implementation of this function with no arguments is optional; NULL can be returned if it is inconvenient to implement. The caller must take into account that the return value can be NULL. */ const OdUInt8* scanLines() const override { return m_dibSection.scanLines(); } /** \details Returns the size (in bytes) of the palette data of the DIBSection object. \returns Palette size in bytes. */ OdUInt32 paletteDataSize() const override { return m_dibSection.paletteDataSize(); } /** \details Returns the DIB palette data of this DIBSection object. \param bytes [out] Receives the palette data. \remarks It is up to the caller to allocate sufficient memory for the palette data. */ void paletteData(OdUInt8* pBytes) const override { m_dibSection.paletteData(pBytes); } /** \details Returns the number of colors in palette. \returns Number of colors in palette. */ OdUInt32 numColors() const override { return paletteDataSize() / 4; } /** \details Returns the specified color of the DIB palette. \param colorIndex [in] Color index in the palette. \returns ODCOLORREF value that represents a pixel color. */ ODCOLORREF color(OdUInt32 colorIndex) const override { return m_dibSection.color(colorIndex); } /** \details Returns the color depth for the Device Independent Bitmap. \returns The "bits per pixel" value that represents the color depth. */ OdUInt32 colorDepth() const override { return m_dibSection.getBitsPerPixel(); } /** \details Returns the pixel format information. \returns By default BGR pixel format is used. */ PixelFormatInfo pixelFormat() const override { PixelFormatInfo res; if (m_dibSection.getBitsPerPixel() == 24) res.setBGR(); else res.setBGRA(); return res; } /** \details Retrieves the scanline alignment in bytes. \returns By default returns 4. */ OdUInt32 scanLinesAlignment() const override { return 4; } /** \details Retrieves the image source. \returns Image source represented by a value from the ImageSource enumeration. */ ImageSource imageSource() const override { return kFromRender; } /** \details Returns a smart pointer to this OdGiRasterImage object. \returns Smart pointer to this OdGiRasterImage object. */ OdGiRasterImagePtr getRasterImage() { return this; } /** \details Assigns a raster image. \remarks By default this method does nothing. */ void putRasterImage(OdGiRasterImage* ) {} /** \details Returns the number of bits per pixel used for colors by this BitmapDevice object. \returns The color depth value. */ OdUInt32 get_BitPerPixel() const { return colorDepth(); } /** \details Sets the number of bits per pixel used for colors by this BitmapDevice object. \param bitsPerPixel [in] Bits per pixel. */ void put_BitPerPixel(OdUInt32 bitsPerPixel) { putBitPerPixel(bitsPerPixel); } /** \details Returns image parameters for taking snapshots. \returns Smart pointer to this OdGiRasterImage object. */ OdGiRasterImagePtr snapshotImageParams() const { return this; } /** \details Gets a snapshot of the current device. \param area [in] Area from which to take a snapshot. \returns Smart pointer to this OdGiRasterImage object. */ OdGiRasterImagePtr snapshotRegion(const OdGsDCRect &area, bool bCrop) const { if (bCrop) return crop(area.m_min.x, area.m_min.y, area.m_max.x - area.m_min.x, area.m_max.y - area.m_min.y); return this; } protected: /** \details Creates a context for this Device object. */ virtual void createContext() { this->deleteContext(); T::m_hDC = m_dibSection.getHDC(); T::createContext(); } /** \details Returns true if and only if the vectorization is to be rendered to the screen. \note The default implementation of this function always returns false. */ bool renderToScreen() const { return false; } virtual void createPalette(ODGSPALETTE *logicalPalette) { T::createPalette(logicalPalette); if (T::m_pPal) { m_dibSection.setPalette(T::m_pPal); } } GsDIBSection m_dibSection; OdUInt8Array m_trpData; }; #include "TD_PackPop.h" #endif // ODEXGSBITMAPDEVICE_INCLUDED