bool GraphicsContext3D::packPixels(const uint8_t* sourceData, DataFormat sourceDataFormat, unsigned width, unsigned height, unsigned sourceUnpackAlignment, unsigned destinationFormat, unsigned destinationType, AlphaOp alphaOp, void* destinationData, bool flipY)
{
    int validSrc = width * TexelBytesForFormat(sourceDataFormat);
    int remainder = sourceUnpackAlignment ? (validSrc % sourceUnpackAlignment) : 0;
    int srcStride = remainder ? (validSrc + sourceUnpackAlignment - remainder) : validSrc;

    DataFormat dstDataFormat = getDataFormat(destinationFormat, destinationType);
    int dstStride = width * TexelBytesForFormat(dstDataFormat);
    if (flipY) {
        destinationData = static_cast<uint8_t*>(destinationData) + dstStride*(height - 1);
        dstStride = -dstStride;
    }
    if (!hasAlpha(sourceDataFormat) || !hasColor(sourceDataFormat) || !hasColor(dstDataFormat))
        alphaOp = AlphaDoNothing;

    if (sourceDataFormat == dstDataFormat && alphaOp == AlphaDoNothing) {
        const uint8_t* ptr = sourceData;
        const uint8_t* ptrEnd = sourceData + srcStride * height;
        unsigned rowSize = (dstStride > 0) ? dstStride: -dstStride;
        uint8_t* dst = static_cast<uint8_t*>(destinationData);
        while (ptr < ptrEnd) {
            memcpy(dst, ptr, rowSize);
            ptr += srcStride;
            dst += dstStride;
        }
        return true;
    }

    FormatConverter converter(width, height, sourceData, destinationData, srcStride, dstStride);
    converter.convert(sourceDataFormat, dstDataFormat, alphaOp);
    if (!converter.success())
        return false;
    return true;
}
Exemple #2
0
/*! 
 * Returns true if pixel at point (x,y) in device units is transparent.
 */
