Beispiel #1
0
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;
}
Beispiel #2
0
static void copyClosingSubpathsApplierFunction(void* info, const CGPathElement* element)
{
    CGMutablePathRef path = static_cast<CGMutablePathRef>(info);
    CGPoint* points = element->points;
    
    switch (element->type) {
    case kCGPathElementMoveToPoint:
        if (!CGPathIsEmpty(path)) // to silence a warning when trying to close an empty path
            CGPathCloseSubpath(path); // This is the only change from CGPathCreateMutableCopy
        CGPathMoveToPoint(path, 0, points[0].x, points[0].y);
        break;
    case kCGPathElementAddLineToPoint:
        CGPathAddLineToPoint(path, 0, points[0].x, points[0].y);
        break;
    case kCGPathElementAddQuadCurveToPoint:
        CGPathAddQuadCurveToPoint(path, 0, points[0].x, points[0].y, points[1].x, points[1].y);
        break;
    case kCGPathElementAddCurveToPoint:
        CGPathAddCurveToPoint(path, 0, points[0].x, points[0].y, points[1].x, points[1].y, points[2].x, points[2].y);
        break;
    case kCGPathElementCloseSubpath:
        CGPathCloseSubpath(path);
        break;
    }
}
Beispiel #3
0
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;
}
//-----------------------------------------------------------------------------------
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); 
}
Beispiel #5
0
void
PathBuilderCG::LineTo(const Point &aPoint)
{
  if (!aPoint.IsFinite()) {
    return;
  }

  if (CGPathIsEmpty(mCGPath))
    MoveTo(aPoint);
  else
    CGPathAddLineToPoint(mCGPath, nullptr, aPoint.x, aPoint.y);
}
Beispiel #6
0
 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;
       }
   }
 }
Beispiel #7
0
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;
}
Beispiel #8
0
void Path::addLineTo(const FloatPoint& p)
{
    CGPathAddLineToPoint(m_path, 0, p.x(), p.y());
}
/*
	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;
}
Beispiel #10
0
void Path::addLineTo(const FloatPoint& p)
{
    CGPathAddLineToPoint(ensurePlatformPath(), 0, p.x(), p.y());
}