CGImageRef CreateCGImage(void *aInfo, const void *aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat) { //XXX: we should avoid creating this colorspace everytime CGColorSpaceRef colorSpace = nullptr; CGBitmapInfo bitinfo = 0; int bitsPerComponent = 0; int bitsPerPixel = 0; switch (aFormat) { case SurfaceFormat::B8G8R8A8: colorSpace = CGColorSpaceCreateDeviceRGB(); bitinfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host; bitsPerComponent = 8; bitsPerPixel = 32; break; case SurfaceFormat::B8G8R8X8: colorSpace = CGColorSpaceCreateDeviceRGB(); bitinfo = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host; bitsPerComponent = 8; bitsPerPixel = 32; break; case SurfaceFormat::A8: // XXX: why don't we set a colorspace here? bitsPerComponent = 8; bitsPerPixel = 8; break; default: MOZ_CRASH(); } size_t bufLen = BufferSizeFromStrideAndHeight(aStride, aSize.height); if (bufLen == 0) { return nullptr; } CGDataProviderRef dataProvider = CGDataProviderCreateWithData(aInfo, aData, bufLen, releaseCallback); CGImageRef image; if (aFormat == SurfaceFormat::A8) { CGFloat decode[] = {1.0, 0.0}; image = CGImageMaskCreate (aSize.width, aSize.height, bitsPerComponent, bitsPerPixel, aStride, dataProvider, decode, true); } else { image = CGImageCreate (aSize.width, aSize.height, bitsPerComponent, bitsPerPixel, aStride, colorSpace, bitinfo, dataProvider, nullptr, true, kCGRenderingIntentDefault); } CGDataProviderRelease(dataProvider); CGColorSpaceRelease(colorSpace); return image; }
FX_BOOL CFX_AggDeviceDriver::DrawDeviceText(int nChars, const FXTEXT_CHARPOS * pCharPos, CFX_Font * pFont, CFX_FontCache * pCache, const CFX_AffineMatrix * pObject2Device, FX_FLOAT font_size, FX_DWORD argb, int alpha_flag, void* pIccTransform) { if (!pFont) { return FALSE; } FX_BOOL bBold = pFont->IsBold(); if (!bBold && pFont->GetSubstFont() && pFont->GetSubstFont()->m_Weight >= 500 && pFont->GetSubstFont()->m_Weight <= 600) { return FALSE; } for (int i = 0; i < nChars; i ++) { if (pCharPos[i].m_bGlyphAdjust) { return FALSE; } } CGContextRef ctx = CGContextRef(m_pPlatformGraphics); if (NULL == ctx) { return FALSE; } CGContextSaveGState(ctx); CGContextSetTextDrawingMode(ctx, kCGTextFillClip); CGRect rect_cg; CGImageRef pImageCG = NULL; if (m_pClipRgn) { rect_cg = CGRectMake(m_pClipRgn->GetBox().left, m_pClipRgn->GetBox().top, m_pClipRgn->GetBox().Width(), m_pClipRgn->GetBox().Height()); const CFX_DIBitmap* pClipMask = m_pClipRgn->GetMask(); if (pClipMask) { CGDataProviderRef pClipMaskDataProvider = CGDataProviderCreateWithData(NULL, pClipMask->GetBuffer(), pClipMask->GetPitch() * pClipMask->GetHeight(), _DoNothing); CGFloat decode_f[2] = {255.f, 0.f}; pImageCG = CGImageMaskCreate(pClipMask->GetWidth(), pClipMask->GetHeight(), 8, 8, pClipMask->GetPitch(), pClipMaskDataProvider, decode_f, FALSE); CGDataProviderRelease(pClipMaskDataProvider); } } else { rect_cg = CGRectMake(0, 0, m_pBitmap->GetWidth(), m_pBitmap->GetHeight()); } rect_cg = CGContextConvertRectToDeviceSpace(ctx, rect_cg); if (pImageCG) { CGContextClipToMask(ctx, rect_cg, pImageCG); } else { CGContextClipToRect(ctx, rect_cg); } FX_BOOL ret = _CGDrawGlyphRun(ctx, nChars, pCharPos, pFont, pCache, pObject2Device, font_size, argb, alpha_flag, pIccTransform); if (pImageCG) { CGImageRelease(pImageCG); } CGContextRestoreGState(ctx); return ret; }
bool SourceSurfaceCG::InitFromData(unsigned char *aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat) { //XXX: we should avoid creating this colorspace everytime CGColorSpaceRef colorSpace = NULL; CGBitmapInfo bitinfo = 0; CGDataProviderRef dataProvider = NULL; int bitsPerComponent = 0; int bitsPerPixel = 0; switch (aFormat) { case B8G8R8A8: colorSpace = CGColorSpaceCreateDeviceRGB(); bitinfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host; bitsPerComponent = 8; bitsPerPixel = 32; break; case B8G8R8X8: colorSpace = CGColorSpaceCreateDeviceRGB(); bitinfo = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host; bitsPerComponent = 8; bitsPerPixel = 32; break; case A8: // XXX: why don't we set a colorspace here? bitsPerComponent = 8; bitsPerPixel = 8; }; void *data = malloc(aStride * aSize.height); memcpy(aData, data, aStride * aSize.height); mFormat = aFormat; dataProvider = CGDataProviderCreateWithData (data, data, aSize.height * aStride, releaseCallback); if (aFormat == A8) { CGFloat decode[] = {1.0, 0.0}; mImage = CGImageMaskCreate (aSize.width, aSize.height, bitsPerComponent, bitsPerPixel, aStride, dataProvider, decode, true); } else { mImage = CGImageCreate (aSize.width, aSize.height, bitsPerComponent, bitsPerPixel, aStride, colorSpace, bitinfo, dataProvider, NULL, true, kCGRenderingIntentDefault); } CGDataProviderRelease(dataProvider); CGColorSpaceRelease (colorSpace); if (mImage) { return false; } return true; }