bool GR_UnixImage::isTransparentAt(UT_sint32 x, UT_sint32 y)
{
  if(!hasAlpha())
  {
    return false;
  }
  UT_return_val_if_fail(m_image,false);
  // UT_sint32 iBitsPerPixel = gdk_pixbuf_get_bits_per_sample(m_image);
  UT_sint32 iRowStride = gdk_pixbuf_get_rowstride(m_image);
  UT_sint32 iWidth =  gdk_pixbuf_get_width(m_image);
  UT_sint32 iHeight =  gdk_pixbuf_get_height(m_image);
  UT_ASSERT(iRowStride/iWidth == 4);
  UT_return_val_if_fail((x>= 0) && (x < iWidth), false);
  UT_return_val_if_fail((y>= 0) && (y < iHeight), false);
  guchar * pData = gdk_pixbuf_get_pixels(m_image);
  xxx_UT_DEBUGMSG(("BitsPerPixel = %d \n",iBitsPerPixel));
  UT_sint32 iOff = iRowStride*y;
  guchar pix0 = pData[iOff+ x*4];
  guchar pix1 = pData[iOff+ x*4 +1];
  guchar pix2 = pData[iOff+ x*4 +2];
  guchar pix3 = pData[iOff+ x*4 +3];
  if((pix3 | pix0 | pix1 | pix2) == 0)
  {
    return true;
  }
  UT_DEBUGMSG(("x %d y %d pix0 %d pix1 %d pix2 %d pix3 %d \n",x,y,pix0,pix1,pix2,pix3));
  return false;
}
Exemple #3
0
String Color::serialized() const
{
    if (!hasAlpha()) {
        StringBuilder builder;
        builder.reserveCapacity(7);
        builder.append('#');
        appendByteAsHex(red(), builder, Lowercase);
        appendByteAsHex(green(), builder, Lowercase);
        appendByteAsHex(blue(), builder, Lowercase);
        return builder.toString();
    }

    StringBuilder result;
    result.reserveCapacity(28);

    result.appendLiteral("rgba(");
    result.appendNumber(red());
    result.appendLiteral(", ");
    result.appendNumber(green());
    result.appendLiteral(", ");
    result.appendNumber(blue());
    result.appendLiteral(", ");

    if (!alpha())
        result.append('0');
    else {
        result.append(Decimal::fromDouble(alpha() / 255.0).toString());
    }

    result.append(')');
    return result.toString();
}
Exemple #4
0
String Color::serializedAsCSSComponentValue() const
{
    StringBuilder result;
    result.reserveCapacity(32);
    bool colorHasAlpha = hasAlpha();
    if (colorHasAlpha)
        result.appendLiteral("rgba(");
    else
        result.appendLiteral("rgb(");

    result.appendNumber(static_cast<unsigned char>(red()));
    result.appendLiteral(", ");

    result.appendNumber(static_cast<unsigned char>(green()));
    result.appendLiteral(", ");

    result.appendNumber(static_cast<unsigned char>(blue()));
    if (colorHasAlpha) {
        result.appendLiteral(", ");

        NumberToStringBuffer buffer;
        const char* alphaString = numberToFixedPrecisionString(alpha() / 255.0f, 6, buffer, true);
        result.append(alphaString, strlen(alphaString));
    }

    result.append(')');
    return result.toString();
}
Exemple #5
0
SurfaceT<T> SurfaceT<T>::clone( bool copyPixels ) const
{
	SurfaceT result( getWidth(), getHeight(), hasAlpha(), getChannelOrder() );
	if( copyPixels )
		result.copyFrom( *this, getBounds() );
	
	return result;
}
Exemple #6
0
SurfaceT<T> SurfaceT<T>::clone( const Area &area, bool copyPixels ) const
{
	SurfaceT result( area.getWidth(), area.getHeight(), hasAlpha(), getChannelOrder() );
	if( copyPixels )
		result.copyFrom( *this, area, -area.getUL() );
	
	return result;
}
Exemple #7
0
// For all ops, an "Identity" is an op that only does bit-depth conversion
// and is therefore a candidate for the optimizer to remove.
bool MatrixOpData::isIdentity() const
{
    if (hasOffsets() || hasAlpha() || !isDiagonal())
    {
        return false;
    }

    return isMatrixIdentity();
}
Exemple #8
0
void SurfaceT<T>::copyFrom( const SurfaceT<T> &srcSurface, const Area &srcArea, const Vec2i &relativeOffset )
{
	std::pair<Area,Vec2i> srcDst = clippedSrcDst( srcSurface.getBounds(), srcArea, getBounds(), srcArea.getUL() + relativeOffset );
	
	if( getChannelOrder() == srcSurface.getChannelOrder() )
		copyRawSameChannelOrder( srcSurface, srcDst.first, srcDst.second );
	else if( hasAlpha() && srcSurface.hasAlpha() )
		copyRawRgba( srcSurface, srcDst.first, srcDst.second );
	else
		copyRawRgb( srcSurface, srcDst.first, srcDst.second );
}
Exemple #9
0
NativeImagePtr RGBA32Buffer::asNewNativeImage() const
{
    if (!m_image) {
        static const VGImageFormat bufferFormat = VG_sARGB_8888_PRE;

        // Save memory by using 16-bit images for fully opaque images.
        const VGImageFormat imageFormat = hasAlpha()
            ? WEBKIT_OPENVG_NATIVE_IMAGE_FORMAT_s_8888
            : VG_sRGB_565;

#if PLATFORM(EGL)
        EGLDisplayOpenVG::current()->sharedPlatformSurface()->makeCurrent();
#endif

        const IntSize vgMaxImageSize(vgGeti(VG_MAX_IMAGE_WIDTH), vgGeti(VG_MAX_IMAGE_HEIGHT));
        ASSERT_VG_NO_ERROR();

        PassRefPtr<TiledImageOpenVG> tiledImage = adoptRef(new TiledImageOpenVG(
            IntSize(width(), height()), vgMaxImageSize));

        const int numColumns = tiledImage->numColumns();
        const int numRows = tiledImage->numRows();

        for (int yIndex = 0; yIndex < numRows; ++yIndex) {
            for (int xIndex = 0; xIndex < numColumns; ++xIndex) {
                IntRect tileRect = tiledImage->tileRect(xIndex, yIndex);
                VGImage tile = vgCreateImage(imageFormat,
                    tileRect.width(), tileRect.height(), VG_IMAGE_QUALITY_FASTER);
                ASSERT_VG_NO_ERROR();

                PixelData* pixelData = m_bytes.data();
                pixelData += (tileRect.y() * width()) + tileRect.x();

                vgImageSubData(tile, reinterpret_cast<unsigned char*>(pixelData),
                    width() * sizeof(PixelData), bufferFormat,
                    0, 0, tileRect.width(), tileRect.height());
                ASSERT_VG_NO_ERROR();

                tiledImage->setTile(xIndex, yIndex, tile);
            }
        }

        // Incomplete images will be returned without storing them in m_image,
        // so the image will be regenerated once loading is complete.
        if (m_status != FrameComplete)
            return tiledImage;

        m_image = tiledImage;
        m_bytes.clear();
    }

    return m_image; // and increase refcount
}
void ImageTargetFileQuartz::setupImageDestOptions()
{
	int bitsPerComponent = ImageIo::dataTypeBytes( getDataType() ) * 8;

	// setup the dictionary of options for CGImageDestinationAddImage
	mImageDestOptions = std::shared_ptr<__CFDictionary>( ::CFDictionaryCreateMutable( kCFAllocatorDefault, 3, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ), cocoa::safeCfRelease );
	::CFDictionarySetValue( mImageDestOptions.get(), kCGImagePropertyIsFloat, ( getDataType() == ImageIo::FLOAT32 ) ? kCFBooleanTrue : kCFBooleanFalse );
	::CFDictionarySetValue( mImageDestOptions.get(), kCGImagePropertyHasAlpha, ( hasAlpha() ) ? kCFBooleanTrue : kCFBooleanFalse );
	::CFNumberRef depthNumber = ::CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &bitsPerComponent );
	::CFDictionarySetValue( mImageDestOptions.get(), kCGImagePropertyDepth, depthNumber );
	::CFRelease( depthNumber );
}
	void TextureCommandsGL33::write(unsigned int level, unsigned int width, unsigned int height, PixelFormat format,
			PixelType type, void const* data)
	{
		GLint intFormatgl = hasAlpha(format) ? GL_RGBA : GL_RGB;
		GLint formatgl = pixelFormat2GL(format);
		glGetError();
		glTexImage2D(texType2GL(s_pCurTexture->getType()), level, intFormatgl, width, height, 0, formatgl,
				pixelType2GL(type), data);
		auto err = glGetError();
		if (err != GL_NO_ERROR)
			throw std::runtime_error { std::string { "glTexImage2D failed: " }
					+ reinterpret_cast<const char*>(glewGetErrorString(err)) };
	}
