コード例 #1
0
DRAW_TEST_P(CGContextFillMode, OverlappedEllipses) {
    CGContextRef context = GetDrawingContext();
    CGRect bounds = GetDrawingBounds();
    bounds = CGRectInset(bounds, 16.f, 16.f);
    CGFloat width = bounds.size.width;
    CGFloat height = bounds.size.height;
    CGFloat xstart = bounds.origin.x;
    CGFloat ystart = bounds.origin.y;

    CGPathDrawingMode fillMode = GetParam();

    CGMutablePathRef leftCircles = CGPathCreateMutable();

    CGPathMoveToPoint(leftCircles, NULL, xstart + .25 * width + .4 * height, ystart + .5 * height);
    CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .4 * height, 0, M_PI, true);
    CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .4 * height, M_PI, 0, true);

    CGPathMoveToPoint(leftCircles, NULL, xstart + .25 * width + .3 * height, ystart + .5 * height);
    CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .3 * height, 0, M_PI, true);
    CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .3 * height, M_PI, 0, true);

    CGPathMoveToPoint(leftCircles, NULL, xstart + .25 * width + .2 * height, ystart + .5 * height);
    CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .2 * height, 0, M_PI, true);
    CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .2 * height, M_PI, 0, true);

    CGPathMoveToPoint(leftCircles, NULL, xstart + .25 * width + .1 * height, ystart + .5 * height);
    CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .1 * height, 0, M_PI, true);
    CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .1 * height, M_PI, 0, true);

    CGPathCloseSubpath(leftCircles);

    CGMutablePathRef rightCircles = CGPathCreateMutable();

    CGPathMoveToPoint(rightCircles, NULL, xstart + .75 * width + .4 * height, ystart + .5 * height);
    CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .4 * height, 0, M_PI, false);
    CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .4 * height, M_PI, 0, false);

    CGPathMoveToPoint(rightCircles, NULL, xstart + .75 * width + .3 * height, ystart + .5 * height);
    CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .3 * height, 0, M_PI, true);
    CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .3 * height, M_PI, 0, true);

    CGPathMoveToPoint(rightCircles, NULL, xstart + .75 * width + .2 * height, ystart + .5 * height);
    CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .2 * height, 0, M_PI, false);
    CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .2 * height, M_PI, 0, false);

    CGPathMoveToPoint(rightCircles, NULL, xstart + .75 * width + .1 * height, ystart + .5 * height);
    CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .1 * height, 0, M_PI, true);
    CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .1 * height, M_PI, 0, true);

    CGPathCloseSubpath(rightCircles);

    CGContextAddPath(context, leftCircles);
    CGContextAddPath(context, rightCircles);
    CGContextSetRGBFillColor(context, 0, 0, 1, 1);
    CGContextSetRGBStrokeColor(context, 1, 0, 0, 1);
    CGContextDrawPath(context, fillMode);

    CGPathRelease(leftCircles);
    CGPathRelease(rightCircles);
}
コード例 #2
0
void GraphicsContext::drawFocusRing(const Color& color)
{
    if (paintingDisabled())
        return;

    float radius = (focusRingWidth() - 1) / 2.0f;
    int offset = radius + focusRingOffset();
    CGColorRef colorRef = color.isValid() ? cgColor(color) : 0;

    CGMutablePathRef focusRingPath = CGPathCreateMutable();
    const Vector<IntRect>& rects = focusRingRects();
    unsigned rectCount = rects.size();
    for (unsigned i = 0; i < rectCount; i++)
        CGPathAddRect(focusRingPath, 0, CGRectInset(rects[i], -offset, -offset));

    CGContextRef context = platformContext();
    CGContextSaveGState(context);

    CGContextBeginPath(context);
    CGContextAddPath(context, focusRingPath);

    wkDrawFocusRing(context, colorRef, radius);

    CGColorRelease(colorRef);

    CGPathRelease(focusRingPath);

    CGContextRestoreGState(context);
}
コード例 #3
0
ファイル: PathCG.cpp プロジェクト: 13W/phantomjs
static CGMutablePathRef copyCGPathClosingSubpaths(CGPathRef originalPath)
{
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathApply(originalPath, path, copyClosingSubpathsApplierFunction);
    CGPathCloseSubpath(path);
    return path;
}
コード例 #4
0
ファイル: TIPCGUtils.c プロジェクト: samiamwork/Questionable
CGMutablePathRef TIPCGUtilsRoundedBoxCreate( CGRect inRect, float margin, float radius, float lineWidth )
{	
	float halfLineWidth = lineWidth/2.0f;
	
	inRect.origin.x += margin;
	inRect.origin.y += margin;
	inRect.size.width -= 2.0f*margin;
	inRect.size.height -= 2.0f*margin;
	
	CGMutablePathRef roundedBoxRef = CGPathCreateMutable();
	
	CGPathMoveToPoint(roundedBoxRef, NULL,
					  inRect.origin.x + halfLineWidth, inRect.origin.y + halfLineWidth + radius);
	CGPathAddLineToPoint(roundedBoxRef, NULL,
						 inRect.origin.x + halfLineWidth, inRect.origin.y + inRect.size.height - radius - halfLineWidth);
	CGPathAddArcToPoint(roundedBoxRef, NULL,
						inRect.origin.x + halfLineWidth, inRect.origin.y + inRect.size.height - halfLineWidth,
						inRect.origin.x + halfLineWidth + radius, inRect.origin.y + inRect.size.height - halfLineWidth,
						radius);
	CGPathAddArcToPoint(roundedBoxRef, NULL,
						inRect.origin.x + inRect.size.width - halfLineWidth, inRect.origin.y + inRect.size.height - halfLineWidth,
						inRect.origin.x + inRect.size.width - halfLineWidth, inRect.origin.y + inRect.size.height - radius - halfLineWidth,
						radius);
	CGPathAddArcToPoint(roundedBoxRef, NULL,
						inRect.origin.x + inRect.size.width - halfLineWidth, inRect.origin.y + halfLineWidth,
						inRect.origin.x + inRect.size.width - radius - halfLineWidth, inRect.origin.y + halfLineWidth,
						radius);
	CGPathAddArcToPoint(roundedBoxRef, NULL,
						inRect.origin.x + halfLineWidth, inRect.origin.y + halfLineWidth,
						inRect.origin.x + halfLineWidth, inRect.origin.y + halfLineWidth + radius,
						radius);
	
	return roundedBoxRef;
}
コード例 #5
0
ファイル: PathCG.cpp プロジェクト: acss/owb-mirror
void Path::transform(const AffineTransform& transform)
{
    CGMutablePathRef path = CGPathCreateMutable();
    CGAffineTransform transformCG = transform;
    CGPathAddPath(path, &transformCG, m_path);
    CGPathRelease(m_path);
    m_path = path;
}
コード例 #6
0
ファイル: PathCG.cpp プロジェクト: 13W/phantomjs
void Path::translate(const FloatSize& size)
{
    CGAffineTransform translation = CGAffineTransformMake(1, 0, 0, 1, size.width(), size.height());
    CGMutablePathRef newPath = CGPathCreateMutable();
    CGPathAddPath(newPath, &translation, m_path);
    CGPathRelease(m_path);
    m_path = newPath;
}
コード例 #7
0
void Path::clear()
{
    if (isNull())
        return;

    CGPathRelease(m_path);
    m_path = CGPathCreateMutable();
}
コード例 #8
0
ファイル: PathCG.cpp プロジェクト: 70599/Waterfox
already_AddRefed<PathBuilder>
PathCG::TransformedCopyToBuilder(const Matrix &aTransform, FillRule aFillRule) const
{
  // 10.7 adds CGPathCreateMutableCopyByTransformingPath it might be faster than doing
  // this by hand

  struct TransformApplier {
    CGMutablePathRef path;
    CGAffineTransform transform;
    static void
    TranformCGPathApplierFunc(void *vinfo, const CGPathElement *element)
    {
      TransformApplier *info = reinterpret_cast<TransformApplier*>(vinfo);
      switch (element->type) {
        case kCGPathElementMoveToPoint:
          {
            CGPoint pt = element->points[0];
            CGPathMoveToPoint(info->path, &info->transform, pt.x, pt.y);
            break;
          }
        case kCGPathElementAddLineToPoint:
          {
            CGPoint pt = element->points[0];
            CGPathAddLineToPoint(info->path, &info->transform, pt.x, pt.y);
            break;
          }
        case kCGPathElementAddQuadCurveToPoint:
          {
            CGPoint cpt = element->points[0];
            CGPoint pt  = element->points[1];
            CGPathAddQuadCurveToPoint(info->path, &info->transform, cpt.x, cpt.y, pt.x, pt.y);
            break;
          }
        case kCGPathElementAddCurveToPoint:
          {
            CGPoint cpt1 = element->points[0];
            CGPoint cpt2 = element->points[1];
            CGPoint pt   = element->points[2];
            CGPathAddCurveToPoint(info->path, &info->transform, cpt1.x, cpt1.y, cpt2.x, cpt2.y, pt.x, pt.y);
            break;
          }
        case kCGPathElementCloseSubpath:
          {
            CGPathCloseSubpath(info->path);
            break;
          }
      }
    }
  };

  TransformApplier ta;
  ta.path = CGPathCreateMutable();
  ta.transform = GfxMatrixToCGAffineTransform(aTransform);

  CGPathApply(mPath, &ta, TransformApplier::TranformCGPathApplierFunc);
  return MakeAndAddRef<PathBuilderCG>(ta.path, aFillRule);
}
コード例 #9
0
void Path::translate(const FloatSize& size)
{
    CGAffineTransform translation = CGAffineTransformMake(1, 0, 0, 1, size.width(), size.height());
    CGMutablePathRef newPath = CGPathCreateMutable();
    // FIXME: This is potentially wasteful to allocate an empty path only to create a transformed copy.
    CGPathAddPath(newPath, &translation, ensurePlatformPath());
    CGPathRelease(m_path);
    m_path = newPath;
}
コード例 #10
0
//-----------------------------------------------------------------------------------
static void DoTheTracking(EventRef inEvent, MTViewData* data)
{
    MouseTrackingResult	mouseResult;
    ControlPartCode	part;
    Point		qdPt;
    HIPoint		where;
    
    // Extract the mouse location (local coordinates!)
    GetEventParameter(inEvent, kEventParamMouseLocation, typeHIPoint, NULL, sizeof(HIPoint), NULL, &where);

    CGAffineTransform m = CGAffineTransformIdentity;
    // Reset the path
    if (data->thePath != NULL)
	CGPathRelease(data->thePath);
    
    data->thePath = CGPathCreateMutable();
    
#if CG_COORDINATES
    where.y = FlipHIViewYCoordinate(data->theView, where.y);
#endif

    CGPathMoveToPoint(data->thePath, &m, where.x, where.y);
//  fprintf(stderr, "StartPt:  (%g, %g\n", where.x, where.y);
    
    while (true)
    {
	// Watch the mouse for change: qdPt comes back in global coordinates!
	TrackMouseLocation((GrafPtr)(-1), &qdPt, &mouseResult);

	// Bail out when the mouse is released
	if ( mouseResult == kMouseTrackingMouseReleased )
	{
	    HIViewSetNeedsDisplay(data->theView, true);
	    break;
	}
	
	// Need to convert from global
	where = QDGlobalToHIViewLocal(qdPt, data->theView);
#if CG_COORDINATES
	where.y = FlipHIViewYCoordinate(data->theView, where.y);
#endif
	
	CGPathAddLineToPoint(data->thePath, &m, where.x, where.y);
//	fprintf(stderr, "TrackPt:  (%g, %g\n", where.x, where.y);

	part = 0;
	SetEventParameter(inEvent, kEventParamControlPart, typeControlPartCode, sizeof(ControlPartCode), &part); 

	HIViewSetNeedsDisplay(data->theView, true);
    }
    
    // Send back the part upon which the mouse was released
    part = kControlEntireControl;
    SetEventParameter(inEvent, kEventParamControlPart, typeControlPartCode, sizeof(ControlPartCode), &part); 
}
コード例 #11
0
ファイル: PathCG.cpp プロジェクト: 13W/phantomjs
void Path::transform(const AffineTransform& transform)
{
    if (transform.isIdentity() || isEmpty())
        return;

    CGMutablePathRef path = CGPathCreateMutable();
    CGAffineTransform transformCG = transform;
    CGPathAddPath(path, &transformCG, m_path);
    CGPathRelease(m_path);
    m_path = path;
}
コード例 #12
0
DRAW_TEST_F(CGContextFlush, FillFlush, WhiteBackgroundTest<>) {
    CGContextRef context = GetDrawingContext();
    CGRect bounds = GetDrawingBounds();
    _CGContextPushBeginDraw(context);

    CGContextSetRGBFillColor(context, 1, 0, 0, 1);
    CGContextFillRect(context, bounds);

    // Flush the red fill rect
    CGContextFlush(context);

    CGContextSetRGBFillColor(context, 0, 0, 1, 1);
    CGContextFillRect(context, CGRectMake(0, 0, 300, 300));

    // We should still have red & blue rectangle should not show up.
    unsigned char* dataPtr = static_cast<unsigned char*>(CGBitmapContextGetData(context));
    ASSERT_NE(dataPtr, nullptr);

    // Validate only the red fill rect is executed.
    EXPECT_EQ(dataPtr[0], 0x00);
    EXPECT_EQ(dataPtr[1], 0x00);
    EXPECT_EQ(dataPtr[2], 0xff);
    EXPECT_EQ(dataPtr[3], 0xff);

    CGContextFlush(context);

    // We should now see the blue fill rect
    EXPECT_EQ(dataPtr[0], 0xff);
    EXPECT_EQ(dataPtr[1], 0x00);
    EXPECT_EQ(dataPtr[2], 0x00);
    EXPECT_EQ(dataPtr[3], 0xff);

    // Add some extra drawings
    CGContextClearRect(context, CGRectMake(100, 100, 200, 300));

    CGPoint center = _CGRectGetCenter(bounds);

    CGMutablePathRef concentricCirclesPath = CGPathCreateMutable();

    CGPathAddEllipseInRect(concentricCirclesPath, nullptr, _CGRectCenteredOnPoint({ 50, 50 }, center));
    CGPathAddEllipseInRect(concentricCirclesPath, nullptr, _CGRectCenteredOnPoint({ 100, 100 }, center));
    CGPathAddEllipseInRect(concentricCirclesPath, nullptr, _CGRectCenteredOnPoint({ 150, 150 }, center));
    CGPathAddEllipseInRect(concentricCirclesPath, nullptr, _CGRectCenteredOnPoint({ 200, 200 }, center));

    CGContextSetRGBFillColor(context, 1.0, 0.0, 0.0, 0.5);
    CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0);

    CGContextAddPath(context, concentricCirclesPath);
    CGContextDrawPath(context, kCGPathFillStroke);

    CGPathRelease(concentricCirclesPath);

    _CGContextPopEndDraw(context);
}
コード例 #13
0
ファイル: TIPCGUtils.c プロジェクト: samiamwork/Questionable
CGMutablePathRef TIPCGUtilsPartialRoundedBoxCreate( CGRect inRect, float radius, bool lowerRight, bool upperRight, bool upperLeft, bool lowerLeft )
{
	CGMutablePathRef roundedBoxRef = CGPathCreateMutable();
	
	if( lowerRight ) {
		CGPathMoveToPoint(roundedBoxRef, NULL,
						  inRect.origin.x, inRect.origin.y + radius);
	} else {
		CGPathMoveToPoint(roundedBoxRef, NULL,
						  inRect.origin.x, inRect.origin.y);
	}
	
	if( upperRight ) {
		CGPathAddLineToPoint(roundedBoxRef, NULL,
							 inRect.origin.x, inRect.origin.y + inRect.size.height - radius);
		CGPathAddArcToPoint(roundedBoxRef, NULL,
							inRect.origin.x, inRect.origin.y + inRect.size.height,
							inRect.origin.x + radius, inRect.origin.y + inRect.size.height,
							radius);
	} else {
		CGPathAddLineToPoint(roundedBoxRef, NULL,
							 inRect.origin.x, inRect.origin.y + inRect.size.height);
	}
	
	if( upperLeft ) {
		CGPathAddArcToPoint(roundedBoxRef, NULL,
							inRect.origin.x + inRect.size.width, inRect.origin.y + inRect.size.height,
							inRect.origin.x + inRect.size.width, inRect.origin.y + inRect.size.height - radius,
							radius);
	} else {
		CGPathAddLineToPoint(roundedBoxRef, NULL,
							 inRect.origin.x + inRect.size.width, inRect.origin.y + inRect.size.height);
	}
	
	if( lowerLeft ) {
		CGPathAddArcToPoint(roundedBoxRef, NULL,
							inRect.origin.x + inRect.size.width, inRect.origin.y,
							inRect.origin.x + inRect.size.width - radius, inRect.origin.y,
							radius);
	} else {
		CGPathAddLineToPoint(roundedBoxRef, NULL,
							 inRect.origin.x + inRect.size.width, inRect.origin.y);
	}
	
	if( lowerRight ) {
		CGPathAddArcToPoint(roundedBoxRef, NULL,
							inRect.origin.x, inRect.origin.y,
							inRect.origin.x, inRect.origin.y + radius,
							radius);
	}
	
	return roundedBoxRef;
}
コード例 #14
0
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);
}
コード例 #15
0
ファイル: ScaledFontMac.cpp プロジェクト: abotalov/gecko-dev
TemporaryRef<Path>
ScaledFontMac::GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget)
{
  if (aTarget->GetType() == BackendType::COREGRAPHICS || aTarget->GetType() == BackendType::COREGRAPHICS_ACCELERATED) {
      CGMutablePathRef path = CGPathCreateMutable();

      for (unsigned int i = 0; i < aBuffer.mNumGlyphs; i++) {
          // XXX: we could probably fold both of these transforms together to avoid extra work
          CGAffineTransform flip = CGAffineTransformMakeScale(1, -1);
          CGPathRef glyphPath = ::CGFontGetGlyphPath(mFont, &flip, 0, aBuffer.mGlyphs[i].mIndex);

          CGAffineTransform matrix = CGAffineTransformMake(mSize, 0, 0, mSize,
                                                           aBuffer.mGlyphs[i].mPosition.x,
                                                           aBuffer.mGlyphs[i].mPosition.y);
          CGPathAddPath(path, &matrix, glyphPath);
          CGPathRelease(glyphPath);
      }
      TemporaryRef<Path> ret = new PathCG(path, FillRule::FILL_WINDING);
      CGPathRelease(path);
      return ret;
  }
  return ScaledFontBase::GetPathForGlyphs(aBuffer, aTarget);
}
コード例 #16
0
ファイル: BitLockerSkia.cpp プロジェクト: 1833183060/wke
CGContextRef BitLockerSkia::cgContext()
{
    SkDevice* device = m_canvas->getDevice();
    ASSERT(device);
    if (!device)
        return 0;
    releaseIfNeeded();
    const SkBitmap& bitmap = device->accessBitmap(true);
    bitmap.lockPixels();
    void* pixels = bitmap.getPixels();
    m_cgContext = CGBitmapContextCreate(pixels, device->width(),
        device->height(), 8, bitmap.rowBytes(), CGColorSpaceCreateDeviceRGB(), 
        kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst);

    // Apply device matrix.
    CGAffineTransform contentsTransform = CGAffineTransformMakeScale(1, -1);
    contentsTransform = CGAffineTransformTranslate(contentsTransform, 0, -device->height());
    CGContextConcatCTM(m_cgContext, contentsTransform);

    // Apply clip in device coordinates.
    CGMutablePathRef clipPath = CGPathCreateMutable();
    SkRegion::Iterator iter(m_canvas->getTotalClip());
    for (; !iter.done(); iter.next()) {
        IntRect rect = iter.rect();
        CGPathAddRect(clipPath, 0, rect);
    }
    CGContextAddPath(m_cgContext, clipPath);
    CGContextClip(m_cgContext);
    CGPathRelease(clipPath);

    // Apply content matrix.
    const SkMatrix& skMatrix = m_canvas->getTotalMatrix();
    CGAffineTransform affine = SkMatrixToCGAffineTransform(skMatrix);
    CGContextConcatCTM(m_cgContext, affine);

    return m_cgContext;
}
コード例 #17
0
ファイル: FontCGWin.cpp プロジェクト: Kaless1n/phantomjs
static CGPathRef createPathForGlyph(HDC hdc, Glyph glyph)
{
    CGMutablePathRef path = CGPathCreateMutable();

    static const MAT2 identity = { 0, 1,  0, 0,  0, 0,  0, 1 };
    GLYPHMETRICS glyphMetrics;
    // GGO_NATIVE matches the outline perfectly when Windows font smoothing is off.
    // GGO_NATIVE | GGO_UNHINTED does not match perfectly either when Windows font smoothing is on or off.
    DWORD outlineLength = GetGlyphOutline(hdc, glyph, GGO_GLYPH_INDEX | GGO_NATIVE, &glyphMetrics, 0, 0, &identity);
    ASSERT(outlineLength >= 0);
    if (outlineLength < 0)
        return path;

    Vector<UInt8> outline(outlineLength);
    GetGlyphOutline(hdc, glyph, GGO_GLYPH_INDEX | GGO_NATIVE, &glyphMetrics, outlineLength, outline.data(), &identity);

    unsigned offset = 0;
    while (offset < outlineLength) {
        LPTTPOLYGONHEADER subpath = reinterpret_cast<LPTTPOLYGONHEADER>(outline.data() + offset);
        ASSERT(subpath->dwType == TT_POLYGON_TYPE);
        if (subpath->dwType != TT_POLYGON_TYPE)
            return path;

        CGPathMoveToPoint(path, 0, toCGFloat(subpath->pfxStart.x), toCGFloat(subpath->pfxStart.y));

        unsigned subpathOffset = sizeof(*subpath);
        while (subpathOffset < subpath->cb) {
            LPTTPOLYCURVE segment = reinterpret_cast<LPTTPOLYCURVE>(reinterpret_cast<UInt8*>(subpath) + subpathOffset);
            switch (segment->wType) {
            case TT_PRIM_LINE:
                for (unsigned i = 0; i < segment->cpfx; i++)
                    CGPathAddLineToPoint(path, 0, toCGFloat(segment->apfx[i].x), toCGFloat(segment->apfx[i].y));
                break;

            case TT_PRIM_QSPLINE:
                for (unsigned i = 0; i < segment->cpfx; i++) {
                    CGFloat x = toCGFloat(segment->apfx[i].x);
                    CGFloat y = toCGFloat(segment->apfx[i].y);
                    CGFloat cpx;
                    CGFloat cpy;

                    if (i == segment->cpfx - 2) {
                        cpx = toCGFloat(segment->apfx[i + 1].x);
                        cpy = toCGFloat(segment->apfx[i + 1].y);
                        i++;
                    } else {
                        cpx = (toCGFloat(segment->apfx[i].x) + toCGFloat(segment->apfx[i + 1].x)) / 2;
                        cpy = (toCGFloat(segment->apfx[i].y) + toCGFloat(segment->apfx[i + 1].y)) / 2;
                    }

                    CGPathAddQuadCurveToPoint(path, 0, x, y, cpx, cpy);
                }
                break;

            case TT_PRIM_CSPLINE:
                for (unsigned i = 0; i < segment->cpfx; i += 3) {
                    CGFloat cp1x = toCGFloat(segment->apfx[i].x);
                    CGFloat cp1y = toCGFloat(segment->apfx[i].y);
                    CGFloat cp2x = toCGFloat(segment->apfx[i + 1].x);
                    CGFloat cp2y = toCGFloat(segment->apfx[i + 1].y);
                    CGFloat x = toCGFloat(segment->apfx[i + 2].x);
                    CGFloat y = toCGFloat(segment->apfx[i + 2].y);

                    CGPathAddCurveToPoint(path, 0, cp1x, cp1y, cp2x, cp2y, x, y);
                }
                break;

            default:
                ASSERT_NOT_REACHED();
                return path;
            }

            subpathOffset += sizeof(*segment) + (segment->cpfx - 1) * sizeof(segment->apfx[0]);
        }
        CGPathCloseSubpath(path);
        offset += subpath->cb;
    }
    return path;
}
コード例 #18
0
ファイル: FontCGWin.cpp プロジェクト: arjunroy/cinder_webkit
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;
    int drawingMode = graphicsContext->textDrawingMode();
    if (drawingMode == cTextFill) {
        if (!fillColor.alpha())
            return;

        drawIntoBitmap = fillColor.alpha() != 255 || graphicsContext->inTransparencyLayer();
        if (!drawIntoBitmap) {
            IntSize size;
            int blur;
            Color color;
            graphicsContext->getShadow(size, blur, color);
            drawIntoBitmap = !size.isEmpty() || 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.
        int lineGap = font->lineGap();
        textRect = IntRect(point.x() - (font->ascent() + font->descent()) / 2, point.y() - font->ascent() - lineGap, totalWidth + font->ascent() + font->descent(), font->lineSpacing());
        bitmap.set(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->m_font.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 == cTextFill) {
        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->m_syntheticBoldOffset) {
            xform.eM21 = 0;
            xform.eDx = font->m_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 {
        RetainPtr<CGMutablePathRef> path(AdoptCF, CGPathCreateMutable());

        XFORM xform;
        GetWorldTransform(hdc, &xform);
        TransformationMatrix 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;
        CGAffineTransform glyphTranslation = CGAffineTransformIdentity;

        for (unsigned i = 0; i < numGlyphs; ++i) {
            RetainPtr<CGPathRef> glyphPath(AdoptCF, createPathForGlyph(hdc, glyphBuffer.glyphAt(from + i)));
            CGAffineTransform glyphTransform = CGAffineTransformConcat(initialGlyphTransform, glyphTranslation);
            CGPathAddPath(path.get(), &glyphTransform, glyphPath.get());
            glyphTranslation = CGAffineTransformTranslate(glyphTranslation, gdiAdvances[i], 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()));

        if (drawingMode & cTextFill) {
            CGContextAddPath(cgContext, path.get());
            CGContextFillPath(cgContext);
            if (font->m_syntheticBoldOffset) {
                CGContextTranslateCTM(cgContext, font->m_syntheticBoldOffset, 0);
                CGContextAddPath(cgContext, path.get());
                CGContextFillPath(cgContext);
                CGContextTranslateCTM(cgContext, -font->m_syntheticBoldOffset, 0);
            }
        }
        if (drawingMode & cTextStroke) {
            CGContextAddPath(cgContext, path.get());
            CGContextStrokePath(cgContext);
            if (font->m_syntheticBoldOffset) {
                CGContextTranslateCTM(cgContext, font->m_syntheticBoldOffset, 0);
                CGContextAddPath(cgContext, path.get());
                CGContextStrokePath(cgContext);
                CGContextTranslateCTM(cgContext, -font->m_syntheticBoldOffset, 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.topLeft());
    } else
        graphicsContext->releaseWindowsContext(hdc, textRect, true, false);
}
コード例 #19
0
OSStatus GenerateThumbnailForURL(void *thisInterface, 
								 QLThumbnailRequestRef thumbnail,
								 CFURLRef url, CFStringRef contentTypeUTI, 
								 CFDictionaryRef options, CGSize maxSize)
{
	CGFloat minCartDrawSize = 64;
	CGFloat size = fmin(maxSize.width, maxSize.height);
	CGContextRef qlContext = NULL;
	if (size < minCartDrawSize) { 
		size = 32;
		qlContext = QLThumbnailRequestCreateContext(thumbnail, CGSizeMake(size,size), true, NULL);
	}
	else 
	{
		qlContext = QLThumbnailRequestCreateContext(thumbnail, CGSizeMake(size,size), false, NULL);
	}
	
	if (qlContext) {
		NDSHeader header;	
		NDSIcon icon;
		int pathlen = 2047;
		UInt8 path[pathlen+1];
		if (CFURLGetFileSystemRepresentation(url, true, path, pathlen)) { 
			
			if (size < minCartDrawSize) { // at smaller sizes we only draw the game icon at native size and let QL do the scaling
				parseNDSInfo(path, &header, &icon);
				CGImageRef image = CGImageCreateWithNDSIcon(&icon);
				if (image) {
					CGContextDrawImage(qlContext, CGRectMake(0, 0, size, size), image);
					CGImageRelease(image);
				}
			}
			else 
			{
				CGContextClearRect(qlContext, CGRectMake(0,0,size,size));
				
				// draw cartridge background
				CFURLRef bgURL = CFBundleCopyResourceURL(CFBundleGetBundleWithIdentifier(
																						 CFSTR("net.mironer.nds.quicklookgenerator")), CFSTR("background"), CFSTR("png"), NULL);
				if (bgURL) {
					CGDataProviderRef bgPNG = CGDataProviderCreateWithURL(bgURL);
					if (bgPNG) {
						CGImageRef bg = CGImageCreateWithPNGDataProvider(bgPNG, NULL, true, kCGRenderingIntentDefault);
						if (bg) {
							CGContextDrawImage(qlContext, CGRectMake(0, 0, size, size), bg);				
							CGImageRelease(bg);
						}
						CGDataProviderRelease(bgPNG);
					}
					CFRelease(bgURL);
				}			
				
				// draw game icon
				parseNDSInfo(path, &header, &icon);
				CGImageRef image = CGImageCreateWithNDSIcon(&icon);
				if (image) {
					CGContextDrawImage(qlContext, CGRectMake(size / 5, size / 5, size * 3 / 5, size * 3 / 5), image);
					CGImageRelease(image);
				}
				
				// draw cartridge overlay
				CFURLRef ovrURL = CFBundleCopyResourceURL( 
														  CFBundleGetBundleWithIdentifier(
																						  CFSTR("net.mironer.nds.quicklookgenerator")), CFSTR("overlay"), CFSTR("png"), NULL);
				if (ovrURL) {
					CGDataProviderRef ovrPNG = CGDataProviderCreateWithURL(ovrURL);
					if (ovrPNG) {
						CGImageRef ovr = CGImageCreateWithPNGDataProvider(ovrPNG, NULL, true, kCGRenderingIntentDefault);
						if (ovr) {
							CGContextDrawImage(qlContext, CGRectMake(0, 0, size, size), ovr);				
							CGImageRelease(ovr);
						}
						CGDataProviderRelease(ovrPNG);
					}
					CFRelease(ovrURL);
				}			
				
				// draw serial number
				CFStringRef serial = CFStringCreateWithSerialNumber(&header);
				CFAttributedStringRef aString = CFAttributedStringCreate(kCFAllocatorDefault, serial, NULL);
				CFMutableAttributedStringRef attrStr = CFAttributedStringCreateMutableCopy(kCFAllocatorDefault, 128, aString);
				CFIndex len =  CFAttributedStringGetLength(attrStr);
				CTFontRef font = CTFontCreateWithName(CFSTR("Lucida Sans"), size / 16, NULL);
				CFAttributedStringSetAttribute(attrStr, CFRangeMake(0, len), kCTFontAttributeName, font);		
				
				CTTextAlignment rightAlign = kCTRightTextAlignment;
				CTParagraphStyleSetting styleSettings[] = { {kCTParagraphStyleSpecifierAlignment, sizeof(rightAlign), &rightAlign} };
				CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(styleSettings, 1);
				CFAttributedStringSetAttribute(attrStr, CFRangeMake(0, len), kCTParagraphStyleAttributeName, paragraphStyle);
				
				CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attrStr);
				CFRelease(attrStr);
				CFRelease(aString);
				CFRelease(serial);
				CFRelease(font);
				
				CGMutablePathRef path = CGPathCreateMutable();
				CGPathAddRect(path, NULL, CGRectMake(-size * 1.55 / 8, -size * 6.1 / 8, size, size));			
				CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
				CTFrameDraw(frame, qlContext);
				CFRelease(frame);
				CFRelease(framesetter); 
				CFRelease(paragraphStyle);
				CFRelease(path);
			}
		}
		QLThumbnailRequestFlushContext(thumbnail, qlContext);
        CFRelease(qlContext);
    }
    return noErr;
}
コード例 #20
0
ファイル: PathCG.cpp プロジェクト: 13W/phantomjs
Path::Path()
    : m_path(CGPathCreateMutable())
{
}
コード例 #21
0
PlatformPathPtr Path::ensurePlatformPath()
{
    if (!m_path)
        m_path = CGPathCreateMutable();
    return m_path;
}
コード例 #22
0
ファイル: PathCG.cpp プロジェクト: 13W/phantomjs
void Path::clear()
{
    CGPathRelease(m_path);
    m_path = CGPathCreateMutable();
}
コード例 #23
0
/*
	Event handler for the content view that gets attached to the menu frame.

	The content view will (eventually) contain the menu view.
*/
OSStatus ContentViewEventHandler(
	EventHandlerCallRef inCallRef,
	EventRef inEvent,
	void *refcon)
{
	OSStatus retVal = eventNotHandledErr;
	if(GetEventClass(inEvent) == kEventClassMenu) {
		return noErr;
	} else
	if(GetEventClass(inEvent) == kEventClassControl) {
		HIViewRef hiSelf = NULL;
		verify_noerr(GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(hiSelf), NULL, &hiSelf));

		if(hiSelf) {
			HIRect frame;
			HIViewGetFrame(hiSelf, &frame);

			switch(GetEventKind(inEvent)) {
				case kEventControlAddedSubControl : {
					HIViewRef subControl;
					ControlID subControlID;

					GetEventParameter(inEvent, kEventParamControlSubControl, typeControlRef, NULL, sizeof(subControl), NULL, &subControl );
					GetControlID(subControl, &subControlID);

					// This should be comparing against kHIViewMenuContentID as shown inside the
					// #if 0. At the time of this writing, however, using that constant causes a
					// linker error (and a crash if you use ZeroLink).  I extracted the signature
					// and id by determining the value at run-time the value I compare against.
#if 0
					if( kHIViewMenuContentID.signature == subControlID.signature && kHIViewMenuContentID.id == subControlID.id ) {
#else
					if( 'menu' == subControlID.signature && 0 == subControlID.id ) {
#endif
						// If we have the menu content view then set up some view bindings for it.
						HIRect bounds;
						HIViewGetBounds(hiSelf, &bounds);
						HIViewSetFrame(subControl, &bounds);

						HILayoutInfo contentLayout = {
							kHILayoutInfoVersionZero,
							{
								{ NULL, kHILayoutBindTop },
								{ NULL, kHILayoutBindLeft },
								{ NULL, kHILayoutBindBottom },
								{ NULL, kHILayoutBindRight }
							},
							{
								{ NULL, kHILayoutScaleAbsolute, 0 },
								{ NULL, kHILayoutScaleAbsolute, 0 }
							},
							{
								{ NULL, kHILayoutPositionTop, 0 },
								{ NULL, kHILayoutPositionLeft, 0 }
							}
						};

						verify_noerr(HIViewSetLayoutInfo(subControl, &contentLayout));
					}

					retVal = noErr;
				} break;

				case kEventControlGetFrameMetrics :
					HIViewFrameMetrics metrics;

					// The offset from the frame view to the content view is 
					// given by the kFrameOffset constant
					metrics.top = kFrameOffset;
					metrics.left = kFrameOffset;
					metrics.right = kFrameOffset;
					metrics.bottom = kFrameOffset;

					verify_noerr(SetEventParameter(inEvent, kEventParamControlFrameMetrics, typeControlFrameMetrics, sizeof(metrics), &metrics));

					retVal = noErr;
				break;

				case kEventControlBoundsChanged :
				case kEventControlOwningWindowChanged : {
					// Maintain the QuickDraw port by changing its position to
					// match that of the content view.
					CGrafPtr windowPort = NULL;
					WindowRef window = GetControlOwner(hiSelf);

					if(window && (windowPort = GetWindowPort(window))) {
						CGrafPtr savePort;
						bool swapped = QDSwapPort(windowPort, &savePort);

						MovePortTo((short) frame.origin.x, (short) frame.origin.y);
						PortSize((short) frame.size.width, (short) frame.size.height);

						if(swapped) {
							QDSwapPort(savePort, NULL);
						}
					}

					retVal = noErr;
				} break;
			} // switch
		} // if (hiSelf)
	}

	return retVal;
}


/* ------------------------------------------ CreatePathForEntireStarMenu */
/*
	Create a path shape for the star frame.
	
	This looks an awful lot like CreatePathForEntireStarMenu in
	StarMenu.cpp but takes the radius to use as a parameter and
	then takes into account the kFrameOffest when creating the path.

	In true Core Foundation style, this is a CreateXXX routine and the
	caller is responsible for freeing the path that is returned.
*/
CGPathRef CreatePathForStarFrame(StarFrameData *menuData, float radius)
{
   CGMutablePathRef retVal = CGPathCreateMutable();
   MenuItemIndex numItems = CountMenuItems(menuData->menu);

   if(numItems > 0) {
	  const CGPoint fullRadiusPoint = { radius, 0 };
	  const CGPoint halfRadiusPoint = { ((radius - kFrameOffset) / 2.0) + kFrameOffset , 0 };

	  float   anglePerItem = 2 * pi / (float)numItems;   // in radians naturally
	  float   halfAngle = anglePerItem / 2.0;

	  CGPoint startPoint = halfRadiusPoint;
	  CGAffineTransform midRotate = CGAffineTransformMakeRotation(halfAngle);
	  CGPoint midPoint = CGPointApplyAffineTransform(fullRadiusPoint, midRotate);

	  CGAffineTransform rotateToNext = CGAffineTransformMakeRotation(anglePerItem);

	  CGPathMoveToPoint(retVal, NULL, startPoint.x, startPoint.y);
	  CGPathAddLineToPoint(retVal, NULL, midPoint.x, midPoint.y);

	  for(short ctr = 0; ctr < numItems; ctr++) {
		 startPoint = CGPointApplyAffineTransform(startPoint, rotateToNext);
		 midPoint = CGPointApplyAffineTransform(midPoint, rotateToNext);

		 CGPathAddLineToPoint(retVal, NULL, startPoint.x, startPoint.y);
		 CGPathAddLineToPoint(retVal, NULL, midPoint.x, midPoint.y);
	  }

	  CGPathCloseSubpath(retVal);
   }

   return retVal;
}