Changeset 31246 in webkit
- Timestamp:
- Mar 24, 2008 10:55:58 AM (16 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r31245 r31246 1 2008-03-24 Dan Bernstein <mitz@apple.com> 2 3 Reviewed by Sam Weinig. 4 5 - fix <rdar://problem/5792582> CSS opacity does not work with GDI text 6 - fix <rdar://problem/5792619> non-opaque CSS colors do not work with GDI text (RGBA, HSLA) 7 - fix <rdar://problem/5792624> GDI text can't be stroked/filled independently 8 - make text-shadow work with GDI text 9 - make -webkit-background-clip: text work with GDI text 10 11 * platform/graphics/GraphicsContext.cpp: 12 (WebCore::GraphicsContext::setShadow): Made this a shared method that 13 updates the state and calls the platform-specific method. 14 (WebCore::GraphicsContext::clearShadow): Ditto. 15 (WebCore::GraphicsContext::getShadow): Added. 16 17 * platform/graphics/GraphicsContext.h: 18 (WebCore::GraphicsContext::WindowsBitmap): Added this class that 19 represents a bitmap with a Windows device context that GDI can draw into. 20 21 * platform/graphics/GraphicsContextPrivate.h: 22 (WebCore::GraphicsContextState::GraphicsContextState): Added the shadow 23 parameters to the graphics state. 24 25 * platform/graphics/cairo/GraphicsContextCairo.cpp: 26 (WebCore::GraphicsContext::setPlatformShadow): Renamed the platform- 27 specific implementation to this. 28 (WebCore::GraphicsContext::clearPlatformShadow): Renamed the platform- 29 specific implementation to this. 30 31 * platform/graphics/cg/GraphicsContextCG.cpp: 32 (WebCore::GraphicsContext::setPlatformShadow): Renamed the platform- 33 specific implementation to this. 34 (WebCore::GraphicsContext::clearPlatformShadow): Renamed the platform- 35 specific implementation to this. 36 37 * platform/graphics/qt/GraphicsContextQt.cpp: 38 (WebCore::GraphicsContext::setPlatformShadow): Renamed the platform- 39 specific implementation to this. 40 (WebCore::GraphicsContext::clearPlatformShadow): Renamed the platform- 41 specific implementation to this. 42 43 * platform/graphics/win/FontCGWin.cpp: 44 (WebCore::toCGFloat): Added. Converts a Windows FIXED. 45 (WebCore::createPathForGlyph): Added. Retrieves a glyph's hinted 46 outline from GDI and creates a CGPath containing it. 47 (WebCore::Font::drawGlyphs): Added two code paths in the GDI case. 48 The existing code path, which uses GDI to draw text directly to the 49 graphics context, is used for opaque-colored, non-transformed, 50 non-stroked, non-shadowed text in a GDI-backed graphics context that is 51 not in a transparency layer. 52 An additional code path is used for non-stroked text in all other cases. 53 It uses GDI to draw black text into an all-white Windows bitmap, then 54 uses the green channel as a mask to create a bitmap with the desired 55 fill color and alpha. The bitmap is then drawn into the graphics 56 context, at which time transparency layers, transforms and shadows are 57 handled properly. 58 A third code path is used for stroked text. It constructs a path from 59 hinted glyph outlines retrieved from GDI and strokes (and optionally 60 fills) it. 61 62 * platform/graphics/win/GraphicsContextCGWin.cpp: 63 (WebCore::GraphicsContext::getWindowsContext): Added a mayCreateBitmap 64 parameter. When false, prevents this method from creating a Windows 65 device context if the graphics context does not already have one. 66 (WebCore::GraphicsContext::releaseWindowsContext): Added a 67 mayCreateBitmap parameter to match getWindowsContext(). 68 (WebCore::GraphicsContext::WindowsBitmap::WindowsBitmap): 69 (WebCore::GraphicsContext::WindowsBitmap::~WindowsBitmap): 70 (WebCore::GraphicsContext::createWindowsBitmap): Added. 71 (WebCore::GraphicsContext::drawWindowsBitmap): Added. Draws the bitmap 72 as a non-alpha-premultiplied image. 73 1 74 2008-03-24 Kevin McCullough <kmccullough@apple.com> 2 75 -
trunk/WebCore/platform/graphics/GraphicsContext.cpp
r31200 r31246 138 138 } 139 139 140 void GraphicsContext::setShadow(const IntSize& size, int blur, const Color& color) 141 { 142 m_common->state.shadowSize = size; 143 m_common->state.shadowBlur = blur; 144 m_common->state.shadowColor = color; 145 setPlatformShadow(size, blur, color); 146 } 147 148 void GraphicsContext::clearShadow() 149 { 150 m_common->state.shadowSize = IntSize(); 151 m_common->state.shadowBlur = 0; 152 m_common->state.shadowColor = Color(); 153 clearPlatformShadow(); 154 } 155 156 void GraphicsContext::getShadow(IntSize& size, int& blur, Color& color) 157 { 158 size = m_common->state.shadowSize; 159 blur = m_common->state.shadowBlur; 160 color = m_common->state.shadowColor; 161 } 162 140 163 float GraphicsContext::strokeThickness() const 141 164 { -
trunk/WebCore/platform/graphics/GraphicsContext.h
r31200 r31246 192 192 193 193 void setShadow(const IntSize&, int blur, const Color&); 194 void getShadow(IntSize&, int&, Color&); 194 195 void clearShadow(); 195 196 … … 229 230 GraphicsContext(HDC); // FIXME: To be removed. 230 231 bool inTransparencyLayer() const; 231 HDC getWindowsContext(const IntRect&, bool supportAlphaBlend = true); // The passed in rect is used to create a bitmap for compositing inside transparency layers. 232 void releaseWindowsContext(HDC, const IntRect&, bool supportAlphaBlend = true); // The passed in HDC should be the one handed back by getWindowsContext. 232 HDC getWindowsContext(const IntRect&, bool supportAlphaBlend = true, bool mayCreateBitmap = true); // The passed in rect is used to create a bitmap for compositing inside transparency layers. 233 void releaseWindowsContext(HDC, const IntRect&, bool supportAlphaBlend = true, bool mayCreateBitmap = true); // The passed in HDC should be the one handed back by getWindowsContext. 234 235 class WindowsBitmap : public Noncopyable { 236 public: 237 WindowsBitmap(HDC, IntSize); 238 ~WindowsBitmap(); 239 240 HDC hdc() const { return m_hdc; } 241 UInt8* buffer() const { return m_bitmapBuffer; } 242 unsigned bufferLength() const { return m_bitmapBufferLength; } 243 IntSize size() const { return m_size; } 244 unsigned bytesPerRow() const { return m_bytesPerRow; } 245 246 private: 247 HDC m_hdc; 248 HBITMAP m_bitmap; 249 UInt8* m_bitmapBuffer; 250 unsigned m_bitmapBufferLength; 251 IntSize m_size; 252 unsigned m_bytesPerRow; 253 }; 254 255 WindowsBitmap* createWindowsBitmap(IntSize); 256 // The bitmap should be non-premultiplied. 257 void drawWindowsBitmap(WindowsBitmap*, const IntPoint&); 233 258 #endif 234 259 … … 254 279 void setPlatformFillColor(const Color&); 255 280 void setPlatformFont(const Font& font); 281 void setPlatformShadow(const IntSize&, int blur, const Color&); 282 void clearPlatformShadow(); 256 283 257 284 int focusRingWidth() const; -
trunk/WebCore/platform/graphics/GraphicsContextPrivate.h
r30933 r31246 39 39 , textDrawingMode(cTextFill) 40 40 , paintingDisabled(false) 41 , shadowBlur(0) 41 42 { 42 43 } … … 49 50 int textDrawingMode; 50 51 bool paintingDisabled; 52 IntSize shadowSize; 53 unsigned shadowBlur; 54 Color shadowColor; 51 55 }; 52 56 -
trunk/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
r30533 r31246 584 584 585 585 586 void GraphicsContext::set Shadow(IntSize const&, int, Color const&)586 void GraphicsContext::setPlatformShadow(IntSize const&, int, Color const&) 587 587 { 588 588 notImplemented(); 589 589 } 590 590 591 void GraphicsContext::clear Shadow()591 void GraphicsContext::clearPlatformShadow() 592 592 { 593 593 notImplemented(); -
trunk/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
r31200 r31246 514 514 } 515 515 516 void GraphicsContext::set Shadow(const IntSize& size, int blur, const Color& color)516 void GraphicsContext::setPlatformShadow(const IntSize& size, int blur, const Color& color) 517 517 { 518 518 // Extreme "blur" values can make text drawing crash or take crazy long times, so clamp … … 553 553 } 554 554 555 void GraphicsContext::clear Shadow()555 void GraphicsContext::clearPlatformShadow() 556 556 { 557 557 if (paintingDisabled()) -
trunk/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
r30337 r31246 600 600 } 601 601 602 void GraphicsContext::set Shadow(const IntSize& pos, int blur, const Color &color)602 void GraphicsContext::setPlatformShadow(const IntSize& pos, int blur, const Color &color) 603 603 { 604 604 if (paintingDisabled()) … … 611 611 } 612 612 613 void GraphicsContext::clear Shadow()613 void GraphicsContext::clearPlatformShadow() 614 614 { 615 615 if (paintingDisabled()) -
trunk/WebCore/platform/graphics/win/FontCGWin.cpp
r30056 r31246 27 27 #include "Font.h" 28 28 29 #include "AffineTransform.h" 30 #include "FloatConversion.h" 29 31 #include "GlyphBuffer.h" 30 32 #include "GraphicsContext.h" … … 40 42 const int syntheticObliqueAngle = 14; 41 43 44 static inline CGFloat toCGFloat(FIXED f) 45 { 46 return f.value + f.fract / CGFloat(65536.0); 47 } 48 49 static CGPathRef createPathForGlyph(HDC hdc, Glyph glyph) 50 { 51 CGMutablePathRef path = CGPathCreateMutable(); 52 53 static const MAT2 identity = { 0, 1, 0, 0, 0, 0, 0, 1 }; 54 GLYPHMETRICS glyphMetrics; 55 // GGO_NATIVE matches the outline perfectly when Windows font smoothing is off. 56 // GGO_NATIVE | GGO_UNHINTED does not match perfectly either when Windows font smoothing is on or off. 57 DWORD outlineLength = GetGlyphOutline(hdc, glyph, GGO_GLYPH_INDEX | GGO_NATIVE, &glyphMetrics, 0, 0, &identity); 58 ASSERT(outlineLength >= 0); 59 if (outlineLength < 0) 60 return path; 61 62 Vector<UInt8> outline(outlineLength); 63 GetGlyphOutline(hdc, glyph, GGO_GLYPH_INDEX | GGO_NATIVE, &glyphMetrics, outlineLength, outline.data(), &identity); 64 65 unsigned offset = 0; 66 while (offset < outlineLength) { 67 LPTTPOLYGONHEADER subpath = reinterpret_cast<LPTTPOLYGONHEADER>(outline.data() + offset); 68 ASSERT(subpath->dwType == TT_POLYGON_TYPE); 69 if (subpath->dwType != TT_POLYGON_TYPE) 70 return path; 71 72 CGPathMoveToPoint(path, 0, toCGFloat(subpath->pfxStart.x), toCGFloat(subpath->pfxStart.y)); 73 74 unsigned subpathOffset = sizeof(*subpath); 75 while (subpathOffset < subpath->cb) { 76 LPTTPOLYCURVE segment = reinterpret_cast<LPTTPOLYCURVE>(reinterpret_cast<UInt8*>(subpath) + subpathOffset); 77 switch (segment->wType) { 78 case TT_PRIM_LINE: 79 for (unsigned i = 0; i < segment->cpfx; i++) 80 CGPathAddLineToPoint(path, 0, toCGFloat(segment->apfx[i].x), toCGFloat(segment->apfx[i].y)); 81 break; 82 83 case TT_PRIM_QSPLINE: 84 for (unsigned i = 0; i < segment->cpfx; i++) { 85 CGFloat x = toCGFloat(segment->apfx[i].x); 86 CGFloat y = toCGFloat(segment->apfx[i].y); 87 CGFloat cpx; 88 CGFloat cpy; 89 90 if (i == segment->cpfx - 2) { 91 cpx = toCGFloat(segment->apfx[i + 1].x); 92 cpy = toCGFloat(segment->apfx[i + 1].y); 93 i++; 94 } else { 95 cpx = (toCGFloat(segment->apfx[i].x) + toCGFloat(segment->apfx[i + 1].x)) / 2; 96 cpy = (toCGFloat(segment->apfx[i].y) + toCGFloat(segment->apfx[i + 1].y)) / 2; 97 } 98 99 CGPathAddQuadCurveToPoint(path, 0, x, y, cpx, cpy); 100 } 101 break; 102 103 case TT_PRIM_CSPLINE: 104 for (unsigned i = 0; i < segment->cpfx; i += 3) { 105 CGFloat cp1x = toCGFloat(segment->apfx[i].x); 106 CGFloat cp1y = toCGFloat(segment->apfx[i].y); 107 CGFloat cp2x = toCGFloat(segment->apfx[i + 1].x); 108 CGFloat cp2y = toCGFloat(segment->apfx[i + 1].y); 109 CGFloat x = toCGFloat(segment->apfx[i + 2].x); 110 CGFloat y = toCGFloat(segment->apfx[i + 2].y); 111 112 CGPathAddCurveToPoint(path, 0, cp1x, cp1y, cp2x, cp2y, x, y); 113 } 114 break; 115 116 default: 117 ASSERT_NOT_REACHED(); 118 return path; 119 } 120 121 subpathOffset += sizeof(*segment) + (segment->cpfx - 1) * sizeof(segment->apfx[0]); 122 } 123 CGPathCloseSubpath(path); 124 offset += subpath->cb; 125 } 126 return path; 127 } 128 42 129 void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* font, const GlyphBuffer& glyphBuffer, 43 130 int from, int numGlyphs, const FloatPoint& point) const 44 131 { 45 132 if (font->m_font.useGDI()) { 46 // FIXME: Support alpha blending.47 // FIXME: Support text stroke/fill.48 // FIXME: Support text shadow.49 133 Color fillColor = graphicsContext->fillColor(); 50 if ( fillColor.alpha() == 0)134 if (!fillColor.alpha()) 51 135 return; 52 136 … … 59 143 } 60 144 61 // We put slop into this rect, since glyphs can overflow the ascent/descent bounds and the left/right edges. 62 int lineGap = font->lineGap(); 63 IntRect textRect(point.x() - lineGap, point.y() - font->ascent() - lineGap, totalWidth + 2 * lineGap, font->lineSpacing()); 64 HDC hdc = graphicsContext->getWindowsContext(textRect); 145 bool drawIntoBitmap = false; 146 int drawingMode = graphicsContext->textDrawingMode(); 147 if (drawingMode == cTextFill) { 148 drawIntoBitmap = fillColor.alpha() != 255 || graphicsContext->inTransparencyLayer(); 149 if (!drawIntoBitmap) { 150 IntSize size; 151 int blur; 152 Color color; 153 graphicsContext->getShadow(size, blur, color); 154 drawIntoBitmap = !size.isEmpty() || blur; 155 } 156 } 157 158 HDC hdc = 0; 159 OwnPtr<GraphicsContext::WindowsBitmap> bitmap; 160 IntRect textRect; 161 if (!drawIntoBitmap) 162 hdc = graphicsContext->getWindowsContext(textRect, true, false); 163 if (!hdc) { 164 drawIntoBitmap = true; 165 // We put slop into this rect, since glyphs can overflow the ascent/descent bounds and the left/right edges. 166 // FIXME: Can get glyphs' optical bounds (even from CG) to get this right. 167 // FIXME: Line gap does not make sense as a horizontal distance. 168 int lineGap = font->lineGap(); 169 textRect = IntRect(point.x() - lineGap, point.y() - font->ascent() - lineGap, totalWidth + 2 * lineGap, font->lineSpacing()); 170 bitmap.set(graphicsContext->createWindowsBitmap(textRect.size())); 171 memset(bitmap->buffer(), 255, bitmap->bufferLength()); 172 hdc = bitmap->hdc(); 173 174 XFORM xform; 175 xform.eM11 = 1.0f; 176 xform.eM12 = 0.0f; 177 xform.eM21 = 0.0f; 178 xform.eM22 = 1.0f; 179 xform.eDx = -textRect.x(); 180 xform.eDy = -textRect.y(); 181 SetWorldTransform(hdc, &xform); 182 } 183 65 184 SelectObject(hdc, font->m_font.hfont()); 66 185 67 186 // Set the correct color. 68 HDC textDrawingDC = hdc; 69 SetTextColor(hdc, RGB(fillColor.red(), fillColor.green(), fillColor.blue())); 187 if (drawIntoBitmap) 188 SetTextColor(hdc, RGB(0, 0, 0)); 189 else 190 SetTextColor(hdc, RGB(fillColor.red(), fillColor.green(), fillColor.blue())); 70 191 71 192 SetBkMode(hdc, TRANSPARENT); … … 84 205 ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY); 85 206 } 86 ExtTextOut(hdc, point.x(), point.y(), ETO_GLYPH_INDEX, 0, (WCHAR*)glyphBuffer.glyphs(from), numGlyphs, gdiAdvances.data()); 87 88 graphicsContext->releaseWindowsContext(hdc, textRect); 207 208 if (drawingMode == cTextFill) 209 ExtTextOut(hdc, point.x(), point.y(), ETO_GLYPH_INDEX, 0, (WCHAR*)glyphBuffer.glyphs(from), numGlyphs, gdiAdvances.data()); 210 else { 211 RetainPtr<CGMutablePathRef> path(AdoptCF, CGPathCreateMutable()); 212 213 XFORM xform; 214 GetWorldTransform(hdc, &xform); 215 AffineTransform hdcTransform(xform.eM11, xform.eM21, xform.eM12, xform.eM22, xform.eDx, xform.eDy); 216 CGAffineTransform initialGlyphTransform = hdcTransform.isInvertible() ? hdcTransform.inverse() : CGAffineTransformIdentity; 217 initialGlyphTransform.tx = 0; 218 initialGlyphTransform.ty = 0; 219 CGAffineTransform glyphTranslation = CGAffineTransformIdentity; 220 221 for (unsigned i = 0; i < numGlyphs; ++i) { 222 RetainPtr<CGPathRef> glyphPath(AdoptCF, createPathForGlyph(hdc, glyphBuffer.glyphAt(from + i))); 223 CGAffineTransform glyphTransform = CGAffineTransformConcat(initialGlyphTransform, glyphTranslation); 224 CGPathAddPath(path.get(), &glyphTransform, glyphPath.get()); 225 glyphTranslation = CGAffineTransformTranslate(glyphTranslation, gdiAdvances[i], 0); 226 } 227 228 CGContextRef cgContext = graphicsContext->platformContext(); 229 CGContextSaveGState(cgContext); 230 231 BOOL fontSmoothingEnabled = false; 232 SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &fontSmoothingEnabled, 0); 233 CGContextSetShouldAntialias(cgContext, fontSmoothingEnabled); 234 235 CGContextScaleCTM(cgContext, 1.0, -1.0); 236 CGContextTranslateCTM(cgContext, point.x() + glyphBuffer.offsetAt(from).width(), -(point.y() + glyphBuffer.offsetAt(from).height())); 237 238 if (drawingMode & cTextFill) { 239 CGContextAddPath(cgContext, path.get()); 240 CGContextFillPath(cgContext); 241 } 242 if (drawingMode & cTextStroke) { 243 CGContextAddPath(cgContext, path.get()); 244 CGContextStrokePath(cgContext); 245 } 246 CGContextRestoreGState(cgContext); 247 } 248 249 if (drawIntoBitmap) { 250 UInt8* buffer = bitmap->buffer(); 251 unsigned bufferLength = bitmap->bufferLength(); 252 for (unsigned i = 0; i < bufferLength; i += 4) { 253 // Use green, which is always in the middle. 254 UInt8 alpha = (255 - buffer[i + 1]) * fillColor.alpha() / 255; 255 buffer[i] = fillColor.blue(); 256 buffer[i + 1] = fillColor.green(); 257 buffer[i + 2] = fillColor.red(); 258 buffer[i + 3] = alpha; 259 } 260 graphicsContext->drawWindowsBitmap(bitmap.get(), textRect.topLeft()); 261 } else 262 graphicsContext->releaseWindowsContext(hdc, textRect, true, false); 263 89 264 return; 90 265 } -
trunk/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
r30533 r31246 77 77 bool GraphicsContext::inTransparencyLayer() const { return m_data->m_transparencyCount; } 78 78 79 HDC GraphicsContext::getWindowsContext(const IntRect& dstRect, bool supportAlphaBlend) 80 { 81 if (inTransparencyLayer()) { 79 // FIXME: Is it possible to merge getWindowsContext and createWindowsBitmap into a single API 80 // suitable for all clients? 81 HDC GraphicsContext::getWindowsContext(const IntRect& dstRect, bool supportAlphaBlend, bool mayCreateBitmap) 82 { 83 // FIXME: Should a bitmap be created also when a shadow is set? 84 if (mayCreateBitmap && inTransparencyLayer()) { 82 85 if (dstRect.isEmpty()) 83 86 return 0; … … 134 137 } 135 138 136 void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, bool supportAlphaBlend )137 { 138 if ( hdc && inTransparencyLayer()) {139 void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, bool supportAlphaBlend, bool mayCreateBitmap) 140 { 141 if (mayCreateBitmap && hdc && inTransparencyLayer()) { 139 142 if (dstRect.isEmpty()) 140 143 return; … … 167 170 168 171 m_data->restore(); 172 } 173 174 GraphicsContext::WindowsBitmap::WindowsBitmap(HDC hdc, IntSize size) 175 : m_hdc(0) 176 , m_size(size) 177 { 178 BITMAPINFO bitmapInfo; 179 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 180 bitmapInfo.bmiHeader.biWidth = m_size.width(); 181 bitmapInfo.bmiHeader.biHeight = m_size.height(); 182 bitmapInfo.bmiHeader.biPlanes = 1; 183 bitmapInfo.bmiHeader.biBitCount = 32; 184 bitmapInfo.bmiHeader.biCompression = BI_RGB; 185 bitmapInfo.bmiHeader.biSizeImage = 0; 186 bitmapInfo.bmiHeader.biXPelsPerMeter = 0; 187 bitmapInfo.bmiHeader.biYPelsPerMeter = 0; 188 bitmapInfo.bmiHeader.biClrUsed = 0; 189 bitmapInfo.bmiHeader.biClrImportant = 0; 190 191 m_bitmap = CreateDIBSection(0, &bitmapInfo, DIB_RGB_COLORS, reinterpret_cast<void**>(&m_bitmapBuffer), 0, 0); 192 if (!m_bitmap) 193 return; 194 195 m_hdc = CreateCompatibleDC(hdc); 196 SelectObject(m_hdc, m_bitmap); 197 198 BITMAP bmpInfo; 199 GetObject(m_bitmap, sizeof(bmpInfo), &bmpInfo); 200 m_bytesPerRow = bmpInfo.bmWidthBytes; 201 m_bitmapBufferLength = bmpInfo.bmWidthBytes * bmpInfo.bmHeight; 202 203 SetGraphicsMode(m_hdc, GM_ADVANCED); 204 } 205 206 GraphicsContext::WindowsBitmap::~WindowsBitmap() 207 { 208 if (!m_bitmap) 209 return; 210 211 DeleteDC(m_hdc); 212 DeleteObject(m_bitmap); 213 } 214 215 GraphicsContext::WindowsBitmap* GraphicsContext::createWindowsBitmap(IntSize size) 216 { 217 return new WindowsBitmap(m_data->m_hdc, size); 218 } 219 220 void GraphicsContext::drawWindowsBitmap(WindowsBitmap* image, const IntPoint& point) 221 { 222 RetainPtr<CGColorSpaceRef> deviceRGB(AdoptCF, CGColorSpaceCreateDeviceRGB()); 223 RetainPtr<CFDataRef> imageData(AdoptCF, CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, image->buffer(), image->bufferLength(), kCFAllocatorNull)); 224 RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateWithCFData(imageData.get())); 225 RetainPtr<CGImageRef> cgImage(AdoptCF, CGImageCreate(image->size().width(), image->size().height(), 8, 32, image->bytesPerRow(), deviceRGB.get(), 226 kCGBitmapByteOrder32Little | kCGImageAlphaFirst, dataProvider.get(), 0, true, kCGRenderingIntentDefault)); 227 CGContextDrawImage(m_data->m_cgContext, CGRectMake(point.x(), point.y(), image->size().width(), image->size().height()), cgImage.get()); 169 228 } 170 229
Note: See TracChangeset
for help on using the changeset viewer.