Exemple #12
0
void SharedBitmap::draw(HDC hdc, const IntRect& dstRect, const IntRect& srcRect, CompositeOperator compositeOp, BlendMode blendMode)
{
    if (!m_pixels)
        return;

    if (dstRect.isEmpty() || srcRect.isEmpty())
        return;

    HBITMAP hbitmap = 0;
    OwnPtr<HBITMAP> hTempBitmap;
    bool usingHandle = compositeOp == CompositeSourceOver && (hasAlpha() && hasAlphaBlendSupport() || usesTransparentColor());

    if (usingHandle) {
        if (ensureHandle())
            hbitmap = m_hbitmap.get();
        else {
            void* pixels;
            BitmapInfo bmpInfo;
            hTempBitmap = createHandle(&pixels, &bmpInfo, -1, usesTransparentColor());
            hbitmap = hTempBitmap.get();
        }
    }
    if (!hbitmap) {
        // FIXME: handle other composite operation types?
        DWORD rop = compositeOp == CompositeCopy ? SRCCOPY
            : compositeOp == CompositeXOR ? PATINVERT
            : compositeOp == CompositeClear ? WHITENESS
            : SRCCOPY;

        StretchDIBits(hdc, dstRect.x(), dstRect.y(), dstRect.width(), dstRect.height(),
            srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height(), m_pixels, &m_bmpInfo, DIB_RGB_COLORS, rop);
        return;
    }

    OwnPtr<HDC> hmemdc = adoptPtr(CreateCompatibleDC(hdc));
    HGDIOBJ hOldBmp = SelectObject(hmemdc.get(), hbitmap);

    if (!usesTransparentColor() && hasAlphaBlendSupport()) {
        static const BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
        bool success = alphaBlendIfSupported(hdc, dstRect.x(), dstRect.y(), dstRect.width(), dstRect.height(), hmemdc.get(),
            srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height(), blend);
        ASSERT_UNUSED(success, success);
    } else {
        TransparentBlt(hdc, dstRect.x(), dstRect.y(), dstRect.width(), dstRect.height(), hmemdc.get(),
            srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height(), transparentColor());
    }

    SelectObject(hmemdc.get(), hOldBmp);
}
Exemple #13
0
Color Color::blendWithWhite() const
{
    // If the color contains alpha already, we leave it alone.
    if (hasAlpha())
        return *this;

    Color newColor;
    for (int alpha = cStartAlpha; alpha <= cEndAlpha; alpha += cAlphaIncrement) {
        // We have a solid color.  Convert to an equivalent color that looks the same when blended with white
        // at the current alpha.  Try using less transparency if the numbers end up being negative.
        int r = blendComponent(red(), alpha);
        int g = blendComponent(green(), alpha);
        int b = blendComponent(blue(), alpha);

        newColor = Color(r, g, b, alpha);

        if (r >= 0 && g >= 0 && b >= 0)
            break;
    }
    return newColor;
}
NativeImagePtr RGBA32Buffer::asNewNativeImage() const
{
    static const VGImageFormat bufferFormat = VG_sARGB_8888_PRE;
    // Save memory by using 16-bit images for fully opaque images.
    const VGImageFormat imageFormat = hasAlpha() ? bufferFormat : VG_sRGB_565;

#if PLATFORM(EGL)
    EGLDisplayOpenVG::current()->sharedPlatformSurface()->makeCurrent();
#endif

    const IntSize vgMaxImageSize(vgGeti(VG_MAX_IMAGE_WIDTH), vgGeti(VG_MAX_IMAGE_HEIGHT));
    ASSERT_VG_NO_ERROR();

    TiledImageOpenVG* tiledImage = new TiledImageOpenVG(IntSize(width(), height()), vgMaxImageSize);

    const int numColumns = tiledImage->numColumns();
    const int numRows = tiledImage->numRows();

    for (int yIndex = 0; yIndex < numRows; ++yIndex) {
        for (int xIndex = 0; xIndex < numColumns; ++xIndex) {
            IntRect tileRect = tiledImage->tileRect(xIndex, yIndex);
            VGImage image = vgCreateImage(imageFormat,
                tileRect.width(), tileRect.height(), VG_IMAGE_QUALITY_FASTER);
            ASSERT_VG_NO_ERROR();

            PixelData* pixelData = const_cast<PixelData*>(m_bytes);
            pixelData += (tileRect.y() * width()) + tileRect.x();

            vgImageSubData(image, reinterpret_cast<unsigned char*>(pixelData),
                width() * sizeof(PixelData), bufferFormat,
                0, 0, tileRect.width(), tileRect.height());
            ASSERT_VG_NO_ERROR();

            tiledImage->setTile(xIndex, yIndex, image);
        }
    }

    return tiledImage;
}
bool DeviceOrientationProviderQt::filter(QRotationReading* reading)
{
    if (m_controller) {
        // Provide device orientation data according W3C spec:
        // http://dev.w3.org/geo/api/spec-source-orientation.html
        // Qt mobility (QtSensors in Qt5) provide these data via QRotationSensor
        // using the QRotationReading class:
        //  - the rotation around z axis (alpha) is given as z in QRotationReading;
        //  - the rotation around x axis (beta) is given as x in QRotationReading;
        //  - the rotation around y axis (gamma) is given as y in QRotationReading;
        // See: http://doc.qt.nokia.com/qtmobility-1.0/qrotationreading.html
        // The Z (alpha) rotation angle is checked via hasAlpha() private method,
        // depending if the device is able do detect the alpha rotation. X (beta) and
        // Y (gamma) axis are availble in this context.
        m_lastOrientation = DeviceOrientationData::create(hasAlpha(), reading->z(),
                /* x available */ true, reading->x(),
                /* y available */ true, reading->y());
        m_controller->didChangeDeviceOrientation(m_lastOrientation.get());
    }

    // We are the only filter, so no need to propagate.
    return false;
}
Exemple #16
0
bool SharedBitmap::ensureHandle()
{
    if (m_hbitmap)
        return true;

    if (!m_pixels)
        return false;

    if (m_locked)
        return false;

    BitmapInfo bmpInfo;
    void* pixels;
    m_hbitmap = createHandle(&pixels, &bmpInfo, -1, !hasAlpha());

    if (!m_hbitmap)
        return false;

    m_pixelData = nullptr;
    m_pixels = pixels;
    m_bmpInfo = bmpInfo;

    return true;
}
String Color::serialized() const
{
    if (!hasAlpha()) {
        StringBuilder builder;
        builder.reserveCapacity(7);
        builder.append('#');
        appendByteAsHex(red(), builder, Lowercase);
        appendByteAsHex(green(), builder, Lowercase);
        appendByteAsHex(blue(), builder, Lowercase);
        return builder.toString();
    }

    Vector<LChar> result;
    result.reserveInitialCapacity(28);
    const char commaSpace[] = ", ";
    const char rgbaParen[] = "rgba(";

    result.append(rgbaParen, 5);
    appendNumber(result, red());
    result.append(commaSpace, 2);
    appendNumber(result, green());
    result.append(commaSpace, 2);
    appendNumber(result, blue());
    result.append(commaSpace, 2);

    if (!alpha())
        result.append('0');
    else {
        NumberToLStringBuffer buffer;
        unsigned length = DecimalNumber(alpha() / 255.0).toStringDecimal(buffer, WTF::NumberToStringBufferLength);
        result.append(buffer, length);
    }

    result.append(')');
    return String::adopt(result);
}
Exemple #18
0
/*!
    Creates a \c HBITMAP equivalent to the QPixmap. Returns the \c HBITMAP
    handle.

    If \a mask is not NULL, the mask mode is turned on. In this mode, the bitmap
    mask is also created from the QPixmap's mask and returned in the given
    variable. This bitmap mask will contain two vertically adjacent sections,
    the first of which is the AND mask and the second one is the XOR mask
    (according to WinCreatePointer() specification). Also, in mask mode, the
    HBITMAP returned for the pixmap itself will be prepared for masking (with
    transparent pixels made black). This mode is useful for creating system
    icons and pointers (\sa toPmHPOINTER()).

    if \a embedRealAlpha is \c true, the real alpha chennel (not the 1bpp mask)
    will be embedded in the high 8 bits of the 32-bit pixel value for each pixel
    in the created bitmap (which always has 1 plane and the 32-bit depth). This
    extra information isn't touched by PM/GPI but may be used by custom drawing
    routines to do real alpha blending.

    Note that if \a mask is not NULL but the pixmap does neither have a mask nor
    the alpha channel, an emptpy bitmap mask with no transparency (zeroed AND
    and XOR parts) will be created and returned.

    It is the caller's responsibility to free both returned \c HBITMAP handes
    after use.

    \warning This function is only available on OS/2.

    \sa fromPmHBITMAP(), toPmHPOINTER()
*/
HBITMAP QPixmap::toPmHBITMAP(HBITMAP *mask, bool embedRealAlpha) const
{
    if (data->classId() != QPixmapData::RasterClass) {
        QPixmapData *data = new QRasterPixmapData(depth() == 1 ?
                                                  QPixmapData::BitmapType :
                                                  QPixmapData::PixmapType);
        data->fromImage(toImage(), Qt::AutoColor);
        return QPixmap(data).toPmHBITMAP(mask, embedRealAlpha);
    }

    QRasterPixmapData* d = static_cast<QRasterPixmapData*>(data.data());
    int w = d->image.width();
    int h = d->image.height();

    HPS hps = qt_alloc_mem_ps(w, h * 2);
    if (hps == NULLHANDLE)
        return NULLHANDLE;

    HBITMAP hbm = NULLHANDLE;
    HBITMAP hbmMask = NULLHANDLE;

    // Note that we always use ARGB32 even if embedRealAlpha is false because
    // in this case we will use the alpha channel to dither the 1bpp mask
    QImage image = d->image.convertToFormat(QImage::Format_ARGB32);
    // flip the bitmap top to bottom for PM
    image = image.mirrored();

    // bitmap header + 2 palette entries (for the mask)
    char bmi[sizeof(BITMAPINFOHEADER2) + 4 * 2];
    memset(bmi, 0, sizeof(bmi));
    PBITMAPINFOHEADER2 bmh = (PBITMAPINFOHEADER2)bmi;
    bmh->cbFix = sizeof(BITMAPINFOHEADER2);
    PULONG pal = (PULONG)(bmi + sizeof(BITMAPINFOHEADER2));

    // create the normal bitmap from the pixmap data
    bmh->cx = w;
    bmh->cy = h;
    bmh->cPlanes = 1;
    bmh->cBitCount = 32;
    hbm = GpiCreateBitmap(hps, bmh, CBM_INIT, (PBYTE)(const uchar *)image.bits(),
                          (PBITMAPINFO2)&bmi);

    if (mask) {
        // get the mask
        QImage mask;
        if (hasAlpha()) {
            if (!embedRealAlpha) {
                // We prefer QImage::createAlphaMask() over QPixmap::mask()
                // since the former will dither while the latter will convert any
                // non-zero alpha value to an opaque pixel
                mask = image.createAlphaMask().convertToFormat(QImage::Format_Mono);

                // note: for some strange reason, createAlphaMask() (as opposed to
                // mask().toImage()) returns an image already flipped top to bottom,
                // so take it into account

                // create the AND mask
                mask.invertPixels();
                // add the XOR mask (and leave it zeroed)
                mask = mask.copy(0, -h, w, h * 2);
            } else {
                // if we embedded real alpha, we still need a mask if we are going
                // to create a pointer out of this pixmap (WinCreatePointerIndirect()
                // requirement), but we will use QPixmap::mask() because it won't be
                // able to destroy the alpha channel of non-fully transparent pixels
                // when preparing the color bitmap for masking later. We could also
                // skip this prepare step, but well, let's go this way, it won't hurt.
                mask = this->mask().toImage().convertToFormat(QImage::Format_Mono);

                // create the AND mask
                mask.invertPixels();
                // add the XOR mask (and leave it zeroed)
                mask = mask.copy(0, 0, w, h * 2);
                // flip the bitmap top to bottom for PM
                mask = mask.mirrored(false, true);
            }
        } else {
            mask = QImage(w, h * 2, QImage::Format_Mono);
            mask.fill(0);
        }

        // create the mask bitmap
        bmh->cbFix = sizeof(BITMAPINFOHEADER2);
        bmh->cx = w;
        bmh->cy = h * 2;
        bmh->cPlanes = 1;
        bmh->cBitCount = 1;
        bmh->cclrUsed = 2;
        pal[0] = 0;
        pal[1] = 0x00FFFFFF;
        hbmMask = GpiCreateBitmap(hps, bmh, CBM_INIT,
                                  (PBYTE)(const uchar *)mask.bits(),
                                  (PBITMAPINFO2)&bmi);

        // prepare the bitmap for masking by setting transparent pixels to black
        GpiSetBitmap(hps, hbm);

        POINTL ptls[] = {
            { 0, 0 }, { w - 1, h - 1 },     // dst: inclusive-inclusive
            { 0, h }, { w, h * 2 },         // src: inclusive-exclusive
        };
        ptls[0].y -= h;
        ptls[1].y -= h;
        enum { AllImageAttrs = IBB_COLOR | IBB_BACK_COLOR |
                               IBB_MIX_MODE | IBB_BACK_MIX_MODE };
        IMAGEBUNDLE ib = { CLR_TRUE, CLR_FALSE, FM_OVERPAINT, BM_OVERPAINT };
        GpiSetAttrs(hps, PRIM_IMAGE, AllImageAttrs, 0, (PBUNDLE)&ib);
        GpiDrawBits(hps, (PBYTE)(const uchar *)mask.bits(), (PBITMAPINFO2)&bmi,
                    4, ptls, ROP_SRCAND, BBO_IGNORE);
    }

    qt_free_mem_ps(hps);

    if (mask)
        *mask = hbmMask;

    return hbm;
}
void ImageTargetFileWic::setupPixelFormat( const GUID &guid )
{
	if( guid == GUID_WICPixelFormat24bppBGR ) {		
		setChannelOrder( ImageIo::BGR ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT8 );
	}
	else if( guid == GUID_WICPixelFormat24bppRGB ) {
		setChannelOrder( ImageIo::RGB ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT8 );
	}
	else if( guid == GUID_WICPixelFormat32bppBGR ) {
		setChannelOrder( ImageIo::BGRX ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT8 );
	}
	else if( guid == GUID_WICPixelFormat32bppBGRA ) {
		setChannelOrder( ImageIo::BGRA ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT8 );
	}
	else if( guid == GUID_WICPixelFormat32bppPBGRA ) {
		setChannelOrder( ImageIo::BGRA ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT8 );// mIsPremultipliedAlpha = true;
	}
	else if( guid == GUID_WICPixelFormat48bppRGB ) {
		setChannelOrder( ImageIo::RGB ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT16 );
	}
	else if( guid == GUID_WICPixelFormat64bppRGBA ) {
		setChannelOrder( ImageIo::RGBA ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT16 );
	}
	else if( guid == GUID_WICPixelFormat64bppPRGBA ) {
		setChannelOrder( ImageIo::RGBA ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT16 ); // mIsPremultipliedAlpha = true;
	}
	else if( guid == GUID_WICPixelFormat128bppRGBFloat ) {
		setChannelOrder( ImageIo::RGB ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::FLOAT32 );
	}
	else if( guid == GUID_WICPixelFormat8bppGray ) {
		setChannelOrder( ImageIo::Y ); setColorModel( ImageIo::CM_GRAY ); setDataType( ImageIo::UINT8 );
	}
	else if( guid == GUID_WICPixelFormat16bppGray ) {
		setChannelOrder( ImageIo::Y ); setColorModel( ImageIo::CM_GRAY ); setDataType( ImageIo::UINT16 );
	}
	else if( guid == GUID_WICPixelFormat32bppGrayFloat ) {
		setChannelOrder( ImageIo::Y ); setColorModel( ImageIo::CM_GRAY ); setDataType( ImageIo::FLOAT32 );
	}
	else
		throw ImageIoExceptionFailedLoad();
	
	int32_t bitsPerComponent;
	bool writingAlpha = hasAlpha();
	bool isFloat = true;
	switch( getDataType() ) {
		case ImageIo::UINT8: bitsPerComponent = 8; isFloat = false; break;
		case ImageIo::UINT16: bitsPerComponent = 16; isFloat = false; break;
		default: bitsPerComponent = 32; isFloat = true;
	}
	uint8_t numChannels;
	switch( getColorModel() ) {
		case ImageIo::CM_GRAY:
			numChannels = ( writingAlpha ) ? 2 : 1; break;
		default:
			numChannels = ( writingAlpha ) ? 4 : 3;
	}
	int32_t bitsPerPixel = numChannels * bitsPerComponent;
	mRowBytes = ( mWidth * ( bitsPerPixel / 8 ) + 3 ) & ~3;

	return;
}
/*!
 * Return the distance from the left side of the image that is "pad" distance
 * to the nearest point in the transparent outline from the line segment
 * start at Y and running for distance Height below it.
 * All distances are in logical units.
 *                -----------------
 *                |               |
 *                |      *        |
 *                |    *****      |
 *             ||||||   ***       |
 *                | |    **       |
 *                |---------------|
 *                | |
 *                | |
 *
 * This case would give a -ve distance.
 * The input yTop is in logical units as measured from the top of the image.
 * If y is above the image it should be negative.
 * The returned value is in logical units.
 */
