static void Quartz_Circle(double x, double y, double r, R_GE_gcontext *gc, NewDevDesc *dd) { QuartzDesc *xd = (QuartzDesc*)dd->deviceSpecific; CGContextSaveGState( GetContext(xd) ); CGContextBeginPath( GetContext(xd) ); Quartz_SetLineProperties(gc, dd); CGContextAddArc( GetContext(xd), (float)x , (float)y, (float)r, 3.141592654 * 2.0, 0.0, 0); Quartz_SetFill( gc->fill, gc->gamma, dd); CGContextFillPath( GetContext(xd) ); Quartz_SetStroke( gc->col, gc->gamma, dd); CGContextAddArc( GetContext(xd), (float)x , (float)y, (float)r, 3.141592654 * 2.0, 0.0, 0); CGContextStrokePath( GetContext(xd) ); CGContextRestoreGState( GetContext(xd) ); }
void SVGPaintServer::fillPath(CGContextRef context, const RenderPath* path) const { if (path->style()->svgStyle()->fillRule() == RULE_EVENODD) CGContextEOFillPath(context); else CGContextFillPath(context); }
void structGraphicsScreen :: v_fillArea (long numberOfPoints, double *xyDC) { #if cairo if (our d_cairoGraphicsContext == NULL) return; // cairo_new_path (our d_cairoGraphicsContext); // move_to() automatically creates a new path cairo_move_to (our d_cairoGraphicsContext, xyDC [0], xyDC [1]); for (long i = 1; i < numberOfPoints; i ++) cairo_line_to (our d_cairoGraphicsContext, xyDC [i + i], xyDC [i + i + 1]); cairo_close_path (our d_cairoGraphicsContext); cairo_fill (our d_cairoGraphicsContext); #elif win MY_BRUSH BeginPath (our d_gdiGraphicsContext); MoveToEx (our d_gdiGraphicsContext, xyDC [0], xyDC [1], NULL); for (long i = 1; i < numberOfPoints; i ++) LineTo (our d_gdiGraphicsContext, xyDC [i + i], xyDC [i + i + 1]); EndPath (our d_gdiGraphicsContext); FillPath (our d_gdiGraphicsContext); DEFAULT #elif mac GraphicsQuartz_initDraw (this); quartzPrepareFill (this); CGContextBeginPath (our d_macGraphicsContext); CGContextMoveToPoint (our d_macGraphicsContext, xyDC [0], xyDC [1]); for (long i = 1; i < numberOfPoints; i ++) { CGContextAddLineToPoint (our d_macGraphicsContext, xyDC [i + i], xyDC [i + i + 1]); } CGContextFillPath (our d_macGraphicsContext); GraphicsQuartz_exitDraw (this); #endif }
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); }
static inline void fillPathWithFillRule(CGContextRef context, WindRule fillRule) { if (fillRule == RULE_EVENODD) CGContextEOFillPath(context); else CGContextFillPath(context); }
// This method is only used to draw the little circles used in lists. void GraphicsContext::drawEllipse(const IntRect& rect) { // FIXME: CG added CGContextAddEllipseinRect in Tiger, so we should be able to quite easily draw an ellipse. // This code can only handle circles, not ellipses. But khtml only // uses it for circles. ASSERT(rect.width() == rect.height()); if (paintingDisabled()) return; CGContextRef context = platformContext(); CGContextBeginPath(context); float r = (float)rect.width() / 2; CGContextAddArc(context, rect.x() + r, rect.y() + r, r, 0, 2*M_PI, true); CGContextClosePath(context); if (fillColor().alpha()) { if (strokeStyle() != NoStroke) // stroke and fill CGContextDrawPath(context, kCGPathFillStroke); else CGContextFillPath(context); } else if (strokeStyle() != NoStroke) CGContextStrokePath(context); }
void paintOval(CGContextRef context, CGRect r) { // Add a path for the oval to this context addOvalToPath(context,r); // Fill the oval CGContextFillPath(context); }
void JBGFillTriangle(CGContextRef ctx, CGPoint point_a, CGPoint point_b, CGPoint point_c, CGColorRef color) { CGContextBeginPath(ctx); CGPoint points[] = {point_a, point_b, point_c}; CGContextAddLines(ctx, points, sizeof(points) / sizeof(points[0])); CGContextClosePath(ctx); CGContextSetFillColorWithColor(ctx, color); CGContextFillPath(ctx); }
/* fillRoundedRect : fills a rounded rectangle with the current fill color Parameter Descriptions rect : The CG rectangle that defines the rectangle's boundary. ovalWidth : The width of the CG rectangle that encloses the rounded corners ovalHeight : The height of the CG rectangle that encloses the rounded corners context : The CG context to render to. */ void fillRoundedRect(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight) { // Signal the start of a path CGContextBeginPath(context); // Add a rounded rect to the path addRoundedRectToPath(context, rect, ovalWidth, ovalHeight); // Fill the path CGContextFillPath(context); }
void MacDock::overlay(const QString& text) { if (text.isEmpty()) { overlayed = false; RestoreApplicationDockTileImage(); return; } // Create the context CGContextRef context = BeginCGContextForApplicationDockTile(); if (!overlayed) { overlayed = true; // Add some subtle drop down shadow // FIXME: Disabled because 10.2 doesn't support it //CGSize s = { 2.0, -4.0 }; //CGContextSetShadow(context,s,5.0); } // Draw a circle CGContextBeginPath(context); CGContextAddArc(context, 95.0, 95.0, 25.0, 0.0, 2 * M_PI, true); CGContextClosePath(context); CGContextSetRGBFillColor(context, 1, 0.0, 0.0, 1); CGContextFillPath(context); // Set the clipping path to the same circle CGContextBeginPath(context); CGContextAddArc(context, 95.0, 95.0, 25.0, 0.0, 2 * M_PI, true); CGContextClip(context); // Remove drop shadow // FIXME: Disabled because 10.2 doesn't support it //CGSize s = { 0.0, -0.0 }; //CGContextSetShadowWithColor(context, s, 0, NULL); // Select the appropriate font CGContextSelectFont(context,DOCK_FONT_NAME, DOCK_FONT_SIZE, kCGEncodingMacRoman); CGContextSetRGBFillColor(context, 1, 1, 1, 1); // Draw the text invisible CGPoint begin = CGContextGetTextPosition(context); CGContextSetTextDrawingMode(context, kCGTextInvisible); CGContextShowTextAtPoint(context, begin.x, begin.y, text.toStdString().c_str(), text.length()); CGPoint end = CGContextGetTextPosition(context); // Draw the text CGContextSetTextDrawingMode(context, kCGTextFill); CGContextShowTextAtPoint(context, 95 - (end.x - begin.x)/2, 95 - 8, text.toStdString().c_str(), text.length()); // Cleanup CGContextFlush(context); EndCGContextForApplicationDockTile(context); }
FX_BOOL CFX_QuartzDeviceDriver::DrawPath(const CFX_PathData* pathData, const CFX_AffineMatrix* matrix, const CFX_GraphStateData* graphState, FX_DWORD fillArgb, FX_DWORD strokeArgb, int fillMode, int alpha_flag, void* pIccTransform, int blend_type ) { SaveState(); CGBlendMode mode = GetCGBlendMode(blend_type); if (mode != kCGBlendModeNormal) { CGContextSetBlendMode(_context, mode); } CGAffineTransform m = CGAffineTransformIdentity; if (matrix) { m = CGAffineTransformMake(matrix->GetA(), matrix->GetB(), matrix->GetC(), matrix->GetD(), matrix->GetE(), matrix->GetF()); } m = CGAffineTransformConcat(m, _foxitDevice2User); CGContextConcatCTM(_context, m); int pathMode = 0; if (graphState && strokeArgb) { CGContextSetMiterLimit(_context, graphState->m_MiterLimit); FX_FLOAT lineWidth = getLineWidth(graphState, m); setStrokeInfo(graphState, strokeArgb, lineWidth); pathMode |= 4; } if (fillMode && fillArgb) { setFillInfo(fillArgb); if ((fillMode & 3) == FXFILL_WINDING) { pathMode |= 1; } else if ((fillMode & 3) == FXFILL_ALTERNATE) { pathMode |= 2; } } setPathToContext(pathData); if (fillMode & FXFILL_FULLCOVER) { CGContextSetShouldAntialias(_context, false); } if (pathMode == 4) { CGContextStrokePath(_context); } else if (pathMode == 1) { CGContextFillPath(_context); } else if (pathMode == 2) { CGContextEOFillPath(_context); } else if (pathMode == 5) { CGContextDrawPath(_context, kCGPathFillStroke); } else if (pathMode == 6) { CGContextDrawPath(_context, kCGPathEOFillStroke); } RestoreState(FALSE); return TRUE; }
void CanvasRenderingContext2D::fill() { GraphicsContext* c = drawingContext(); if (!c) return; // FIXME: Do this through platform-independent GraphicsContext API. #if PLATFORM(CG) CGContextBeginPath(c->platformContext()); CGContextAddPath(c->platformContext(), state().m_path.platformPath()); if (!state().m_path.isEmpty()) willDraw(CGContextGetPathBoundingBox(c->platformContext())); if (state().m_fillStyle->gradient()) { // Shading works on the entire clip region, so convert the current path to a clip. c->save(); CGContextClip(c->platformContext()); CGContextDrawShading(c->platformContext(), state().m_fillStyle->gradient()->platformShading()); c->restore(); } else { if (state().m_fillStyle->pattern()) applyFillPattern(); CGContextFillPath(c->platformContext()); } #elif PLATFORM(QT) QPainterPath* path = state().m_path.platformPath(); QPainter* p = static_cast<QPainter*>(c->platformContext()); willDraw(path->controlPointRect()); if (state().m_fillStyle->gradient()) { p->fillPath(*path, QBrush(*(state().m_fillStyle->gradient()->platformShading()))); } else { if (state().m_fillStyle->pattern()) applyFillPattern(); p->fillPath(*path, p->brush()); } #elif PLATFORM(CAIRO) cairo_t* pathCr = state().m_path.platformPath()->m_cr; cairo_t* cr = c->platformContext(); cairo_save(cr); willDraw(state().m_path.boundingRect()); if (state().m_fillStyle->gradient()) { cairo_set_source(cr, state().m_fillStyle->gradient()->platformShading()); c->addPath(state().m_path); cairo_fill(cr); } else { if (state().m_fillStyle->pattern()) applyFillPattern(); c->addPath(state().m_path); cairo_fill(cr); } cairo_restore(cr); #endif clearPathForDashboardBackwardCompatibilityMode(); }
void CanvasRenderingContext2D::fill() { GraphicsContext* c = drawingContext(); if (!c) return; c->beginPath(); c->addPath(m_path); if (!m_path.isEmpty()) willDraw(m_path.boundingRect()); #if PLATFORM(CG) if (state().m_fillStyle->canvasGradient()) { // Shading works on the entire clip region, so convert the current path to a clip. c->save(); CGContextClip(c->platformContext()); CGContextDrawShading(c->platformContext(), state().m_fillStyle->canvasGradient()->gradient().platformGradient()); c->restore(); } else { if (state().m_fillStyle->pattern()) applyFillPattern(); CGContextFillPath(c->platformContext()); } #elif PLATFORM(QT) QPainterPath* path = m_path.platformPath(); QPainter* p = static_cast<QPainter*>(c->platformContext()); if (state().m_fillStyle->canvasGradient()) { p->fillPath(*path, QBrush(*(state().m_fillStyle->canvasGradient()->gradient().platformGradient()))); } else { if (state().m_fillStyle->pattern()) applyFillPattern(); p->fillPath(*path, p->brush()); } #elif PLATFORM(CAIRO) && !PLATFORM(BAL) cairo_t* cr = c->platformContext(); cairo_save(cr); if (state().m_fillStyle->canvasGradient()) { cairo_set_source(cr, state().m_fillStyle->canvasGradient()->gradient().platformGradient()); cairo_fill(cr); } else { if (state().m_fillStyle->pattern()) applyFillPattern(); cairo_fill(cr); } cairo_restore(cr); #elif PLATFORM(BAL) //FIXME notImplemented(); #endif #if ENABLE(DASHBOARD_SUPPORT) clearPathForDashboardBackwardCompatibilityMode(); #endif }
void PlatformCALayer::drawRepaintIndicator(CGContextRef context, PlatformCALayer* platformCALayer, int repaintCount, CGColorRef customBackgroundColor) { char text[16]; // that's a lot of repaints snprintf(text, sizeof(text), "%d", repaintCount); FloatRect indicatorBox = platformCALayer->bounds();\ indicatorBox.setLocation( { 1, 1 } ); indicatorBox.setSize(FloatSize(12 + 10 * strlen(text), 27)); CGContextStateSaver stateSaver(context); CGContextSetAlpha(context, 0.5f); CGContextBeginTransparencyLayerWithRect(context, indicatorBox, 0); if (customBackgroundColor) CGContextSetFillColorWithColor(context, customBackgroundColor); else CGContextSetRGBFillColor(context, 0, 0.5f, 0.25f, 1); if (platformCALayer->isOpaque()) CGContextFillRect(context, indicatorBox); else { Path boundsPath; boundsPath.moveTo(indicatorBox.maxXMinYCorner()); boundsPath.addLineTo(indicatorBox.maxXMaxYCorner()); boundsPath.addLineTo(indicatorBox.minXMaxYCorner()); const float cornerChunk = 8; boundsPath.addLineTo(FloatPoint(indicatorBox.x(), indicatorBox.y() + cornerChunk)); boundsPath.addLineTo(FloatPoint(indicatorBox.x() + cornerChunk, indicatorBox.y())); boundsPath.closeSubpath(); CGContextAddPath(context, boundsPath.platformPath()); CGContextFillPath(context); } if (platformCALayer->owner()->isUsingDisplayListDrawing(platformCALayer)) { CGContextSetRGBStrokeColor(context, 0, 0, 0, 0.65); CGContextSetLineWidth(context, 2); CGContextStrokeRect(context, indicatorBox); } if (platformCALayer->acceleratesDrawing()) CGContextSetRGBFillColor(context, 1, 0, 0, 1); else CGContextSetRGBFillColor(context, 1, 1, 1, 1); platformCALayer->drawTextAtPoint(context, indicatorBox.x() + 5, indicatorBox.y() + 22, CGSizeMake(1, -1), 22, text, strlen(text)); CGContextEndTransparencyLayer(context); }
void InitButton(unsigned w, unsigned h) { CGColorSpaceRef colorspace; CGContextRef gc; unsigned char *data; float cx, cy; data = (unsigned char *)malloc(w * h * 4); colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); gc = CGBitmapContextCreate(data, w, h, 8, w * 4, colorspace, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host); cx = CENTERX * w; cy = CENTERY * h; // background CGContextTranslateCTM(gc, 0.0, h); CGContextScaleCTM(gc, 1.0, -1.0); CGContextClearRect(gc, CGRectMake(0, 0, w, h)); CGContextSetRGBFillColor(gc, 0.0, 0.0, 0.0, 0.8); AddRoundedRectToPath(gc, CGRectMake(w*0.05, h*0.5 - 32, w*0.9, 64), 32, 32); CGContextFillPath(gc); CGGradientRef gradient; size_t num_locations = 2; CGFloat locations[2] = { 0.0, 1.0 }; CGFloat components[8] = { 1.0, 1.0, 1.0, 0.5, // Start color 0.0, 0.0, 0.0, 0.0 }; // End color gradient = CGGradientCreateWithColorComponents (colorspace, components, locations, num_locations); // top bevel CGContextSaveGState(gc); AddRoundedRectToPath(gc, CGRectMake(w*0.05, h*0.5 - 32, w*0.9, 64), 32, 32); CGContextEOClip(gc); CGContextDrawLinearGradient (gc, gradient, CGPointMake(cx, cy + 32), CGPointMake(cx, cy), 0); CGContextDrawLinearGradient (gc, gradient, CGPointMake(cx, cy - 32), CGPointMake(cx, cy - 16), 0); glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, w, h, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data); CGContextRelease(gc); CGColorSpaceRelease(colorspace); free(data); }
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 paintArc(CGContextRef context, CGRect r, int startAngle, int arcAngle) { float start, end; // Signal the start of a path CGContextBeginPath(context); // Set the start of the path to the arcs focal point CGContextMoveToPoint(context, r.origin.x + r.size.width/2, r.origin.y + r.size.height/2); // Add to the path the arc of the oval that fits inside the rectangle. pathForArc(context,r,startAngle,arcAngle); // Complete the path closing the arc at the focal point CGContextClosePath(context); // Fill the path CGContextFillPath(context); }
static void gdk_quartz_draw_polygon (GdkDrawable *drawable, GdkGC *gc, gboolean filled, GdkPoint *points, gint npoints) { CGContextRef context = gdk_quartz_drawable_get_context (drawable, FALSE); int i; if (!context) return; if (!_gdk_quartz_gc_update_cg_context (gc, drawable, context, filled ? GDK_QUARTZ_CONTEXT_FILL : GDK_QUARTZ_CONTEXT_STROKE)) { gdk_quartz_drawable_release_context (drawable, context); return; } if (filled) { CGContextMoveToPoint (context, points[0].x, points[0].y); for (i = 1; i < npoints; i++) CGContextAddLineToPoint (context, points[i].x, points[i].y); CGContextClosePath (context); CGContextFillPath (context); } else { CGContextMoveToPoint (context, points[0].x + 0.5, points[0].y + 0.5); for (i = 1; i < npoints; i++) CGContextAddLineToPoint (context, points[i].x + 0.5, points[i].y + 0.5); CGContextClosePath (context); CGContextStrokePath (context); } gdk_quartz_drawable_release_context (drawable, context); }
static void Quartz_Polygon(int n, double *x, double *y, R_GE_gcontext *gc, NewDevDesc *dd) { int i; QuartzDesc *xd = (QuartzDesc*)dd->deviceSpecific; CGPoint *lines; CGContextSaveGState( GetContext(xd) ); CGContextBeginPath( GetContext(xd) ); /* Quartz_SetLineProperties(gc, dd); */ lines = (CGPoint *)malloc(sizeof(CGPoint)*(n+1)); if(lines == NULL) return; for (i = 0; i < n; i++) { lines[i].x = (float)x[i]; lines[i].y = (float)y[i]; } lines[n].x = (float)x[0]; lines[n].y = (float)y[0]; CGContextAddLines( GetContext(xd), &lines[0], n+1 ); Quartz_SetLineProperties(gc, dd); Quartz_SetFill( gc->fill, gc->gamma, dd); CGContextFillPath( GetContext(xd) ); CGContextAddLines( GetContext(xd), &lines[0], n+1 ); Quartz_SetStroke( gc->col, gc->gamma, dd); CGContextStrokePath( GetContext(xd) ); CGContextRestoreGState( GetContext(xd) ); }
void doRotatedEllipsesWithCGPath(CGContextRef context) { int i, totreps = 144.; CGMutablePathRef path = NULL; float tint = 1., tintIncrement = 1./totreps; // Create a new transform consisting of a 45 degree rotation. CGAffineTransform theTransform = CGAffineTransformMakeRotation(M_PI/4); // Apply a scaling transformation to the transform just created. theTransform = CGAffineTransformScale(theTransform, 1, 2); // Create a mutable CGPath object. path = CGPathCreateMutable(); if(!path){ fprintf(stderr, "Couldn't create path!\n"); return; } // Add a circular arc to the CGPath object, transformed // by an affine transform. CGPathAddArc(path, &theTransform, 0., 0., 45., 0., 2*M_PI, false); // Close the CGPath object. CGPathCloseSubpath(path); // Place the first ellipse at a good location. CGContextTranslateCTM(context, 100., 100.); for (i = 0 ; i < totreps ; i++){ CGContextBeginPath(context); // Add the CGPath object to the current path in the context. CGContextAddPath(context, path); // Set the fill color for this instance of the ellipse. CGContextSetRGBFillColor(context, tint, 0., 0., 1.); // Filling the path implicitly closes it. CGContextFillPath(context); // Compute the next tint color. tint -= tintIncrement; // Move over for the next ellipse. CGContextTranslateCTM(context, 1, 0.); } // Release the path when done with it. CGPathRelease(path); }
static void drawNeedle(CGContextRef gc, int w, int h, float angle) { float dx, dy, cx, cy, radius, needle; cx = CENTERX * w; cy = CENTERY * h; dx = -cos(angle); dy = -sin(angle); radius = 0.5 * (w > h ? w : h); needle = radius * 0.85; CGContextMoveToPoint(gc, cx + needle*dx - 0.5*dy, cy + needle*dy + 0.5*dx); CGContextAddLineToPoint(gc, cx + needle*dx + 0.5*dy, cy + needle*dy - 0.5*dx); CGContextAddLineToPoint(gc, cx - NEEDLE_THICKNESS*dx + 0.5*NEEDLE_THICKNESS*dy, cy - NEEDLE_THICKNESS*dy - 0.5*NEEDLE_THICKNESS*dx); CGContextAddArc(gc, cx - NEEDLE_THICKNESS*dx, cy - NEEDLE_THICKNESS*dy, 0.5*NEEDLE_THICKNESS, angle - 0.5*M_PI, angle + 0.5*M_PI, false); CGContextAddLineToPoint(gc, cx - NEEDLE_THICKNESS*dx - 0.5*NEEDLE_THICKNESS*dy, cy - NEEDLE_THICKNESS*dy + 0.5*NEEDLE_THICKNESS*dx); CGContextFillPath(gc); }
void MacVegaPrinterListener::FillEllipse(const OpRect& rect) { CGRect cgrect = CGRectMake(rect.x, rect.y, rect.width, rect.height); cgrect.origin.y = m_winHeight - cgrect.origin.y - cgrect.size.height; float cx = cgrect.origin.x + (cgrect.size.width / 2); float cy = cgrect.origin.y + (cgrect.size.height / 2); float radius = cgrect.size.width / 2; if(cgrect.size.width != cgrect.size.height) { cy = cy * cgrect.size.width / cgrect.size.height; CGContextScaleCTM(m_ctx, 1.0, cgrect.size.height/cgrect.size.width); } CGContextAddArc(m_ctx, cx, cy, radius, 0, 2*M_PI, 0); CGContextFillPath(m_ctx); if(cgrect.size.width != cgrect.size.height) { CGContextScaleCTM(m_ctx, 1.0, cgrect.size.width/cgrect.size.height); } }
static void gdk_quartz_draw_arc (GdkDrawable *drawable, GdkGC *gc, gboolean filled, gint x, gint y, gint width, gint height, gint angle1, gint angle2) { CGContextRef context = gdk_quartz_drawable_get_context (drawable, FALSE); float start_angle, end_angle; gboolean clockwise = FALSE; if (!context) return; if (!_gdk_quartz_gc_update_cg_context (gc, drawable, context, filled ? GDK_QUARTZ_CONTEXT_FILL : GDK_QUARTZ_CONTEXT_STROKE)) { gdk_quartz_drawable_release_context (drawable, context); return; } start_angle = angle1 * 2.0 * G_PI / 360.0 / 64.0; end_angle = start_angle + angle2 * 2.0 * G_PI / 360.0 / 64.0; /* angle2 is relative to angle1 and can be negative, which switches * the drawing direction */ if (angle2 < 0) clockwise = TRUE; /* below, flip the coordinate system back to its original y-diretion * so the angles passed to CGContextAddArc() are interpreted as * expected * * FIXME: the implementation below works only for perfect circles * (width == height). Any other aspect ratio either scales the * line width unevenly or scales away the path entirely for very * small line widths (esp. for line_width == 0, which is a hair * line on X11 but must be approximated with the thinnest possible * line on quartz). */ if (filled) { CGContextTranslateCTM (context, x + width / 2.0, y + height / 2.0); CGContextScaleCTM (context, 1.0, - (double)height / (double)width); CGContextMoveToPoint (context, 0, 0); CGContextAddArc (context, 0, 0, width / 2.0, start_angle, end_angle, clockwise); CGContextClosePath (context); CGContextFillPath (context); } else { CGContextTranslateCTM (context, x + width / 2.0 + 0.5, y + height / 2.0 + 0.5); CGContextScaleCTM (context, 1.0, - (double)height / (double)width); CGContextAddArc (context, 0, 0, width / 2.0, start_angle, end_angle, clockwise); CGContextStrokePath (context); } gdk_quartz_drawable_release_context (drawable, context); }
static void drawGDIGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* font, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) { Color fillColor = graphicsContext->fillColor(); bool drawIntoBitmap = false; TextDrawingModeFlags drawingMode = graphicsContext->textDrawingMode(); if (drawingMode == TextModeFill) { if (!fillColor.alpha()) return; drawIntoBitmap = fillColor.alpha() != 255 || graphicsContext->inTransparencyLayer(); if (!drawIntoBitmap) { FloatSize offset; float blur; Color color; ColorSpace shadowColorSpace; graphicsContext->getShadow(offset, blur, color, shadowColorSpace); drawIntoBitmap = offset.width() || offset.height() || blur; } } // We have to convert CG's two-dimensional floating point advances to just horizontal integer advances. Vector<int, 2048> gdiAdvances; int totalWidth = 0; for (int i = 0; i < numGlyphs; i++) { gdiAdvances.append(lroundf(glyphBuffer.advanceAt(from + i))); totalWidth += gdiAdvances[i]; } HDC hdc = 0; OwnPtr<GraphicsContext::WindowsBitmap> bitmap; IntRect textRect; if (!drawIntoBitmap) hdc = graphicsContext->getWindowsContext(textRect, true, false); if (!hdc) { drawIntoBitmap = true; // We put slop into this rect, since glyphs can overflow the ascent/descent bounds and the left/right edges. // FIXME: Can get glyphs' optical bounds (even from CG) to get this right. const FontMetrics& fontMetrics = font->fontMetrics(); int lineGap = fontMetrics.lineGap(); textRect = IntRect(point.x() - (fontMetrics.ascent() + fontMetrics.descent()) / 2, point.y() - fontMetrics.ascent() - lineGap, totalWidth + fontMetrics.ascent() + fontMetrics.descent(), fontMetrics.lineSpacing()); bitmap = graphicsContext->createWindowsBitmap(textRect.size()); memset(bitmap->buffer(), 255, bitmap->bufferLength()); hdc = bitmap->hdc(); XFORM xform; xform.eM11 = 1.0f; xform.eM12 = 0.0f; xform.eM21 = 0.0f; xform.eM22 = 1.0f; xform.eDx = -textRect.x(); xform.eDy = -textRect.y(); SetWorldTransform(hdc, &xform); } SelectObject(hdc, font->platformData().hfont()); // Set the correct color. if (drawIntoBitmap) SetTextColor(hdc, RGB(0, 0, 0)); else SetTextColor(hdc, RGB(fillColor.red(), fillColor.green(), fillColor.blue())); SetBkMode(hdc, TRANSPARENT); SetTextAlign(hdc, TA_LEFT | TA_BASELINE); // Uniscribe gives us offsets to help refine the positioning of combining glyphs. FloatSize translation = glyphBuffer.offsetAt(from); if (translation.width() || translation.height()) { XFORM xform; xform.eM11 = 1.0; xform.eM12 = 0; xform.eM21 = 0; xform.eM22 = 1.0; xform.eDx = translation.width(); xform.eDy = translation.height(); ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY); } if (drawingMode == TextModeFill) { XFORM xform; xform.eM11 = 1.0; xform.eM12 = 0; xform.eM21 = font->platformData().syntheticOblique() ? -tanf(syntheticObliqueAngle * piFloat / 180.0f) : 0; xform.eM22 = 1.0; xform.eDx = point.x(); xform.eDy = point.y(); ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY); ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, reinterpret_cast<const WCHAR*>(glyphBuffer.glyphs(from)), numGlyphs, gdiAdvances.data()); if (font->syntheticBoldOffset()) { xform.eM21 = 0; xform.eDx = font->syntheticBoldOffset(); xform.eDy = 0; ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY); ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, reinterpret_cast<const WCHAR*>(glyphBuffer.glyphs(from)), numGlyphs, gdiAdvances.data()); } } else { XFORM xform; GetWorldTransform(hdc, &xform); AffineTransform hdcTransform(xform.eM11, xform.eM21, xform.eM12, xform.eM22, xform.eDx, xform.eDy); CGAffineTransform initialGlyphTransform = hdcTransform.isInvertible() ? hdcTransform.inverse() : CGAffineTransformIdentity; if (font->platformData().syntheticOblique()) initialGlyphTransform = CGAffineTransformConcat(initialGlyphTransform, CGAffineTransformMake(1, 0, tanf(syntheticObliqueAngle * piFloat / 180.0f), 1, 0, 0)); initialGlyphTransform.tx = 0; initialGlyphTransform.ty = 0; CGContextRef cgContext = graphicsContext->platformContext(); CGContextSaveGState(cgContext); BOOL fontSmoothingEnabled = false; SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &fontSmoothingEnabled, 0); CGContextSetShouldAntialias(cgContext, fontSmoothingEnabled); CGContextScaleCTM(cgContext, 1.0, -1.0); CGContextTranslateCTM(cgContext, point.x() + glyphBuffer.offsetAt(from).width(), -(point.y() + glyphBuffer.offsetAt(from).height())); for (unsigned i = 0; i < numGlyphs; ++i) { RetainPtr<CGPathRef> glyphPath(AdoptCF, createPathForGlyph(hdc, glyphBuffer.glyphAt(from + i))); CGContextSaveGState(cgContext); CGContextConcatCTM(cgContext, initialGlyphTransform); if (drawingMode & TextModeFill) { CGContextAddPath(cgContext, glyphPath.get()); CGContextFillPath(cgContext); if (font->syntheticBoldOffset()) { CGContextTranslateCTM(cgContext, font->syntheticBoldOffset(), 0); CGContextAddPath(cgContext, glyphPath.get()); CGContextFillPath(cgContext); CGContextTranslateCTM(cgContext, -font->syntheticBoldOffset(), 0); } } if (drawingMode & TextModeStroke) { CGContextAddPath(cgContext, glyphPath.get()); CGContextStrokePath(cgContext); if (font->syntheticBoldOffset()) { CGContextTranslateCTM(cgContext, font->syntheticBoldOffset(), 0); CGContextAddPath(cgContext, glyphPath.get()); CGContextStrokePath(cgContext); CGContextTranslateCTM(cgContext, -font->syntheticBoldOffset(), 0); } } CGContextRestoreGState(cgContext); CGContextTranslateCTM(cgContext, gdiAdvances[i], 0); } CGContextRestoreGState(cgContext); } if (drawIntoBitmap) { UInt8* buffer = bitmap->buffer(); unsigned bufferLength = bitmap->bufferLength(); for (unsigned i = 0; i < bufferLength; i += 4) { // Use green, which is always in the middle. UInt8 alpha = (255 - buffer[i + 1]) * fillColor.alpha() / 255; buffer[i] = fillColor.blue(); buffer[i + 1] = fillColor.green(); buffer[i + 2] = fillColor.red(); buffer[i + 3] = alpha; } graphicsContext->drawWindowsBitmap(bitmap.get(), textRect.location()); } else graphicsContext->releaseWindowsContext(hdc, textRect, true, false); }
static void initBackground(unsigned w, unsigned h, unsigned max) { CGColorSpaceRef colorspace; CGContextRef gc; unsigned char *data; float cx, cy; float radius, needle; data = (unsigned char *)malloc(w * h * 4); colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); gc = CGBitmapContextCreate(data, w, h, 8, w * 4, colorspace, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host); cx = CENTERX * w; cy = CENTERY * h; radius = 0.5 * (w > h ? w : h); needle = radius * 0.85; // background CGContextTranslateCTM(gc, 0.0, h); CGContextScaleCTM(gc, 1.0, -1.0); CGContextClearRect(gc, CGRectMake(0, 0, w, h)); CGContextSetRGBFillColor(gc, 0.0, 0.0, 0.0, 0.7); CGContextAddArc(gc, cx, cy, radius, 0, 2*M_PI, false); CGContextFillPath(gc); CGGradientRef gradient; size_t num_locations = 2; CGFloat locations[2] = { 0.0, 1.0 }; CGFloat components[8] = { 1.0, 1.0, 1.0, 0.5, // Start color 0.0, 0.0, 0.0, 0.0 }; // End color gradient = CGGradientCreateWithColorComponents (colorspace, components, locations, num_locations); // top rim light CGContextSaveGState(gc); CGContextAddArc(gc, cx, cy, radius, 0, 2*M_PI, false); CGContextAddArc(gc, cx, cy, needle*1.05, 0, 2*M_PI, false); CGContextEOClip(gc); CGContextDrawRadialGradient (gc, gradient, CGPointMake(cx, cy*1.00), radius*1.01, CGPointMake(cx, cy*0.96), radius*0.98, 0); // bottom rim light CGContextDrawRadialGradient (gc, gradient, CGPointMake(cx, cy*1.00), radius*1.01, CGPointMake(cx, cy*1.04), radius*0.98, 0); // top bevel CGContextDrawRadialGradient (gc, gradient, CGPointMake(cx, cy*2.2), radius*0.2, CGPointMake(cx, cy*1.0), radius*1.0, 0); // bottom bevel CGContextRestoreGState(gc); CGContextSaveGState(gc); CGContextAddArc(gc, cx, cy, needle*1.05, 0, 2*M_PI, false); CGContextAddArc(gc, cx, cy, needle*0.96, 0, 2*M_PI, false); CGContextEOClip(gc); CGContextDrawRadialGradient (gc, gradient, CGPointMake(cx, cy* -.5), radius*0.2, CGPointMake(cx, cy*1.0), radius*1.0, 0); CGGradientRelease(gradient); CGContextRestoreGState(gc); CGContextSetRGBFillColor(gc, 0.9, 0.9, 1.0, 1.0); CGContextSetRGBStrokeColor(gc, 0.9, 0.9, 1.0, 1.0); CGContextSetLineCap(gc, kCGLineCapRound); // draw several glow passes, with the content offscreen CGContextTranslateCTM(gc, 0, OFFSCREEN - 10); CGContextSetShadowWithColor(gc, CGSizeMake(0, OFFSCREEN), 48.0, CGColorCreateGenericRGB(0.5, 0.5, 1.0, 0.7)); drawMarks(gc, w, h, max); CGContextTranslateCTM(gc, 0, 20); CGContextSetShadowWithColor(gc, CGSizeMake(0, OFFSCREEN), 48.0, CGColorCreateGenericRGB(0.5, 0.5, 1.0, 0.7)); drawMarks(gc, w, h, max); CGContextTranslateCTM(gc, -10, -10); CGContextSetShadowWithColor(gc, CGSizeMake(0, OFFSCREEN), 48.0, CGColorCreateGenericRGB(0.5, 0.5, 1.0, 0.7)); drawMarks(gc, w, h, max); CGContextTranslateCTM(gc, 20, 0); CGContextSetShadowWithColor(gc, CGSizeMake(0, OFFSCREEN), 48.0, CGColorCreateGenericRGB(0.5, 0.5, 1.0, 0.7)); drawMarks(gc, w, h, max); CGContextTranslateCTM(gc, -10, -OFFSCREEN); // draw real content CGContextSetShadowWithColor(gc, CGSizeMake(0, 1), 6.0, CGColorCreateGenericRGB(0.7, 0.7, 1.0, 0.9)); drawMarks(gc, w, h, max); glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, w, h, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data); CGContextRelease(gc); CGColorSpaceRelease(colorspace); free(data); }
void doClippedEllipse(CGContextRef context) { CGPoint theCenterPoint = { 120., 120. }; CGSize theEllipseSize = { 100., 200. }; float dash[1] = { 2 }; static CGColorRef opaqueBrownColor = NULL, opaqueOrangeColor = NULL; // Initialize the CGColorRefs if necessary. if(opaqueBrownColor == NULL){ // The initial value of the color array is an // opaque brown in an RGB color space. float color[4] = { 0.325, 0.208, 0.157, 1.0 }; CGColorSpaceRef theColorSpace = getTheCalibratedRGBColorSpace(); // Create a CGColorRef for opaque brown. opaqueBrownColor = CGColorCreate(theColorSpace, color); // Make the color array correspond to an opaque orange. color[0] = 0.965 ; color[1] = 0.584; color[2] = 0.059; // Create another CGColorRef for opaque orange. opaqueOrangeColor = CGColorCreate(theColorSpace, color); } // Draw two ellipses centered about the same point, one // rotated 45 degrees from the other. CGContextSaveGState(context); // Ellipse 1 createEllipsePath(context, theCenterPoint, theEllipseSize); CGContextSetFillColorWithColor(context, opaqueBrownColor); CGContextFillPath(context); // Translate and rotate about the center point of the ellipse. CGContextTranslateCTM(context, theCenterPoint.x, theCenterPoint.y); // Rotate by 45 degrees. CGContextRotateCTM(context, DEGREES_TO_RADIANS(45)); // Ellipse 2 // CGPointZero is a pre-defined Quartz point corresponding to // the coordinate (0,0). createEllipsePath(context, CGPointZero, theEllipseSize); CGContextSetFillColorWithColor(context, opaqueOrangeColor); CGContextFillPath(context); CGContextRestoreGState(context); CGContextTranslateCTM(context, 170., 0.); // Now use the first ellipse as a clipping area prior to // painting the second ellipse. CGContextSaveGState(context); // Ellipse 3 createEllipsePath(context, theCenterPoint, theEllipseSize); CGContextSetStrokeColorWithColor(context, opaqueBrownColor); CGContextSetLineDash(context, 0, dash, 1); // Stroke the path with a dash. CGContextStrokePath(context); // Ellipse 4 createEllipsePath(context, theCenterPoint, theEllipseSize); // Clip to the elliptical path. CGContextClip(context); CGContextTranslateCTM(context, theCenterPoint.x, theCenterPoint.y); // Rotate by 45 degrees. CGContextRotateCTM(context, DEGREES_TO_RADIANS(45)); // Ellipse 5 createEllipsePath(context, CGPointZero, theEllipseSize); CGContextSetFillColorWithColor(context, opaqueOrangeColor); CGContextFillPath(context); CGContextRestoreGState(context); }