Exemplo n.º 1
0
void JBGStrokePathByLines(CGContextRef ctx, CGPathRef path, CGColorRef color_1, CGFloat width_1, CGColorRef color_2, CGFloat width_2, CGColorRef color_3, CGFloat width_3)
{
    if (width_1 > 0.0f)
    {
        CGContextSetLineWidth(ctx, width_1);
        CGContextAddPath(ctx, path);
        CGContextSetStrokeColorWithColor(ctx, color_1);
        CGContextStrokePath(ctx);
    }

    if (width_2 > 0.0f)
    {
        CGContextAddPath(ctx, path);
        CGContextSetStrokeColorWithColor(ctx, color_2);
        CGContextSetLineWidth(ctx, width_2);
        CGContextStrokePath(ctx);
    }
    
    if (width_3 > 0.0f)
    {
        CGContextAddPath(ctx, path);
        CGContextSetStrokeColorWithColor(ctx, color_3);
        CGContextSetLineWidth(ctx, width_3);
        CGContextStrokePath(ctx);
    }
}
void doStrokeWithCTM(CGContextRef context)
{
	CGContextTranslateCTM(context, 150., 180.);
	CGContextSetLineWidth(context, 10);
	// Draw ellipse 1 with a uniform stroke.
	CGContextSaveGState(context);
		// Scale the CTM so the circular arc will be elliptical.
		CGContextScaleCTM(context, 2, 1);
		CGContextBeginPath(context);
		// Create an arc that is a circle.
		CGContextAddArc(context, 0., 0., 45., 0., 2*M_PI, 0);
	// Restore the context parameters prior to stroking the path.
	// CGContextRestoreGState does not affect the path in the context.
	CGContextRestoreGState(context);
	CGContextStrokePath(context);
	
	// *** was 0, -120
	CGContextTranslateCTM(context, 220., 0.);
	// Draw ellipse 2 with non-uniform stroke.
	CGContextSaveGState(context);
		// Scale the CTM so the circular arc will be elliptical.
		CGContextScaleCTM(context, 2, 1);
		CGContextBeginPath(context);
		// Create an arc that is a circle.
		CGContextAddArc(context, 0., 0., 45., 0., 2*M_PI, 0);
		// Stroke the path with the scaled coordinate system in effect.
		CGContextStrokePath(context);
	CGContextRestoreGState(context);
}
//-----------------------------------------------------------------------------------
static void DrawTheMTView(CGContextRef ctx, MTViewData* data)
{
    CGRect dstRect;

#if CG_COORDINATES
    TransformHIViewToCG(ctx, data->theView);
#endif

    // Draw the image first, before stroking the path; otherwise the path gets overwritten
    if (data->theImage != NULL)
    {
	dstRect = CGRectMake(0, 0, CGImageGetWidth(data->theImage), CGImageGetHeight(data->theImage));
#if CG_COORDINATES
	CGContextDrawImage(ctx, dstRect, data->theImage);
#else
	HIViewDrawCGImage(ctx, &dstRect, data->theImage);
#endif
    }
    
    if (data->thePath != NULL)
    {
	CGPathApply(data->thePath, (void*)ctx, MyCGPathApplier);
	CGContextStrokePath(ctx);
    }
}   // DrawTheMTView
Exemplo n.º 4
0
void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points, bool shouldAntialias)
{
    if (paintingDisabled())
        return;

    if (npoints <= 1)
        return;

    CGContextRef context = platformContext();

    CGContextSaveGState(context);

    CGContextSetShouldAntialias(context, shouldAntialias);
    
    CGContextBeginPath(context);
    CGContextMoveToPoint(context, points[0].x(), points[0].y());
    for (size_t i = 1; i < npoints; i++)
        CGContextAddLineToPoint(context, points[i].x(), points[i].y());
    CGContextClosePath(context);

    if (fillColor().alpha())
        CGContextEOFillPath(context);

    if (strokeStyle() != NoStroke)
        CGContextStrokePath(context);

    CGContextRestoreGState(context);
}
Exemplo n.º 5
0
// 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);
}
Exemplo n.º 6
0
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) );

}
Exemplo n.º 7
0
static void 	Quartz_Polyline(int n, double *x, double *y,
				R_GE_gcontext *gc,
				NewDevDesc *dd)
{
  	CGPoint *lines;
    int	i;
    CGrafPtr savedPort, port;
    QuartzDesc *xd = (QuartzDesc*)dd->deviceSpecific;

    lines = (CGPoint *)malloc(sizeof(CGPoint)*n);

    if(lines == NULL)
     return;

    for (i = 0; i < n; i++) {
	  lines[i].x = (float)x[i];
	  lines[i].y = (float)y[i];
	 }


    CGContextSaveGState( GetContext(xd) );

    CGContextBeginPath( GetContext(xd) );

    Quartz_SetLineProperties(gc, dd);

    CGContextAddLines( GetContext(xd), &lines[0], n );
    Quartz_SetStroke( gc->col, gc->gamma, dd);
    CGContextStrokePath( GetContext(xd) );

    CGContextRestoreGState( GetContext(xd) );

}
Exemplo n.º 8
0
static void 	Quartz_Line(double x1, double y1, double x2, double y2,
			    R_GE_gcontext *gc,
			    NewDevDesc *dd)
{
    QuartzDesc *xd = (QuartzDesc*)dd->deviceSpecific;
    CGPoint lines[ 2 ];
    Rect rect;

    CGContextSaveGState( GetContext(xd) );


    CGContextBeginPath( GetContext(xd) );

    lines[0].x = (float)x1;
    lines[0].y = (float)y1;
    lines[1].x = (float)x2;
    lines[1].y = (float)y2;

    Quartz_SetLineProperties(gc, dd);

    CGContextAddLines( GetContext(xd), &lines[0], 2 );

    Quartz_SetStroke( gc->col, gc->gamma,  dd);

    CGContextStrokePath( GetContext(xd) );

    CGContextRestoreGState( GetContext(xd) );

}
Exemplo n.º 9
0
FX_BOOL CFX_QuartzDeviceDriver::DrawCosmeticLine(FX_FLOAT           x1,
        FX_FLOAT              y1,
        FX_FLOAT              x2,
        FX_FLOAT              y2,
        FX_DWORD              argb,
        int                   alphaFlag       ,
        void*                 iccTransform    ,
        int					blend_type )
{
    CGBlendMode mode = GetCGBlendMode(blend_type);
    if (mode != kCGBlendModeNormal) {
        CGContextSetBlendMode(_context, mode);
    }
    CGPoint pt = CGPointApplyAffineTransform(CGPointMake(x1, y1), _foxitDevice2User);
    x1 = pt.x;
    y1 = pt.y;
    pt = CGPointApplyAffineTransform(CGPointMake(x2, y2), _foxitDevice2User);
    x2 = pt.x;
    y2 = pt.y;
    FX_INT32 a, r, g, b;
    ArgbDecode(argb, a, r, g, b);
    CGContextSetRGBStrokeColor(_context,
                               r / 255.f,
                               g / 255.f,
                               b / 255.f,
                               a / 255.f);
    CGContextMoveToPoint(_context, x1, y1);
    CGContextAddLineToPoint(_context, x2, y2);
    CGContextStrokePath(_context);
    if (mode != kCGBlendModeNormal) {
        CGContextSetBlendMode(_context, kCGBlendModeNormal);
    }
    return TRUE;
}
Exemplo n.º 10
0
void MacVegaPrinterListener::DrawEllipse(const OpRect& rect, UINT32 width)
{
	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(width != 1)
	{
		CGContextSetLineWidth(m_ctx, width);
	}
	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);

	CGContextStrokePath(m_ctx);

	if(width != 1)
	{
		CGContextSetLineWidth(m_ctx, 1);
	}
	if(cgrect.size.width != cgrect.size.height)
	{
		CGContextScaleCTM(m_ctx, 1.0, cgrect.size.width/cgrect.size.height);
	}
}
void doPixelAlignedFillAndStroke(CGContextRef context)
{
    CGPoint p1 = CGPointMake(16.7, 17.8);
    CGPoint p2 = CGPointMake(116.7, 17.8);
    CGRect r = CGRectMake(16.7, 20.8, 100.6, 100.6);
    CGSize s;
    
    CGContextSetLineWidth(context, 2);
    CGContextSetRGBFillColor(context, 1., 0., 0., 1.);
    CGContextSetRGBStrokeColor(context, 1., 0., 0., 1.);
    
    // Unaligned drawing.
    CGContextBeginPath(context);
    CGContextMoveToPoint(context, p1.x, p1.y);
    CGContextAddLineToPoint(context, p2.x, p2.y);
    CGContextStrokePath(context);
    CGContextFillRect(context, r);
    
    // Translate to the right before drawing along
    // aligned coordinates.
    CGContextTranslateCTM(context, 106, 0);
    
    // Aligned drawing.
    
    // Compute the length of the line in user space.
    s = CGSizeMake(p2.x - p1.x, p2.y - p1.y);
    
    CGContextBeginPath(context);
    // Align the starting point to a device
    // pixel boundary.
    p1 = alignPointToUserSpace(context, p1);
    // Establish the starting point of the line.
    CGContextMoveToPoint(context, p1.x, p1.y);
    // Compute the line length as an integer
    // number of device pixels.
    s = alignSizeToUserSpace(context, s);
    CGContextAddLineToPoint(context, 
				p1.x + s.width, 
				p1.y + s.height);
    CGContextStrokePath(context);
    // Compute a rect that is aligned to device
    // space with a width that is an integer
    // number of device pixels.
    r = alignRectToUserSpace(context, r);
    CGContextFillRect(context, r);
}
Exemplo n.º 12
0
/*
frameOval : Draws an outline of an oval just inside the bounding rectangle that you specify.

Parameter Descriptions
context : The CG context to render to.
r :  The CG rectangle that defines the ovalÕs boundary.
*/
void frameOval(CGContextRef context, CGRect r)
{
	// Add a path for the oval to this context
	addOvalToPath(context,r);

	// Stroke the path
	CGContextStrokePath(context);
}
Exemplo n.º 13
0
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;
}
Exemplo n.º 14
0
/*
strokeRoundedRect : Draws a rounded rectangle with the current stroke 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 strokeRoundedRect(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);
	// Stroke the path
	CGContextStrokePath(context);
}
Exemplo n.º 15
0
void frameArc(CGContextRef context, CGRect r, int startAngle, int arcAngle)
{

	// Signal the start of a path
    CGContextBeginPath(context);

	// Add to the path the arc of the oval that fits inside the rectangle.
	pathForArc(context,r,startAngle,arcAngle);
	
	// Stroke the path
    CGContextStrokePath(context);
}
Exemplo n.º 16
0
bool GiCanvasIos::rawLine(const GiContext* ctx, float x1, float y1, float x2, float y2)
{
    bool ret = m_draw->setPen(ctx);

    if (ret)
    {
        CGContextMoveToPoint(m_draw->getContext(), x1, y1);
        CGContextAddLineToPoint(m_draw->getContext(), x2, y2);
        CGContextStrokePath(m_draw->getContext());
    }

    return ret;
}
Exemplo n.º 17
0
void JBGFillGradientCircle(CGContextRef ctx, CGPoint center_1, CGFloat r_1, CGPoint center_2, CGFloat r_2, CGGradientRef fill_gradient, CGColorRef stroke_color)
{
    if (fill_gradient)
    {
        CGGradientDrawingOptions options = kCGGradientDrawsBeforeStartLocation;
        CGContextDrawRadialGradient(ctx, fill_gradient, center_1, r_1, center_2, r_2, options);
    }
    
    if (stroke_color)
    {
        CGContextSetStrokeColorWithColor(ctx, stroke_color);
        CGContextAddArc(ctx, center_2.x, center_2.y, r_2, 0, M_PI * 2, false);
        CGContextStrokePath(ctx);
    }
}
Exemplo n.º 18
0
bool GiCanvasIos::rawLines(const GiContext* ctx, const Point2d* pxs, int count)
{
    bool ret = m_draw->setPen(ctx) && count > 1;

    if (ret)
    {
        CGContextMoveToPoint(m_draw->getContext(), pxs[0].x, pxs[0].y);
        for (int i = 1; i < count; i++) {
            CGContextAddLineToPoint(m_draw->getContext(), pxs[i].x, pxs[i].y);
        }
        CGContextStrokePath(m_draw->getContext());
    }

    return ret;
}
void CanvasRenderingContext2D::stroke()
{
    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()) {
        float lineWidth = state().m_lineWidth;
        float inset = -lineWidth / 2;
        CGRect boundingRect = CGRectInset(CGContextGetPathBoundingBox(c->platformContext()), inset, inset);
        willDraw(boundingRect);
    }

    if (state().m_strokeStyle->gradient()) {
        // Shading works on the entire clip region, so convert the current path to a clip.
        c->save();
        CGContextReplacePathWithStrokedPath(c->platformContext());
        CGContextClip(c->platformContext());
        CGContextDrawShading(c->platformContext(), state().m_strokeStyle->gradient()->platformShading());        
        c->restore();
    } else {
        if (state().m_strokeStyle->pattern())
            applyStrokePattern();
        CGContextStrokePath(c->platformContext());
    }
#elif PLATFORM(QT)
    QPainterPath* path = state().m_path.platformPath();
    QPainter* p = static_cast<QPainter*>(c->platformContext());
    willDraw(path->controlPointRect());
    if (state().m_strokeStyle->gradient()) {
        p->save();
        p->setBrush(*(state().m_strokeStyle->gradient()->platformShading()));
        p->strokePath(*path, p->pen());
        p->restore();
    } else {
        if (state().m_strokeStyle->pattern())
            applyStrokePattern();
        p->strokePath(*path, p->pen());
    }
#endif

    clearPathForDashboardBackwardCompatibilityMode();
}
Exemplo n.º 20
0
void MacVegaPrinterListener::DrawLine(const OpPoint& from, const OpPoint& to, UINT32 width)
{
	if(width != 1)
	{
		CGContextSetLineWidth(m_ctx, width);
	}

	CGContextBeginPath(m_ctx);

	CGContextMoveToPoint(m_ctx, from.x, m_winHeight - from.y);
	CGContextAddLineToPoint(m_ctx, to.x, m_winHeight - to.y);

	CGContextStrokePath(m_ctx);

	if(width != 1)
	{
		CGContextSetLineWidth(m_ctx, 1);
	}
}
Exemplo n.º 21
0
bool GiCanvasIos::rawBeziers(const GiContext* ctx, const Point2d* pxs, int count)
{
    bool ret = m_draw->setPen(ctx) && count > 1;

    if (ret)
    {
        CGContextMoveToPoint(m_draw->getContext(), pxs[0].x, pxs[0].y);
        for (int i = 1; i + 2 < count; i += 3)
        {
            CGContextAddCurveToPoint(m_draw->getContext(), 
                pxs[i+0].x, pxs[i+0].y,
                pxs[i+1].x, pxs[i+1].y,
                pxs[i+2].x, pxs[i+2].y);
        }
        CGContextStrokePath(m_draw->getContext());
    }

    return ret;
}
Exemplo n.º 22
0
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);
}
Exemplo n.º 23
0
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) );

}
Exemplo n.º 24
0
void GraphicsContext::strokePath(const Path& path)
{
    if (paintingDisabled())
        return;

    CGContextRef context = platformContext();

    CGContextBeginPath(context);
    CGContextAddPath(context, path.platformPath());

    if (m_state.strokeGradient) {
        CGContextSaveGState(context);
        CGContextReplacePathWithStrokedPath(context);
        CGContextClip(context);
        CGContextConcatCTM(context, m_state.strokeGradient->gradientSpaceTransform());
        m_state.strokeGradient->paint(this);
        CGContextRestoreGState(context);
        return;
    }

    if (m_state.strokePattern)
        applyStrokePattern();
    CGContextStrokePath(context);
}
Exemplo n.º 25
0
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);
}
Exemplo n.º 26
0
void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan)
{
    if (paintingDisabled() || strokeStyle() == NoStroke || strokeThickness() <= 0.0f)
        return;

    CGContextRef context = platformContext();
    CGContextSaveGState(context);
    CGContextBeginPath(context);
    CGContextSetShouldAntialias(context, false);

    int x = rect.x();
    int y = rect.y();
    float w = (float)rect.width();
    float h = (float)rect.height();
    float scaleFactor = h / w;
    float reverseScaleFactor = w / h;

    if (w != h)
        scale(FloatSize(1, scaleFactor));

    float hRadius = w / 2;
    float vRadius = h / 2;
    float fa = startAngle;
    float falen =  fa + angleSpan;
    float start = -fa * piFloat / 180.0f;
    float end = -falen * piFloat / 180.0f;
    CGContextAddArc(context, x + hRadius, (y + vRadius) * reverseScaleFactor, hRadius, start, end, true);

    if (w != h)
        scale(FloatSize(1, reverseScaleFactor));

    float width = strokeThickness();
    int patWidth = 0;

    switch (strokeStyle()) {
    case DottedStroke:
        patWidth = (int)(width / 2);
        break;
    case DashedStroke:
        patWidth = 3 * (int)(width / 2);
        break;
    default:
        break;
    }

    if (patWidth) {
        // Example: 80 pixels with a width of 30 pixels.
        // Remainder is 20.  The maximum pixels of line we could paint
        // will be 50 pixels.
        int distance;
        if (hRadius == vRadius)
            distance = static_cast<int>((piFloat * hRadius) / 2.0f);
        else // We are elliptical and will have to estimate the distance
            distance = static_cast<int>((piFloat * sqrtf((hRadius * hRadius + vRadius * vRadius) / 2.0f)) / 2.0f);

        int remainder = distance % patWidth;
        int coverage = distance - remainder;
        int numSegments = coverage / patWidth;

        float patternOffset = 0.0f;
        // Special case 1px dotted borders for speed.
        if (patWidth == 1)
            patternOffset = 1.0f;
        else {
            bool evenNumberOfSegments = !(numSegments % 2);
            if (remainder)
                evenNumberOfSegments = !evenNumberOfSegments;
            if (evenNumberOfSegments) {
                if (remainder) {
                    patternOffset += patWidth - remainder;
                    patternOffset += remainder / 2.0f;
                } else
                    patternOffset = patWidth / 2.0f;
            } else {
                if (remainder)
                    patternOffset = (patWidth - remainder) / 2.0f;
            }
        }

        const CGFloat dottedLine[2] = { patWidth, patWidth };
        CGContextSetLineDash(context, patternOffset, dottedLine, 2);
    }

    CGContextStrokePath(context);

    CGContextRestoreGState(context);
}
Exemplo n.º 27
0
// This is only used to draw borders.
void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
{
    if (paintingDisabled())
        return;

    if (strokeStyle() == NoStroke)
        return;

    float width = strokeThickness();

    FloatPoint p1 = point1;
    FloatPoint p2 = point2;
    bool isVerticalLine = (p1.x() == p2.x());
    
    // For odd widths, we add in 0.5 to the appropriate x/y so that the float arithmetic
    // works out.  For example, with a border width of 3, KHTML will pass us (y1+y2)/2, e.g.,
    // (50+53)/2 = 103/2 = 51 when we want 51.5.  It is always true that an even width gave
    // us a perfect position, but an odd width gave us a position that is off by exactly 0.5.
    if (strokeStyle() == DottedStroke || strokeStyle() == DashedStroke) {
        if (isVerticalLine) {
            p1.move(0, width);
            p2.move(0, -width);
        } else {
            p1.move(width, 0);
            p2.move(-width, 0);
        }
    }
    
    if (((int)width) % 2) {
        if (isVerticalLine) {
            // We're a vertical line.  Adjust our x.
            p1.move(0.5f, 0.0f);
            p2.move(0.5f, 0.0f);
        } else {
            // We're a horizontal line. Adjust our y.
            p1.move(0.0f, 0.5f);
            p2.move(0.0f, 0.5f);
        }
    }
    
    int patWidth = 0;
    switch (strokeStyle()) {
    case NoStroke:
    case SolidStroke:
        break;
    case DottedStroke:
        patWidth = (int)width;
        break;
    case DashedStroke:
        patWidth = 3 * (int)width;
        break;
    }

    CGContextRef context = platformContext();

    if (shouldAntialias())
        CGContextSetShouldAntialias(context, false);

    if (patWidth) {
        CGContextSaveGState(context);

        // Do a rect fill of our endpoints.  This ensures we always have the
        // appearance of being a border.  We then draw the actual dotted/dashed line.
        setCGFillColor(context, strokeColor(), strokeColorSpace());  // The save/restore make it safe to mutate the fill color here without setting it back to the old color.
        if (isVerticalLine) {
            CGContextFillRect(context, FloatRect(p1.x() - width / 2, p1.y() - width, width, width));
            CGContextFillRect(context, FloatRect(p2.x() - width / 2, p2.y(), width, width));
        } else {
            CGContextFillRect(context, FloatRect(p1.x() - width, p1.y() - width / 2, width, width));
            CGContextFillRect(context, FloatRect(p2.x(), p2.y() - width / 2, width, width));
        }

        // Example: 80 pixels with a width of 30 pixels.
        // Remainder is 20.  The maximum pixels of line we could paint
        // will be 50 pixels.
        int distance = (isVerticalLine ? (point2.y() - point1.y()) : (point2.x() - point1.x())) - 2*(int)width;
        int remainder = distance % patWidth;
        int coverage = distance - remainder;
        int numSegments = coverage / patWidth;

        float patternOffset = 0.0f;
        // Special case 1px dotted borders for speed.
        if (patWidth == 1)
            patternOffset = 1.0f;
        else {
            bool evenNumberOfSegments = !(numSegments % 2);
            if (remainder)
                evenNumberOfSegments = !evenNumberOfSegments;
            if (evenNumberOfSegments) {
                if (remainder) {
                    patternOffset += patWidth - remainder;
                    patternOffset += remainder / 2;
                } else
                    patternOffset = patWidth / 2;
            } else {
                if (remainder)
                    patternOffset = (patWidth - remainder)/2;
            }
        }

        const CGFloat dottedLine[2] = { patWidth, patWidth };
        CGContextSetLineDash(context, patternOffset, dottedLine, 2);
    }

    CGContextBeginPath(context);
    CGContextMoveToPoint(context, p1.x(), p1.y());
    CGContextAddLineToPoint(context, p2.x(), p2.y());

    CGContextStrokePath(context);

    if (patWidth)
        CGContextRestoreGState(context);

    if (shouldAntialias())
        CGContextSetShouldAntialias(context, true);
}
Exemplo n.º 28
0
void QuartzWindow::draw_line(int x1, int y1, int x2, int y2) {
  CGContextBeginPath(myContext);
  CGContextMoveToPoint(myContext, x1, y1);
  CGContextAddLineToPoint(myContext, x2, y2);
  CGContextStrokePath(myContext);
}
Exemplo n.º 29
0
static void MusicBoxDrawIndicator(HIViewRef view, CGContextRef mboxctx)
{
	if (!showIndicator)
		return;

	// Bar

	const double	length[] = { 1.0, 1.0 };

	CGContextSetLineWidth(mboxctx, mbxBarWidth);
	CGContextSetLineDash(mboxctx, 0, length, 2);
	CGContextSetLineJoin(mboxctx, kCGLineJoinMiter);

	CGContextBeginPath(mboxctx);

	double   x = mbxOffsetX + mbxMarginX + mbxBarWidth / 2.0;
	for (int h = 0; h < 8; h++)
	{
		// Inactive

		CGContextSetRGBStrokeColor(mboxctx, (196.0 / 256.0), (200.0 / 256.0), (176.0 / 256.0), 1.0);

		CGContextMoveToPoint   (mboxctx, x,                mbxOffsetY + mbxMarginY);
		CGContextAddLineToPoint(mboxctx, x,                mbxOffsetY + mbxMarginY + mbxBarHeight);

		CGContextMoveToPoint   (mboxctx, x + mbxRightBarX, mbxOffsetY + mbxMarginY);
		CGContextAddLineToPoint(mboxctx, x + mbxRightBarX, mbxOffsetY + mbxMarginY + mbxBarHeight);

		CGContextStrokePath(mboxctx);

		// Max

		Channel	*ch = &SoundData.channels[h];

		ch->envx = ch->xenvx >> 4;
		ch-> left_vol_level = (ch->xenvx * ch->volume_left ) >> 11;
		ch->right_vol_level = (ch->xenvx * ch->volume_right) >> 11;

		short		vl = ch-> left_vol_level;
		short		vr = ch->right_vol_level;
		long long	currentTime;

		if (vl <= 0) vl = 0; else if (vl > 64) vl = 64; else vl = (short) (yyscale * sqrt((double) vl)) & (~0 << 1);
		if (vr <= 0) vr = 0; else if (vr > 64) vr = 64; else vr = (short) (yyscale * sqrt((double) vr)) & (~0 << 1);

		if (vl < prevLVol[h]) vl = ((prevLVol[h] + vl) >> 1);
		if (vr < prevRVol[h]) vr = ((prevRVol[h] + vr) >> 1);

		Microseconds((UnsignedWide *) &currentTime);

		// left

		if ((vl >= prevLMax[h]) && (vl > prevLVol[h]))
		{
			barTimeL[h] = currentTime;
			prevLMax[h] = vl;
		}
		else
		if ((prevLMax[h] > 0) && (barTimeL[h] + 1000000 > currentTime))
		{
			CGContextSetRGBStrokeColor(mboxctx, (22.0 / 256.0), (156.0 / 256.0), (20.0 / 256.0), (double) (barTimeL[h] + 1000000 - currentTime) / 1000000.0);

			CGContextMoveToPoint   (mboxctx, x, mbxOffsetY + mbxMarginY + (double) (prevLMax[h] - 2));
			CGContextAddLineToPoint(mboxctx, x, mbxOffsetY + mbxMarginY + (double) (prevLMax[h]    ));

			CGContextStrokePath(mboxctx);
		}
		else
			prevLMax[h] = 0;

		prevLVol[h] = vl;

		// right

		if ((vr >= prevRMax[h]) && (vr > prevRVol[h]))
		{
			barTimeR[h] = currentTime;
			prevRMax[h] = vr;
		}
		else
		if ((prevRMax[h] > 0) && (barTimeR[h] + 1000000 > currentTime))
		{
			CGContextSetRGBStrokeColor(mboxctx, (22.0 / 256.0), (156.0 / 256.0), (20.0 / 256.0), (double) (barTimeR[h] + 1000000 - currentTime) / 1000000.0);

			CGContextMoveToPoint   (mboxctx, x + mbxRightBarX, mbxOffsetY + mbxMarginY + (double) (prevRMax[h] - 2));
			CGContextAddLineToPoint(mboxctx, x + mbxRightBarX, mbxOffsetY + mbxMarginY + (double) (prevRMax[h]    ));

			CGContextStrokePath(mboxctx);
		}
		else
			prevRMax[h] = 0;

		prevRVol[h] = vr;

		// Active

		CGContextSetRGBStrokeColor(mboxctx, (22.0 / 256.0), (22.0 / 256.0), (20.0 / 256.0), 1.0);

		CGContextMoveToPoint   (mboxctx, x,                mbxOffsetY + mbxMarginY);
		CGContextAddLineToPoint(mboxctx, x,                mbxOffsetY + mbxMarginY + (double) vl);
		CGContextStrokePath(mboxctx);
		CGContextMoveToPoint   (mboxctx, x + mbxRightBarX, mbxOffsetY + mbxMarginY);
		CGContextAddLineToPoint(mboxctx, x + mbxRightBarX, mbxOffsetY + mbxMarginY + (double) vr);
		CGContextStrokePath(mboxctx);

		x += (mbxBarWidth + mbxBarSpace);
	}
}
Exemplo n.º 30
0
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);
}