UT_sint32 GR_Image::GetOffsetFromLeft(GR_Graphics * pG, UT_sint32 pad, UT_sint32 yTop, UT_sint32 height)
{
  if(!hasAlpha())
  {
    return pad;
  }
  if(!isOutLinePresent())
  {
    GenerateOutline();
  }
  double maxDist = -10000000.0;
  double d = 0.0;
  UT_uint32 i = 0;
  double ddPad = static_cast<double>(pG->tdu(pad));
  UT_sint32 diTop = pG->tdu(yTop);
  UT_sint32 diHeight = pG->tdu(height);
  double ddTop = static_cast<double>(diTop);
  double ddHeight = static_cast<double>(diHeight);
  GR_Image_Point * pPoint = NULL;
  UT_uint32 nPts = m_vecOutLine.getItemCount()/2;
  for(i=0; i < nPts;i++)
  {
    pPoint = m_vecOutLine.getNthItem(i);
    if((pPoint->m_iY >= diTop) && (pPoint->m_iY <= (yTop + diHeight)))
    {
      d = ddPad - static_cast<double>(pPoint->m_iX);
    }
    else
    {
      double y = ddTop + ddHeight;
      if(abs(pPoint->m_iY - diTop) < abs(pPoint->m_iY - (diTop + diHeight)))
      {
	//
	// Calculate from top point.
	//
	y = ddTop;
      }
      double dYP = static_cast<double>(pPoint->m_iY);
      double root = ddPad*ddPad - (y - dYP)*(y - dYP);
      if(root < 0.0)
      {
	//
	// This point doesn't overlap at all
	//
	  d = -10000000.0;
      }
      else
      {
	d = -static_cast<double>(pPoint->m_iX) - sqrt(root); 
      }
    }
    if(d > maxDist)
    {
      maxDist = d;
    }
  }
  if(maxDist < -9999999.)
  {
    maxDist = static_cast<double>(-getDisplayWidth());
  }
  return pG->tlu(static_cast<UT_sint32>(maxDist));
}
Exemple #21
0
void SharedBitmap::drawPattern(HDC hdc, const AffineTransform& transform, const FloatRect& tileRectIn, const AffineTransform& patternTransform,
                        const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect, const IntSize& origSourceSize)
{
    if (!m_pixels)
        return;

    if (tileRectIn.width() <= 0 || tileRectIn.height() <= 0)
        return;

    bool useAlpha = op == CompositeSourceOver && hasAlpha() && is32bit();

    int bmpWidth = width();
    int bmpHeight = height();

    FloatRect tileRect(tileRectIn);
    if (bmpWidth != origSourceSize.width()) {
        double rate = static_cast<double>(bmpWidth) / origSourceSize.width();
        double temp = tileRect.width() * rate;
        tileRect.setX(tileRect.x() * rate);
        tileRect.setWidth(temp);
        temp = tileRect.height() * rate;
        tileRect.setY(tileRect.y() * rate);
        tileRect.setHeight(temp);
    }

    OwnPtr<HBITMAP> clippedBmp;

    if (tileRect.x() || tileRect.y() || tileRect.width() != bmpWidth || tileRect.height() != bmpHeight) {
        BitmapInfo patternBmpInfo;
        void* patternPixels;
        clippedBmp = clipBitmap(IntRect(tileRect), useAlpha, patternBmpInfo, patternPixels);
        if (!clippedBmp)
            return;

        bmpWidth = tileRect.width();
        bmpHeight = tileRect.height();
    }

    AffineTransform tf = patternTransform * transform;

    FloatRect trRect = tf.mapRect(destRect);

    RECT clipBox;
    int clipType = GetClipBox(hdc, &clipBox);
    if (clipType == SIMPLEREGION)
        trRect.intersect(FloatRect(clipBox.left, clipBox.top, clipBox.right - clipBox.left, clipBox.bottom - clipBox.top));
    else if (clipType == COMPLEXREGION) {
        OwnPtr<HRGN> clipRgn = adoptPtr(CreateRectRgn(0, 0, 0, 0));
        if (GetClipRgn(hdc, clipRgn.get()) > 0) {
            DWORD regionDataSize = GetRegionData(clipRgn.get(), sizeof(RGNDATA), 0);
            if (regionDataSize) {
                Vector<RGNDATA> regionData(regionDataSize);
                GetRegionData(clipRgn.get(), regionDataSize, regionData.data());
                RECT* rect = reinterpret_cast<RECT*>(regionData[0].Buffer);
                for (DWORD i = 0; i < regionData[0].rdh.nCount; ++i, ++rect)
                    trRect.intersect(FloatRect(rect->left, rect->top, rect->right - rect->left, rect->bottom - rect->top));
            }
        }
    }

    if (trRect.width() <= 0 || trRect.height() <= 0)
        return;

    trRect.inflate(1);
    IntRect visibleDstRect = enclosingIntRect(tf.inverse().mapRect(trRect));
    visibleDstRect.intersect(IntRect(destRect));

    if (visibleDstRect.width() <= 0 || visibleDstRect.height() <= 0)
        return;

    trRect = tf.mapRect(visibleDstRect);
    RECT dstRectWin = {
        stableRound(trRect.x()),
        stableRound(trRect.y()),
        stableRound(trRect.maxX()),
        stableRound(trRect.maxY()),
    };
    if (dstRectWin.right <= dstRectWin.left || dstRectWin.bottom <= dstRectWin.top)
        return;

    SIZE bmpSize = { bmpWidth, bmpHeight };

    // Relative to destination, in bitmap pixels
    POINT phaseWin = { stableRound(visibleDstRect.x() - phase.x()), stableRound(visibleDstRect.y() - phase.y()) };
    phaseWin.x = normalizePhase(phaseWin.x, bmpSize.cx);
    phaseWin.y = normalizePhase(phaseWin.y, bmpSize.cy);

    RECT srcRectWin = {
        0,
        0,
        stableRound(visibleDstRect.maxX()) - stableRound(visibleDstRect.x()),
        stableRound(visibleDstRect.maxY()) - stableRound(visibleDstRect.y())
    };
    if (srcRectWin.right <= 0 || srcRectWin.bottom <= 0)
        return;

    BitmapInfo bmpInfo = BitmapInfo::createBottomUp(IntSize(srcRectWin.right, srcRectWin.bottom), useAlpha ? BitmapInfo::BitCount32 : BitmapInfo::BitCount16);
    void* pixels;
    OwnPtr<HBITMAP> hbmpTemp = adoptPtr(CreateDIBSection(0, &bmpInfo, DIB_RGB_COLORS, &pixels, 0, 0));

    if (!hbmpTemp)
        return;

    OwnPtr<HDC> hmemdc = adoptPtr(CreateCompatibleDC(hdc));
    HGDIOBJ oldBmp = SelectObject(hmemdc.get(), hbmpTemp.get());
    if (clippedBmp)
        drawPatternSimple(hmemdc.get(), srcRectWin, clippedBmp.get(), phaseWin);
    else if ((op != CompositeSourceOver || canUseDIBits()) && srcRectWin.right <= bmpSize.cx * 2 && srcRectWin.bottom <= bmpSize.cy * 2)
        drawPatternSimple(hmemdc.get(), srcRectWin, this, bmpSize, phaseWin);
    else if (ensureHandle())
        drawPatternSimple(hmemdc.get(), srcRectWin, getHandle(), phaseWin);
    else {
        void* pixels;
        BitmapInfo bmpInfo;
        OwnPtr<HBITMAP> hbmp = createHandle(&pixels, &bmpInfo, -1, false);
        if (hbmp)
            drawPatternSimple(hmemdc.get(), srcRectWin, hbmp.get(), phaseWin);
        else {
            SelectObject(hmemdc.get(), oldBmp);
            return;
        }
    }

    if (useAlpha && hasAlphaBlendSupport()) {
        static const BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
        bool success = alphaBlendIfSupported(hdc, dstRectWin.left, dstRectWin.top, dstRectWin.right - dstRectWin.left, dstRectWin.bottom - dstRectWin.top,
            hmemdc.get(), 0, 0, srcRectWin.right, srcRectWin.bottom, blend);
        ASSERT_UNUSED(success, success);
    } else if (useAlpha && !hasAlphaBlendSupport() || op == CompositeSourceOver && usesTransparentColor()) {
        TransparentBlt(hdc, dstRectWin.left, dstRectWin.top, dstRectWin.right - dstRectWin.left,
            dstRectWin.bottom - dstRectWin.top, hmemdc.get(), 0, 0, srcRectWin.right, srcRectWin.bottom, transparentColor());
    } else {
        DWORD bmpOp = op == CompositeCopy ? SRCCOPY
                    : op == CompositeSourceOver ? SRCCOPY
                    : op == CompositeXOR ? PATINVERT
                    : op == CompositeClear ? WHITENESS
                    : SRCCOPY; // FIXEME: other types?

        StretchDIBits(hdc, dstRectWin.left, dstRectWin.top, dstRectWin.right - dstRectWin.left,
            dstRectWin.bottom - dstRectWin.top, 0, 0, srcRectWin.right, srcRectWin.bottom,
            pixels, &bmpInfo, DIB_RGB_COLORS, bmpOp);
    }
    SelectObject(hmemdc.get(), oldBmp);
}