void doIndexedColorDrawGraphics(CGContextRef context) { CGColorSpaceRef theBaseRGBSpace = getTheCalibratedRGBColorSpace(); CGColorSpaceRef theIndexedSpace = NULL; unsigned char lookupTable[6]; float opaqueRed[] = { 0, 1 }; // index, alpha float aBlue[] = { 1, 1 }; // index, alpha // Set the first 3 values in the lookup table to a red of // 169/255 = 0.663, no green, and blue = 8/255 = 0.031. This makes // the first entry in the lookup table a shade of red. lookupTable[0] = 169; lookupTable[1] = 0; lookupTable[2] = 8; // Set the second 3 values in the lookup table to a red value // of 123/255 = 0.482, a green value of 158/255 = 0.62, and // a blue value of 222/255 = 0.871. This makes the second entry // in the lookup table a shade of blue. lookupTable[3] = 123; lookupTable[4] = 158; lookupTable[5] = 222; // Create the indexed color space with this color lookup table, // using the RGB color space as the base color space and a 2 element // color lookup table to characterize the indexed color space. theIndexedSpace = CGColorSpaceCreateIndexed(theBaseRGBSpace, 1, lookupTable); if(theIndexedSpace != NULL){ CGContextSetStrokeColorSpace(context, theIndexedSpace); CGContextSetFillColorSpace(context, theIndexedSpace); // Release the color space this code created since it is no // longer needed in this routine. CGColorSpaceRelease(theIndexedSpace); // Set the stroke color to an opaque blue. CGContextSetStrokeColor(context, aBlue); // Set the fill color to an opaque red. CGContextSetFillColor(context, opaqueRed); CGContextSetLineWidth(context, 8.); // Draw the first rectangle. CGContextBeginPath(context); CGContextAddRect(context, CGRectMake(20., 20., 100., 100.)); CGContextDrawPath(context, kCGPathFillStroke); // Continue to use the stroke colorspace already set // but change the stroke alpha value to a semitransparent value // while leaving the index value unchanged. aBlue[1] = 0.5; CGContextSetStrokeColor(context, aBlue); // Draw another rectangle to the right of the first one. CGContextBeginPath(context); CGContextAddRect(context, CGRectMake(140., 20., 100., 100.)); CGContextDrawPath(context, kCGPathFillStroke); }else fprintf(stderr, "Couldn't make the indexed color space!\n"); }
void GraphicsContext::addRoundedRectClip(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight) { if (paintingDisabled()) return; // Need sufficient width and height to contain these curves. Sanity check our // corner radii and our width/height values to make sure the curves can all fit. if (static_cast<unsigned>(rect.width()) < static_cast<unsigned>(topLeft.width()) + static_cast<unsigned>(topRight.width()) || static_cast<unsigned>(rect.width()) < static_cast<unsigned>(bottomLeft.width()) + static_cast<unsigned>(bottomRight.width()) || static_cast<unsigned>(rect.height()) < static_cast<unsigned>(topLeft.height()) + static_cast<unsigned>(bottomLeft.height()) || static_cast<unsigned>(rect.height()) < static_cast<unsigned>(topRight.height()) + static_cast<unsigned>(bottomRight.height())) return; // Clip to our rect. clip(rect); // OK, the curves can fit. CGContextRef context = platformContext(); // Add the four ellipses to the path. Technically this really isn't good enough, since we could end up // not clipping the other 3/4 of the ellipse we don't care about. We're relying on the fact that for // normal use cases these ellipses won't overlap one another (or when they do the curvature of one will // be subsumed by the other). CGContextAddEllipseInRect(context, CGRectMake(rect.x(), rect.y(), topLeft.width() * 2, topLeft.height() * 2)); CGContextAddEllipseInRect(context, CGRectMake(rect.right() - topRight.width() * 2, rect.y(), topRight.width() * 2, topRight.height() * 2)); CGContextAddEllipseInRect(context, CGRectMake(rect.x(), rect.bottom() - bottomLeft.height() * 2, bottomLeft.width() * 2, bottomLeft.height() * 2)); CGContextAddEllipseInRect(context, CGRectMake(rect.right() - bottomRight.width() * 2, rect.bottom() - bottomRight.height() * 2, bottomRight.width() * 2, bottomRight.height() * 2)); // Now add five rects (one for each edge rect in between the rounded corners and one for the interior). CGContextAddRect(context, CGRectMake(rect.x() + topLeft.width(), rect.y(), rect.width() - topLeft.width() - topRight.width(), max(topLeft.height(), topRight.height()))); CGContextAddRect(context, CGRectMake(rect.x() + bottomLeft.width(), rect.bottom() - max(bottomLeft.height(), bottomRight.height()), rect.width() - bottomLeft.width() - bottomRight.width(), max(bottomLeft.height(), bottomRight.height()))); CGContextAddRect(context, CGRectMake(rect.x(), rect.y() + topLeft.height(), max(topLeft.width(), bottomLeft.width()), rect.height() - topLeft.height() - bottomLeft.height())); CGContextAddRect(context, CGRectMake(rect.right() - max(topRight.width(), bottomRight.width()), rect.y() + topRight.height(), max(topRight.width(), bottomRight.width()), rect.height() - topRight.height() - bottomRight.height())); CGContextAddRect(context, CGRectMake(rect.x() + max(topLeft.width(), bottomLeft.width()), rect.y() + max(topLeft.height(), topRight.height()), rect.width() - max(topLeft.width(), bottomLeft.width()) - max(topRight.width(), bottomRight.width()), rect.height() - max(topLeft.height(), topRight.height()) - max(bottomLeft.height(), bottomRight.height()))); CGContextClip(context); }
static void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight) { float fw, fh; // If either ovalWidth or ovalHeight is 0, draw a regular rectangle. if (ovalWidth == 0 || ovalHeight == 0) { CGContextAddRect(context, rect); }else{ CGContextSaveGState(context); // Translate to lower-left corner of rectangle. CGContextTranslateCTM(context, CGRectGetMinX(rect), CGRectGetMinY(rect)); // Scale by the oval width and height so that // each rounded corner is 0.5 units in radius. CGContextScaleCTM(context, ovalWidth, ovalHeight); // Unscale the rectangle width by the amount of the X scaling. fw = CGRectGetWidth(rect) / ovalWidth; // Unscale the rectangle height by the amount of the Y scaling. fh = CGRectGetHeight(rect) / ovalHeight; // Start at the right edge of the rect, at the midpoint in Y. CGContextMoveToPoint(context, fw, fh/2); // Segment 1 CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 0.5); // Segment 2 CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 0.5); // Segment 3 CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 0.5); // Segment 4 CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 0.5); // Closing the path adds the last segment. CGContextClosePath(context); CGContextRestoreGState(context); } }
static void AddRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight) { float fw, fh; if (ovalWidth == 0 || ovalHeight == 0) { CGContextAddRect(context, rect); return; } CGContextSaveGState(context); CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect)); CGContextScaleCTM (context, ovalWidth, ovalHeight); fw = CGRectGetWidth (rect) / ovalWidth; fh = CGRectGetHeight (rect) / ovalHeight; CGContextMoveToPoint(context, fw, fh / 2); CGContextAddArcToPoint(context, fw, fh, fw / 2, fh, 1); CGContextAddArcToPoint(context, 0, fh, 0, fh / 2, 1); CGContextAddArcToPoint(context, 0, 0, fw / 2, 0, 1); CGContextAddArcToPoint(context, fw, 0, fw, fh / 2, 1); CGContextClosePath(context); CGContextRestoreGState(context); }
//----------------------------------------------------------------------------- void CGDrawContext::drawRect (const CRect &rect, const CDrawStyle drawStyle) { CGContextRef context = beginCGContext (true, currentState.drawMode.integralMode ()); if (context) { CGPathDrawingMode m; switch (drawStyle) { case kDrawFilled : m = kCGPathFill; break; case kDrawFilledAndStroked : m = kCGPathFillStroke; break; default : m = kCGPathStroke; break; } applyLineStyle (context); CGRect r; if (currentState.drawMode.integralMode ()) { r = CGRectMake (round (rect.left), round (rect.top + 1), round (rect.width () - 1), round (rect.height () - 1)); } else { r = CGRectMake (rect.left, rect.top + 1, rect.width () - 1, rect.height () - 1); } if ((((int32_t)currentState.frameWidth) % 2)) CGContextTranslateCTM (context, 0.5f, -0.5f); CGContextBeginPath (context); CGContextAddRect (context, r); CGContextDrawPath (context, m); releaseCGContext (context); } }
void drawRoundedRect(CGContextRef context, int x, int y){ struct CGRect cgRect; struct CGPoint cgPoint; cgRect.size.width = 640; cgRect.size.height = y+30; cgPoint.x = 0; cgPoint.y = 5; cgRect.origin = cgPoint; //printf("Drawing %f, %f, %f, %f", cgPoint.x, cgPoint.y, cgRect.size.width, cgRect.size.height); CGContextBeginPath(context); float ovalWidth = 10; float ovalHeight = 10; float fw, fh; // If the width or height of the corner oval is zero, then it reduces to a right angle, // so instead of a rounded rectangle we have an ordinary one. if (ovalWidth == 0 || ovalHeight == 0) { CGContextAddRect(context, cgRect); return; } // Save the context's state so that the translate and scale can be undone with a call // to CGContextRestoreGState. CGContextSaveGState(context); // Translate the origin of the contex to the lower left corner of the rectangle. CGContextTranslateCTM(context, CGRectGetMinX(cgRect), CGRectGetMinY(cgRect)); //Normalize the scale of the context so that the width and height of the arcs are 1.0 CGContextScaleCTM(context, ovalWidth, ovalHeight); // Calculate the width and height of the rectangle in the new coordinate system. fw = CGRectGetWidth(cgRect) / ovalWidth; fh = CGRectGetHeight(cgRect) / ovalHeight; // CGContextAddArcToPoint adds an arc of a circle to the context's path (creating the rounded // corners). It also adds a line from the path's last point to the begining of the arc, making // the sides of the rectangle. CGContextMoveToPoint(context, fw, fh/2); // Start at lower right corner CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1); // Top right corner CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1); // Top left corner CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1); // Lower left corner CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1); // Back to lower right // Close the path CGContextClosePath(context); CGContextSetRGBFillColor (context, 1, 1, 1, 0.7); CGContextFillPath(context); CGContextRestoreGState(context); }
//----------------------------------------------------------------------------- void CGDrawContext::drawRect (const CRect &rect, const CDrawStyle drawStyle) { CGContextRef context = beginCGContext (true, getDrawMode ().integralMode ()); if (context) { CGRect r = CGRectMake (static_cast<CGFloat> (rect.left), static_cast<CGFloat> (rect.top + 1), static_cast<CGFloat> (rect.getWidth () - 1), static_cast<CGFloat> (rect.getHeight () - 1)); CGPathDrawingMode m; switch (drawStyle) { case kDrawFilled : m = kCGPathFill; break; case kDrawFilledAndStroked : m = kCGPathFillStroke; break; default : m = kCGPathStroke; break; } applyLineStyle (context); if (getDrawMode ().integralMode ()) { r = pixelAlligned (r); applyLineWidthCTM (context); } CGContextBeginPath (context); CGContextAddRect (context, r); CGContextDrawPath (context, m); releaseCGContext (context); } }
void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color) { if (paintingDisabled() || !color.alpha()) return; CGContextRef context = platformContext(); Color oldFillColor = fillColor(); if (oldFillColor != color) setCGFillColor(context, color); // Add the four ellipses to the path. Technically this really isn't good enough, since we could end up // not clipping the other 3/4 of the ellipse we don't care about. We're relying on the fact that for // normal use cases these ellipses won't overlap one another (or when they do the curvature of one will // be subsumed by the other). CGContextAddEllipseInRect(context, CGRectMake(rect.x(), rect.y(), topLeft.width() * 2, topLeft.height() * 2)); CGContextAddEllipseInRect(context, CGRectMake(rect.right() - topRight.width() * 2, rect.y(), topRight.width() * 2, topRight.height() * 2)); CGContextAddEllipseInRect(context, CGRectMake(rect.x(), rect.bottom() - bottomLeft.height() * 2, bottomLeft.width() * 2, bottomLeft.height() * 2)); CGContextAddEllipseInRect(context, CGRectMake(rect.right() - bottomRight.width() * 2, rect.bottom() - bottomRight.height() * 2, bottomRight.width() * 2, bottomRight.height() * 2)); // Now add five rects (one for each edge rect in between the rounded corners and one for the interior). CGContextAddRect(context, CGRectMake(rect.x() + topLeft.width(), rect.y(), rect.width() - topLeft.width() - topRight.width(), max(topLeft.height(), topRight.height()))); CGContextAddRect(context, CGRectMake(rect.x() + bottomLeft.width(), rect.bottom() - max(bottomLeft.height(), bottomRight.height()), rect.width() - bottomLeft.width() - bottomRight.width(), max(bottomLeft.height(), bottomRight.height()))); CGContextAddRect(context, CGRectMake(rect.x(), rect.y() + topLeft.height(), max(topLeft.width(), bottomLeft.width()), rect.height() - topLeft.height() - bottomLeft.height())); CGContextAddRect(context, CGRectMake(rect.right() - max(topRight.width(), bottomRight.width()), rect.y() + topRight.height(), max(topRight.width(), bottomRight.width()), rect.height() - topRight.height() - bottomRight.height())); CGContextAddRect(context, CGRectMake(rect.x() + max(topLeft.width(), bottomLeft.width()), rect.y() + max(topLeft.height(), topRight.height()), rect.width() - max(topLeft.width(), bottomLeft.width()) - max(topRight.width(), bottomRight.width()), rect.height() - max(topLeft.height(), topRight.height()) - max(bottomLeft.height(), bottomRight.height()))); CGContextFillPath(context); if (oldFillColor != color) setCGFillColor(context, oldFillColor); }
void drawWithColorRefs(CGContextRef context) { static CGColorRef opaqueRedColor = NULL, opaqueBlueColor = NULL, transparentBlueColor = NULL; // Initialize the CGColorRefs if necessary if(opaqueRedColor == NULL){ // Initialize the color array to an opaque red // in the generic calibrated RGB color space. float color[4] = { 0.663, 0.0, 0.031, 1.0 }; CGColorSpaceRef theColorSpace = getTheCalibratedRGBColorSpace(); // Create a CGColorRef for opaque red. opaqueRedColor = CGColorCreate(theColorSpace, color); // Make the color array correspond to an opaque blue color. color[0] = 0.482; color[1] = 0.62; color[2] = 0.871; // Create another CGColorRef for opaque blue. opaqueBlueColor = CGColorCreate(theColorSpace, color); // Create a new CGColorRef from the opaqueBlue CGColorRef // but with a different alpha value. transparentBlueColor = CGColorCreateCopyWithAlpha(opaqueBlueColor, 0.5); if(!(opaqueRedColor && opaqueBlueColor && transparentBlueColor)){ fprintf(stderr, "Couldn't create one of the CGColorRefs!!!\n"); return; } } // Set the fill color to the opaque red CGColor object. CGContextSetFillColorWithColor(context, opaqueRedColor); // Set the stroke color to the opaque blue CGColor object. CGContextSetStrokeColorWithColor(context, opaqueBlueColor); CGContextSetLineWidth(context, 8.); // Draw the first rectangle. CGContextBeginPath(context); CGContextAddRect(context, CGRectMake(20., 20., 100., 100.)); CGContextDrawPath(context, kCGPathFillStroke); // Set the stroke color to be that of the transparent blue // CGColor object. CGContextSetStrokeColorWithColor(context, transparentBlueColor); // Draw a second rectangle to the right of the first one. CGContextBeginPath(context); CGContextAddRect(context, CGRectMake(140., 20., 100., 100.)); CGContextDrawPath(context, kCGPathFillStroke); }
void GraphicsContext::clipOutEllipseInRect(const IntRect& rect) { if (paintingDisabled()) return; CGContextBeginPath(platformContext()); CGContextAddRect(platformContext(), CGContextGetClipBoundingBox(platformContext())); CGContextAddEllipseInRect(platformContext(), rect); CGContextEOClip(platformContext()); }
void GraphicsContext::clipOut(const Path& path) { if (paintingDisabled()) return; CGContextBeginPath(platformContext()); CGContextAddRect(platformContext(), CGContextGetClipBoundingBox(platformContext())); CGContextAddPath(platformContext(), path.platformPath()); CGContextEOClip(platformContext()); }
void doColorSpaceFillAndStroke(CGContextRef context) { CGColorSpaceRef theColorSpace = getTheCalibratedRGBColorSpace(); float opaqueRed[] = { 0.663, 0.0, 0.031, 1.0 }; // red,green,blue,alpha float aBlue[] = { 0.482, 0.62, 0.871, 1.0 }; // red,green,blue,alpha // Set the fill color space to be the generic calibrated RGB color space. CGContextSetFillColorSpace(context, theColorSpace); // Set the fill color to opaque red. The number of elements in the // array passed to this function must be the number of color // components in the current fill color space plus 1 for alpha. CGContextSetFillColor(context, opaqueRed); // Set the stroke color space to be the generic calibrated RGB color space. CGContextSetStrokeColorSpace(context, theColorSpace); // Set the stroke color to opaque blue. The number of elements // in the array passed to this function must be the number of color // components in the current stroke color space plus 1 for alpha. CGContextSetStrokeColor(context, aBlue); CGContextSetLineWidth(context, 8.); // Rectangle 1. CGContextBeginPath(context); CGContextAddRect(context, CGRectMake(20., 20., 100., 100.)); CGContextDrawPath(context, kCGPathFillStroke); // Continue to use the stroke colorspace already set // but change the stroke alpha value to a semitransparent blue. aBlue[3] = 0.5; CGContextSetStrokeColor(context, aBlue); // Rectangle 2. CGContextBeginPath(context); CGContextAddRect(context, CGRectMake(140., 20., 100., 100.)); CGContextDrawPath(context, kCGPathFillStroke); // Don't release the color space since this routine // didn't create it. }
void QMacWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &offset) { Q_UNUSED(offset); // Get a context for the widget. #ifndef QT_MAC_USE_COCOA CGContextRef context; CGrafPtr port = GetWindowPort(qt_mac_window_for(widget)); QDBeginCGContext(port, &context); #else extern CGContextRef qt_mac_graphicsContextFor(QWidget *); CGContextRef context = qt_mac_graphicsContextFor(widget); #endif CGContextRetain(context); CGContextSaveGState(context); // Flip context. CGContextTranslateCTM(context, 0, widget->height()); CGContextScaleCTM(context, 1, -1); // Clip to region. const QVector<QRect> &rects = rgn.rects(); for (int i = 0; i < rects.size(); ++i) { const QRect &rect = rects.at(i); CGContextAddRect(context, CGRectMake(rect.x(), rect.y(), rect.width(), rect.height())); } CGContextClip(context); // Draw the image onto the window. const CGRect dest = CGRectMake(0, 0, widget->width(), widget->height()); const CGImageRef image = d_ptr->device.toMacCGImageRef(); qt_mac_drawCGImage(context, &dest, image); CFRelease(image); // Restore context. CGContextRestoreGState(context); #ifndef QT_MAC_USE_COCOA QDEndCGContext(port, &context); #else CGContextFlush(context); #endif CGContextRelease(context); }
static void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight) { float fw, fh; // If the width or height of the corner oval is zero, then it reduces to a right angle, // so instead of a rounded rectangle we have an ordinary one. if (ovalWidth == 0 || ovalHeight == 0) { CGContextAddRect(context, rect); return; } // Save the context's state so that the translate and scale can be undone with a call // to CGContextRestoreGState. CGContextSaveGState(context); // Translate the origin of the contex to the lower left corner of the rectangle. CGContextTranslateCTM(context, CGRectGetMinX(rect), CGRectGetMinY(rect)); //Normalize the scale of the context so that the width and height of the arcs are 1.0 CGContextScaleCTM(context, ovalWidth, ovalHeight); // Calculate the width and height of the rectangle in the new coordinate system. fw = CGRectGetWidth(rect) / ovalWidth; fh = CGRectGetHeight(rect) / ovalHeight; // CGContextAddArcToPoint adds an arc of a circle to the context's path (creating the rounded // corners). It also adds a line from the path's last point to the begining of the arc, making // the sides of the rectangle. CGContextMoveToPoint(context, fw, fh/2); // Start at lower right corner CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1); // Top right corner CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1); // Top left corner CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1); // Lower left corner CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1); // Back to lower right // Close the path CGContextClosePath(context); // Restore the context's state. This removes the translation and scaling // but leaves the path, since the path is not part of the graphics state. CGContextRestoreGState(context); }
void GraphicsContext::strokeRect(const FloatRect& r, float lineWidth) { if (paintingDisabled()) return; CGContextRef context = platformContext(); if (m_state.strokeGradient) { CGContextSaveGState(context); setStrokeThickness(lineWidth); CGContextAddRect(context, r); CGContextReplacePathWithStrokedPath(context); CGContextClip(context); m_state.strokeGradient->paint(this); CGContextRestoreGState(context); return; } if (m_state.strokePattern) applyStrokePattern(); CGContextStrokeRectWithWidth(context, r, lineWidth); }
static pascal OSStatus MultiCartPaneEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData) { OSStatus err, result = eventNotHandledErr; HIViewRef view; DragRef drag; PasteboardRef pasteboard; PasteboardItemID itemID; CFArrayRef array; CFStringRef flavorType; CFIndex numFlavors; ItemCount numItems; int index = *((int *) inUserData); switch (GetEventClass(inEvent)) { case kEventClassControl: { switch (GetEventKind(inEvent)) { case kEventControlDraw: { err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &view); if (err == noErr) { CGContextRef ctx; err = GetEventParameter(inEvent, kEventParamCGContextRef, typeCGContextRef, NULL, sizeof(CGContextRef), NULL, &ctx); if (err == noErr) { HIThemeFrameDrawInfo info; HIRect bounds, frame; HIViewGetBounds(view, &bounds); CGContextSetRGBFillColor(ctx, 1.0f, 1.0f, 1.0f, 1.0f); CGContextFillRect(ctx, bounds); info.version = 0; info.kind = kHIThemeFrameTextFieldSquare; info.state = kThemeStateInactive; info.isFocused = false; err = HIThemeDrawFrame(&bounds, &info, ctx, kHIThemeOrientationNormal); if (multiCartDragHilite == index && systemVersion >= 0x1040) { err = HIThemeSetStroke(kThemeBrushDragHilite, NULL, ctx, kHIThemeOrientationNormal); frame = CGRectInset(bounds, 1, 1); CGContextBeginPath(ctx); CGContextAddRect(ctx, frame); CGContextStrokePath(ctx); } } } result = noErr; break; } case kEventControlDragEnter: { err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &view); if (err == noErr) { err = GetEventParameter(inEvent, kEventParamDragRef, typeDragRef, NULL, sizeof(DragRef), NULL, &drag); if (err == noErr) { err = GetDragPasteboard(drag, &pasteboard); if (err == noErr) { err = PasteboardGetItemCount(pasteboard, &numItems); if (err == noErr && numItems == 1) { err = PasteboardGetItemIdentifier(pasteboard, 1, &itemID); if (err == noErr) { err = PasteboardCopyItemFlavors(pasteboard, itemID, &array); if (err == noErr) { numFlavors = CFArrayGetCount(array); for (CFIndex i = 0; i < numFlavors; i++) { flavorType = (CFStringRef) CFArrayGetValueAtIndex(array, i); if (UTTypeConformsTo(flavorType, CFSTR("public.file-url"))) { Boolean accept = true; err = SetEventParameter(inEvent, kEventParamControlWouldAcceptDrop, typeBoolean, sizeof(Boolean), &accept); if (err == noErr) { multiCartDragHilite = index; HIViewSetNeedsDisplay(view, true); result = noErr; } } } CFRelease(array); } } } } } } break; } case kEventControlDragWithin: { result = noErr; break; } case kEventControlDragLeave: { err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &view); if (err == noErr) { multiCartDragHilite = -1; HIViewSetNeedsDisplay(view, true); } result = noErr; break; } case kEventControlDragReceive: { err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &view); if (err == noErr) { err = GetEventParameter(inEvent, kEventParamDragRef, typeDragRef, NULL, sizeof(DragRef), NULL, &drag); if (err == noErr) { multiCartDragHilite = -1; HIViewSetNeedsDisplay(view, true); err = GetDragPasteboard(drag, &pasteboard); if (err == noErr) { err = PasteboardGetItemIdentifier(pasteboard, 1, &itemID); if (err == noErr) { err = PasteboardCopyItemFlavors(pasteboard, itemID, &array); if (err == noErr) { numFlavors = CFArrayGetCount(array); for (CFIndex i = 0; i < numFlavors; i++) { flavorType = (CFStringRef) CFArrayGetValueAtIndex(array, i); if (UTTypeConformsTo(flavorType, CFSTR("public.file-url"))) { CFDataRef flavorData; err = PasteboardCopyItemFlavorData(pasteboard, itemID, flavorType, &flavorData); if (err == noErr) { CFIndex dataSize; UInt8 *data; dataSize = CFDataGetLength(flavorData); data = (UInt8 *) malloc(dataSize); if (data) { CFDataGetBytes(flavorData, CFRangeMake(0, dataSize), data); HIViewRef ctl; HIViewID cid; CFStringRef str; CFURLRef url; GetControlID(view, &cid); cid.signature = 'MNAM'; HIViewFindByID(view, cid, &ctl); url = CFURLCreateWithBytes(kCFAllocatorDefault, data, dataSize, kCFStringEncodingUTF8, NULL); str = CFURLCopyLastPathComponent(url); SetStaticTextCFString(ctl, str, true); CFRelease(str); str = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle); if (multiCartPath[cid.id]) CFRelease(multiCartPath[cid.id]); multiCartPath[cid.id] = str; CFRelease(url); result = noErr; free(data); } CFRelease(flavorData); } } } CFRelease(array); } } } } } } } } } return (result); }
void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &offset) { Q_D(QRasterWindowSurface); // Not ready for painting yet, bail out. This can happen in // QWidget::create_sys() if (!d->image || rgn.rectCount() == 0) return; #ifdef Q_WS_WIN QRect br = rgn.boundingRect(); if (!qt_widget_private(window())->isOpaque && window()->testAttribute(Qt::WA_TranslucentBackground) && (qt_widget_private(window())->data.window_flags & Qt::FramelessWindowHint)) { QRect r = window()->frameGeometry(); QPoint frameOffset = qt_widget_private(window())->frameStrut().topLeft(); QRect dirtyRect = br.translated(offset + frameOffset); SIZE size = {r.width(), r.height()}; POINT ptDst = {r.x(), r.y()}; POINT ptSrc = {0, 0}; BLENDFUNCTION blend = {AC_SRC_OVER, 0, (BYTE)(255.0 * window()->windowOpacity()), Q_AC_SRC_ALPHA}; RECT dirty = {dirtyRect.x(), dirtyRect.y(), dirtyRect.x() + dirtyRect.width(), dirtyRect.y() + dirtyRect.height()}; Q_UPDATELAYEREDWINDOWINFO info = {sizeof(info), NULL, &ptDst, &size, d->image->hdc, &ptSrc, 0, &blend, Q_ULW_ALPHA, &dirty}; ptrUpdateLayeredWindowIndirect(window()->internalWinId(), &info); } else { QPoint wOffset = qt_qwidget_data(widget)->wrect.topLeft(); HDC widget_dc = widget->getDC(); QRect wbr = br.translated(-wOffset); BitBlt(widget_dc, wbr.x(), wbr.y(), wbr.width(), wbr.height(), d->image->hdc, br.x() + offset.x(), br.y() + offset.y(), SRCCOPY); widget->releaseDC(widget_dc); } #ifndef QT_NO_DEBUG static bool flush = !qgetenv("QT_FLUSH_WINDOWSURFACE").isEmpty(); if (flush) { SelectObject(qt_win_display_dc(), GetStockObject(BLACK_BRUSH)); Rectangle(qt_win_display_dc(), 0, 0, d->image->width() + 2, d->image->height() + 2); BitBlt(qt_win_display_dc(), 1, 1, d->image->width(), d->image->height(), d->image->hdc, 0, 0, SRCCOPY); } #endif #endif #ifdef Q_WS_X11 extern void *qt_getClipRects(const QRegion &r, int &num); // in qpaintengine_x11.cpp extern QWidgetData* qt_widget_data(QWidget *); QPoint wOffset = qt_qwidget_data(widget)->wrect.topLeft(); if (widget->window() != window()) { XFreeGC(X11->display, d_ptr->gc); d_ptr->gc = XCreateGC(X11->display, widget->handle(), 0, 0); } QRegion wrgn(rgn); if (!wOffset.isNull()) wrgn.translate(-wOffset); if (wrgn.rectCount() != 1) { int num; XRectangle *rects = (XRectangle *)qt_getClipRects(wrgn, num); XSetClipRectangles(X11->display, d_ptr->gc, 0, 0, rects, num, YXBanded); } QPoint widgetOffset = offset + wOffset; QRect clipRect = widget->rect().translated(widgetOffset).intersected(d_ptr->image->image.rect()); QRect br = rgn.boundingRect().translated(offset).intersected(clipRect); QPoint wpos = br.topLeft() - widgetOffset; #ifndef QT_NO_MITSHM if (d_ptr->image->xshmpm) { XCopyArea(X11->display, d_ptr->image->xshmpm, widget->handle(), d_ptr->gc, br.x(), br.y(), br.width(), br.height(), wpos.x(), wpos.y()); d_ptr->needsSync = true; } else if (d_ptr->image->xshmimg) { XShmPutImage(X11->display, widget->handle(), d_ptr->gc, d_ptr->image->xshmimg, br.x(), br.y(), wpos.x(), wpos.y(), br.width(), br.height(), False); d_ptr->needsSync = true; } else #endif { int depth = widget->x11Info().depth(); const QImage &src = d->image->image; if (src.format() != QImage::Format_RGB32 || depth < 24 || X11->bppForDepth.value(depth) != 32) { Q_ASSERT(src.depth() >= 16); const QImage sub_src(src.scanLine(br.y()) + br.x() * (uint(src.depth()) / 8), br.width(), br.height(), src.bytesPerLine(), src.format()); QX11PixmapData *data = new QX11PixmapData(QPixmapData::PixmapType); data->xinfo = widget->x11Info(); data->fromImage(sub_src, Qt::NoOpaqueDetection); QPixmap pm = QPixmap(data); XCopyArea(X11->display, pm.handle(), widget->handle(), d_ptr->gc, 0 , 0 , br.width(), br.height(), wpos.x(), wpos.y()); } else { // qpaintengine_x11.cpp extern void qt_x11_drawImage(const QRect &rect, const QPoint &pos, const QImage &image, Drawable hd, GC gc, Display *dpy, Visual *visual, int depth); qt_x11_drawImage(br, wpos, src, widget->handle(), d_ptr->gc, X11->display, (Visual *)widget->x11Info().visual(), depth); } } if (wrgn.rectCount() != 1) XSetClipMask(X11->display, d_ptr->gc, XNone); #endif // FALCON #ifdef Q_WS_MAC Q_UNUSED(offset); // This is mainly done for native components like native "open file" dialog. if (widget->testAttribute(Qt::WA_DontShowOnScreen)) { return; } #ifdef QT_MAC_USE_COCOA this->needsFlush = true; this->regionToFlush += rgn; // The actual flushing will be processed in [view drawRect:rect] qt_mac_setNeedsDisplay(widget); #else // Get a context for the widget. CGContextRef context; CGrafPtr port = GetWindowPort(qt_mac_window_for(widget)); QDBeginCGContext(port, &context); CGContextRetain(context); CGContextSaveGState(context); // Flip context. CGContextTranslateCTM(context, 0, widget->height()); CGContextScaleCTM(context, 1, -1); // Clip to region. const QVector<QRect> &rects = rgn.rects(); for (int i = 0; i < rects.size(); ++i) { const QRect &rect = rects.at(i); CGContextAddRect(context, CGRectMake(rect.x(), rect.y(), rect.width(), rect.height())); } CGContextClip(context); QRect r = rgn.boundingRect().intersected(d->image->image.rect()); const CGRect area = CGRectMake(r.x(), r.y(), r.width(), r.height()); CGImageRef image = CGBitmapContextCreateImage(d->image->cg); CGImageRef subImage = CGImageCreateWithImageInRect(image, area); qt_mac_drawCGImage(context, &area, subImage); CGImageRelease(subImage); CGImageRelease(image); QDEndCGContext(port, &context); // Restore context. CGContextRestoreGState(context); CGContextRelease(context); #endif // QT_MAC_USE_COCOA #endif // Q_WS_MAC }
FX_BOOL CFX_QuartzDeviceDriver::SetDIBits(const CFX_DIBSource* pBitmap, FX_ARGB argb, const FX_RECT* srcRect, int dest_left, int dest_top, int blendType, int alphaFlag , void* iccTransform ) { SaveState(); CGFloat src_left, src_top, src_width, src_height; if (srcRect) { src_left = srcRect->left; src_top = srcRect->top; src_width = srcRect->Width(); src_height = srcRect->Height(); } else { src_left = src_top = 0; src_width = pBitmap->GetWidth(); src_height = pBitmap->GetHeight(); } CGAffineTransform ctm = CGContextGetCTM(_context); CGFloat scale_x = FXSYS_fabs(ctm.a); CGFloat scale_y = FXSYS_fabs(ctm.d); src_left /= scale_x; src_top /= scale_y; src_width /= scale_x; src_height /= scale_y; CGRect rect_fx = CGRectMake(dest_left, dest_top, src_width, src_height); CGRect rect_usr = CGRectApplyAffineTransform(rect_fx, _foxitDevice2User); CGContextBeginPath(_context); CGContextAddRect(_context, rect_usr); CGContextClip(_context); rect_usr.size = CGSizeMake(pBitmap->GetWidth() / scale_x, pBitmap->GetHeight() / scale_y); rect_usr = CGRectOffset(rect_usr, -src_left, -src_top); CG_SetImageTransform(dest_left, dest_top, src_width, src_height, &rect_usr); CFX_DIBitmap* pBitmap1 = NULL; if (pBitmap->IsAlphaMask()) { if (pBitmap->GetBuffer()) { pBitmap1 = (CFX_DIBitmap*)pBitmap; } else { pBitmap1 = pBitmap->Clone(); } if (NULL == pBitmap1) { RestoreState(FALSE); return FALSE; } CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData(NULL, pBitmap1->GetBuffer(), pBitmap1->GetPitch() * pBitmap1->GetHeight(), NULL); CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray(); CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault; CGImageRef pImage = CGImageCreate(pBitmap1->GetWidth(), pBitmap1->GetHeight(), pBitmap1->GetBPP(), pBitmap1->GetBPP(), pBitmap1->GetPitch(), pColorSpace, bitmapInfo, pBitmapProvider, NULL, true, kCGRenderingIntentDefault); CGContextClipToMask(_context, rect_usr, pImage); CGContextSetRGBFillColor(_context, FXARGB_R(argb) / 255.f, FXARGB_G(argb) / 255.f, FXARGB_B(argb) / 255.f, FXARGB_A(argb) / 255.f); CGContextFillRect(_context, rect_usr); CGImageRelease(pImage); CGColorSpaceRelease(pColorSpace); CGDataProviderRelease(pBitmapProvider); if (pBitmap1 != pBitmap) { delete pBitmap1; } RestoreState(FALSE); return TRUE; } if (pBitmap->GetBPP() < 32) { pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32); } else { if (pBitmap->GetBuffer()) { pBitmap1 = (CFX_DIBitmap*)pBitmap; } else { pBitmap1 = pBitmap->Clone(); } } if (NULL == pBitmap1) { RestoreState(FALSE); return FALSE; } if (pBitmap1->HasAlpha()) { if (pBitmap1 == pBitmap) { pBitmap1 = pBitmap->Clone(); if (!pBitmap1) { RestoreState(FALSE); return FALSE; } } for (int row = 0; row < pBitmap1->GetHeight(); row ++) { FX_LPBYTE pScanline = (FX_LPBYTE)pBitmap1->GetScanline(row); for (int col = 0; col < pBitmap1->GetWidth(); col ++) { pScanline[0] = (FX_BYTE)(pScanline[0] * pScanline[3] / 255.f + .5f); pScanline[1] = (FX_BYTE)(pScanline[1] * pScanline[3] / 255.f + .5f); pScanline[2] = (FX_BYTE)(pScanline[2] * pScanline[3] / 255.f + .5f); pScanline += 4; } } } CGContextRef ctx = createContextWithBitmap(pBitmap1); CGImageRef image = CGBitmapContextCreateImage(ctx); int blend_mode = blendType; if (FXDIB_BLEND_HARDLIGHT == blendType) { blend_mode = kCGBlendModeSoftLight; } else if (FXDIB_BLEND_SOFTLIGHT == blendType) { blend_mode = kCGBlendModeHardLight; } else if (blendType >= FXDIB_BLEND_NONSEPARABLE && blendType <= FXDIB_BLEND_LUMINOSITY) { blend_mode = blendType - 9; } else if (blendType > FXDIB_BLEND_LUMINOSITY || blendType < 0) { blend_mode = kCGBlendModeNormal; } CGContextSetBlendMode(_context, (CGBlendMode)blend_mode); CGContextDrawImage(_context, rect_usr, image); CGImageRelease(image); CGContextRelease(ctx); if (pBitmap1 != pBitmap) { delete pBitmap1; } RestoreState(FALSE); return TRUE; }
FX_BOOL CFX_QuartzDeviceDriver::StretchDIBits(const CFX_DIBSource* pBitmap, FX_ARGB argb, int dest_left, int dest_top, int dest_width, int dest_height, const FX_RECT* clipRect, FX_DWORD flags, int alphaFlag , void* iccTransform , int blend_type) { SaveState(); if (clipRect) { CGContextBeginPath(_context); CGRect rect_clip = CGRectMake(clipRect->left, clipRect->top, clipRect->Width(), clipRect->Height()); rect_clip = CGRectApplyAffineTransform(rect_clip, _foxitDevice2User); CGContextAddRect(_context, rect_clip); CGContextClip(_context); } CGRect rect = CGRectMake(dest_left, dest_top, dest_width, dest_height); rect = CGRectApplyAffineTransform(rect, _foxitDevice2User); if (FXDIB_BICUBIC_INTERPOL == flags) { CGContextSetInterpolationQuality(_context, kCGInterpolationHigh); } else if (FXDIB_DOWNSAMPLE == flags) { CGContextSetInterpolationQuality(_context, kCGInterpolationNone); } else { CGContextSetInterpolationQuality(_context, kCGInterpolationMedium); } CG_SetImageTransform(dest_left, dest_top, dest_width, dest_height); CFX_DIBitmap* pBitmap1 = NULL; if (pBitmap->IsAlphaMask()) { if (pBitmap->GetBuffer()) { pBitmap1 = (CFX_DIBitmap*)pBitmap; } else { pBitmap1 = pBitmap->Clone(); } if (NULL == pBitmap1) { RestoreState(FALSE); return FALSE; } CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData(NULL, pBitmap1->GetBuffer(), pBitmap1->GetPitch() * pBitmap1->GetHeight(), NULL); CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray(); CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault; CGImageRef pImage = CGImageCreate(pBitmap1->GetWidth(), pBitmap1->GetHeight(), pBitmap1->GetBPP(), pBitmap1->GetBPP(), pBitmap1->GetPitch(), pColorSpace, bitmapInfo, pBitmapProvider, NULL, true, kCGRenderingIntentDefault); CGContextClipToMask(_context, rect, pImage); CGContextSetRGBFillColor(_context, FXARGB_R(argb) / 255.f, FXARGB_G(argb) / 255.f, FXARGB_B(argb) / 255.f, FXARGB_A(argb) / 255.f); CGContextFillRect(_context, rect); CGImageRelease(pImage); CGColorSpaceRelease(pColorSpace); CGDataProviderRelease(pBitmapProvider); if (pBitmap1 != pBitmap) { delete pBitmap1; } RestoreState(FALSE); return TRUE; } if (pBitmap->GetBPP() < 32) { pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32); } else { if (pBitmap->GetBuffer()) { pBitmap1 = (CFX_DIBitmap*)pBitmap; } else { pBitmap1 = pBitmap->Clone(); } } if (NULL == pBitmap1) { RestoreState(FALSE); return FALSE; } if (pBitmap1->HasAlpha()) { if (pBitmap1 == pBitmap) { pBitmap1 = pBitmap->Clone(); if (!pBitmap1) { RestoreState(FALSE); return FALSE; } } for (int row = 0; row < pBitmap1->GetHeight(); row ++) { FX_LPBYTE pScanline = (FX_LPBYTE)pBitmap1->GetScanline(row); for (int col = 0; col < pBitmap1->GetWidth(); col ++) { pScanline[0] = (FX_BYTE)(pScanline[0] * pScanline[3] / 255.f + .5f); pScanline[1] = (FX_BYTE)(pScanline[1] * pScanline[3] / 255.f + .5f); pScanline[2] = (FX_BYTE)(pScanline[2] * pScanline[3] / 255.f + .5f); pScanline += 4; } } } CGContextRef ctx = createContextWithBitmap(pBitmap1); CGImageRef image = CGBitmapContextCreateImage(ctx); CGContextDrawImage(_context, rect, image); CGImageRelease(image); CGContextRelease(ctx); if (pBitmap1 != pBitmap) { delete pBitmap1; } RestoreState(FALSE); return TRUE; }
void drawPlugin(NPP instance, NPCocoaEvent* event) { if (!browserUAString) return; PluginInstance* currentInstance = (PluginInstance*)(instance->pdata); CGContextRef cgContext = event->data.draw.context; if (!cgContext) return; float windowWidth = currentInstance->window.width; float windowHeight = currentInstance->window.height; // save the cgcontext gstate CGContextSaveGState(cgContext); // we get a flipped context CGContextTranslateCTM(cgContext, 0.0, windowHeight); CGContextScaleCTM(cgContext, 1.0, -1.0); // draw a gray background for the plugin CGContextAddRect(cgContext, CGRectMake(0, 0, windowWidth, windowHeight)); CGContextSetGrayFillColor(cgContext, 0.5, 1.0); CGContextDrawPath(cgContext, kCGPathFill); // draw a black frame around the plugin CGContextAddRect(cgContext, CGRectMake(0, 0, windowWidth, windowHeight)); CGContextSetGrayStrokeColor(cgContext, 0.0, 1.0); CGContextSetLineWidth(cgContext, 6.0); CGContextStrokePath(cgContext); // draw the UA string using ATSUI CGContextSetGrayFillColor(cgContext, 0.0, 1.0); ATSUStyle atsuStyle; ATSUCreateStyle(&atsuStyle); CFIndex stringLength = CFStringGetLength(browserUAString); UniChar* unicharBuffer = (UniChar*)malloc((stringLength + 1) * sizeof(UniChar)); CFStringGetCharacters(browserUAString, CFRangeMake(0, stringLength), unicharBuffer); UniCharCount runLengths = kATSUToTextEnd; ATSUTextLayout atsuLayout; ATSUCreateTextLayoutWithTextPtr(unicharBuffer, kATSUFromTextBeginning, kATSUToTextEnd, stringLength, 1, &runLengths, &atsuStyle, &atsuLayout); ATSUAttributeTag contextTag = kATSUCGContextTag; ByteCount byteSize = sizeof(CGContextRef); ATSUAttributeValuePtr contextATSUPtr = &cgContext; ATSUSetLayoutControls(atsuLayout, 1, &contextTag, &byteSize, &contextATSUPtr); ATSUTextMeasurement lineAscent, lineDescent; ATSUGetLineControl(atsuLayout, kATSUFromTextBeginning, kATSULineAscentTag, sizeof(ATSUTextMeasurement), &lineAscent, &byteSize); ATSUGetLineControl(atsuLayout, kATSUFromTextBeginning, kATSULineDescentTag, sizeof(ATSUTextMeasurement), &lineDescent, &byteSize); float lineHeight = FixedToFloat(lineAscent) + FixedToFloat(lineDescent); ItemCount softBreakCount; ATSUBatchBreakLines(atsuLayout, kATSUFromTextBeginning, stringLength, FloatToFixed(windowWidth - 10.0), &softBreakCount); ATSUGetSoftLineBreaks(atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd, 0, NULL, &softBreakCount); UniCharArrayOffset* softBreaks = (UniCharArrayOffset*)malloc(softBreakCount * sizeof(UniCharArrayOffset)); ATSUGetSoftLineBreaks(atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd, softBreakCount, softBreaks, &softBreakCount); UniCharArrayOffset currentDrawOffset = kATSUFromTextBeginning; int i = 0; while (i < softBreakCount) { ATSUDrawText(atsuLayout, currentDrawOffset, softBreaks[i], FloatToFixed(5.0), FloatToFixed(windowHeight - 5.0 - (lineHeight * (i + 1.0)))); currentDrawOffset = softBreaks[i]; i++; } ATSUDrawText(atsuLayout, currentDrawOffset, kATSUToTextEnd, FloatToFixed(5.0), FloatToFixed(windowHeight - 5.0 - (lineHeight * (i + 1.0)))); free(unicharBuffer); free(softBreaks); // restore the cgcontext gstate CGContextRestoreGState(cgContext); }
void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &offset) { Q_D(QRasterWindowSurface); // Not ready for painting yet, bail out. This can happen in // QWidget::create_sys() if (!d->image) return; #ifdef Q_WS_WIN QRect br = rgn.boundingRect(); #ifndef Q_OS_WINCE if (!qt_widget_private(window())->isOpaque && d->canUseLayeredWindow) { QRect r = window()->frameGeometry(); QPoint frameOffset = qt_widget_private(window())->frameStrut().topLeft(); QRect dirtyRect = br.translated(offset + frameOffset); SIZE size = {r.width(), r.height()}; POINT ptDst = {r.x(), r.y()}; POINT ptSrc = {0, 0}; Q_BLENDFUNCTION blend = {AC_SRC_OVER, 0, (int)(255.0 * window()->windowOpacity()), Q_AC_SRC_ALPHA}; RECT dirty = {dirtyRect.x(), dirtyRect.y(), dirtyRect.x() + dirtyRect.width(), dirtyRect.y() + dirtyRect.height()}; Q_UPDATELAYEREDWINDOWINFO info = {sizeof(info), NULL, &ptDst, &size, d->image->hdc, &ptSrc, 0, &blend, Q_ULW_ALPHA, &dirty}; (*ptrUpdateLayeredWindowIndirect)(window()->internalWinId(), &info); } else #endif { QPoint wOffset = qt_qwidget_data(widget)->wrect.topLeft(); HDC widget_dc = widget->getDC(); QRect wbr = br.translated(-wOffset); BitBlt(widget_dc, wbr.x(), wbr.y(), wbr.width(), wbr.height(), d->image->hdc, br.x() + offset.x(), br.y() + offset.y(), SRCCOPY); widget->releaseDC(widget_dc); } #ifndef QT_NO_DEBUG static bool flush = !qgetenv("QT_FLUSH_WINDOWSURFACE").isEmpty(); if (flush) { SelectObject(qt_win_display_dc(), GetStockObject(BLACK_BRUSH)); Rectangle(qt_win_display_dc(), 0, 0, d->image->width() + 2, d->image->height() + 2); BitBlt(qt_win_display_dc(), 1, 1, d->image->width(), d->image->height(), d->image->hdc, 0, 0, SRCCOPY); } #endif #endif #ifdef Q_WS_X11 extern void *qt_getClipRects(const QRegion &r, int &num); // in qpaintengine_x11.cpp extern QWidgetData* qt_widget_data(QWidget *); QPoint wOffset = qt_qwidget_data(widget)->wrect.topLeft(); if (widget->window() != window()) { XFreeGC(X11->display, d_ptr->gc); d_ptr->gc = XCreateGC(X11->display, widget->handle(), 0, 0); } QRegion wrgn(rgn); if (!wOffset.isNull()) wrgn.translate(-wOffset); QRect wbr = wrgn.boundingRect(); int num; XRectangle *rects = (XRectangle *)qt_getClipRects(wrgn, num); XSetClipRectangles(X11->display, d_ptr->gc, 0, 0, rects, num, YXBanded); QRect br = rgn.boundingRect().translated(offset); #ifndef QT_NO_MITSHM if (d_ptr->image->xshmpm) { XCopyArea(X11->display, d_ptr->image->xshmpm, widget->handle(), d_ptr->gc, br.x(), br.y(), br.width(), br.height(), wbr.x(), wbr.y()); XSync(X11->display, False); } else #endif { const QImage &src = d->image->image; br = br.intersected(src.rect()); if (src.format() != QImage::Format_RGB32) { QX11PixmapData *data = new QX11PixmapData(QPixmapData::PixmapType); data->xinfo = widget->x11Info(); data->fromImage(src, Qt::AutoColor); QPixmap pm = QPixmap(data); XCopyArea(X11->display, pm.handle(), widget->handle(), d_ptr->gc, br.x() , br.y() , br.width(), br.height(), wbr.x(), wbr.y()); } else { // qpaintengine_x11.cpp extern void qt_x11_drawImage(const QRect &rect, const QPoint &pos, const QImage &image, Drawable hd, GC gc, Display *dpy, Visual *visual, int depth); qt_x11_drawImage(br, wbr.topLeft(), src, widget->handle(), d_ptr->gc, X11->display, (Visual *)widget->x11Info().visual(), widget->x11Info().depth()); } } #endif // FALCON #ifdef Q_WS_MAC // qDebug() << "Flushing" << widget << rgn << offset; // d->image->image.save("flush.png"); // Get a context for the widget. #ifndef QT_MAC_USE_COCOA CGContextRef context; CGrafPtr port = GetWindowPort(qt_mac_window_for(widget)); QDBeginCGContext(port, &context); #else extern CGContextRef qt_mac_graphicsContextFor(QWidget *); CGContextRef context = qt_mac_graphicsContextFor(widget); #endif CGContextSaveGState(context); // Flip context. CGContextTranslateCTM(context, 0, widget->height()); CGContextScaleCTM(context, 1, -1); // Clip to region. const QVector<QRect> &rects = rgn.rects(); for (int i = 0; i < rects.size(); ++i) { const QRect &rect = rects.at(i); CGContextAddRect(context, CGRectMake(rect.x(), rect.y(), rect.width(), rect.height())); } CGContextClip(context); QRect r = rgn.boundingRect(); const CGRect area = CGRectMake(r.x(), r.y(), r.width(), r.height()); CGImageRef image = CGBitmapContextCreateImage(d->image->cg); CGImageRef subImage = CGImageCreateWithImageInRect(image, area); qt_mac_drawCGImage(context, &area, subImage); CGImageRelease(subImage); CGImageRelease(image); // CGSize size = { d->image->image.width(), d->image->image.height() }; // CGLayerRef layer = CGLayerCreateWithContext(d->image->cg, size, 0); // CGPoint pt = { 0, 0 }; // CGContextDrawLayerAtPoint(context, pt, layer); // CGLayerRelease(layer); // Restore context. CGContextRestoreGState(context); #ifndef QT_MAC_USE_COCOA QDEndCGContext(port, &context); #else CGContextFlush(context); #endif #endif }