Ejemplo n.º 1
0
bool CGRect::CGRectIntersectsRect(const CGRect& rectA, const CGRect& rectB)
{
	return !(CGRectGetMaxX(rectA) < CGRectGetMinX(rectB)||
			CGRectGetMaxX(rectB) < CGRectGetMinX(rectA)||
			CGRectGetMaxY(rectA) < CGRectGetMinY(rectB)||
			CGRectGetMaxY(rectB) < CGRectGetMinY(rectB));
}
Ejemplo n.º 2
0
static void ButtonElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    ThemeButtonParams *params = clientData;
    const HIThemeButtonDrawInfo info = computeButtonDrawInfo(params, 0);
    static const CGRect scratchBounds = {{0, 0}, {100, 100}};
    CGRect contentBounds;

    ButtonElementSizeNoPadding(
        clientData, elementRecord, tkwin,
        widthPtr, heightPtr, paddingPtr);

    /*
     * To compute internal padding, query the appearance manager
     * for the content bounds of a dummy rectangle, then use
     * the difference as the padding.
     */
    ChkErr(HIThemeGetButtonContentBounds,
           &scratchBounds, &info, &contentBounds);

    paddingPtr->left = CGRectGetMinX(contentBounds);
    paddingPtr->top = CGRectGetMinY(contentBounds);
    paddingPtr->right = CGRectGetMaxX(scratchBounds) - CGRectGetMaxX(contentBounds) + 1;
    paddingPtr->bottom = CGRectGetMaxY(scratchBounds) - CGRectGetMaxY(contentBounds);

    /*
     * Now add a little extra padding to account for drop shadows.
     * @@@ SHOULD: call GetThemeButtonBackgroundBounds() instead.
     */

    *paddingPtr = Ttk_AddPadding(*paddingPtr, ButtonMargins);
    *widthPtr += Ttk_PaddingWidth(ButtonMargins);
    *heightPtr += Ttk_PaddingHeight(ButtonMargins);
}
Ejemplo n.º 3
0
// -----------------------------------------------------------------------------
//	HITestViewGetRegion
// -----------------------------------------------------------------------------
//
OSStatus HITestViewGetRegion(
	EventRef				inEvent,
	HITestViewData*			inData )
{
	OSStatus				err;
	ControlPartCode			part;
	RgnHandle				outRegion;
	HIRect					bounds;
	Rect					qdBounds;
	
	err = GetEventParameter( inEvent, kEventParamControlPart, typeControlPartCode,
			NULL, sizeof( ControlPartCode ), NULL, &part );
	require_noerr( err, ParameterMissing );

	err = GetEventParameter( inEvent, kEventParamControlRegion, typeQDRgnHandle,
			NULL, sizeof( RgnHandle ), NULL, &outRegion );

	if ( part == kControlContentMetaPart
			|| part == kControlStructureMetaPart
			/* || part == kControlOpaqueRegionMetaPart */ )
	{
		HIViewGetBounds( inData->view, &bounds );
		qdBounds.top = (SInt16) CGRectGetMinY( bounds );
		qdBounds.left = (SInt16) CGRectGetMinX( bounds );
		qdBounds.bottom = (SInt16) CGRectGetMaxY( bounds );
		qdBounds.right = (SInt16) CGRectGetMaxX( bounds );
	
		RectRgn( outRegion, &qdBounds );
	}
	
ParameterMissing:
	return err;
}
Ejemplo n.º 4
0
CGFloat CBRectPointDistance(CGRect rect, CGPoint point)
{
	CGPoint p00 = CGPointMake(CGRectGetMinX(rect), CGRectGetMinY(rect));
	CGPoint p11 = CGPointMake(CGRectGetMaxX(rect), CGRectGetMaxY(rect));
	if (point.x < p00.x)
	{
		if (point.y < p00.y)
			return CBPointPointDistance(point, p00);
		else if (point.y > p11.y)
			return CBPointPointDistance(point, CGPointMake(p00.x, p11.y));
		else
			return p00.x - point.x;
	}
	if (point.x > p11.x)
	{
		if (point.y < p00.y)
			return CBPointPointDistance(point, CGPointMake(p11.x, p00.y));
		else if (point.y > p11.y)
			return CBPointPointDistance(point, p11);
		else
			return point.x - p11.x;
	}
	if (point.y < p00.y)
		return p00.y - point.y;
	else if (point.y > p11.y)
		return point.y - p11.y;
	return 0.0;
}
Ejemplo n.º 5
0
CGPoint CGLineIntersectsRectAtPoint(CGRect rect, CGLine line)
{
	CGLine top		= CGLineMake( CGPointMake( CGRectGetMinX(rect), CGRectGetMinY(rect) ), CGPointMake( CGRectGetMaxX(rect), CGRectGetMinY(rect) ) );
	CGLine right	= CGLineMake( CGPointMake( CGRectGetMaxX(rect), CGRectGetMinY(rect) ), CGPointMake( CGRectGetMaxX(rect), CGRectGetMaxY(rect) ) );
	CGLine bottom	= CGLineMake( CGPointMake( CGRectGetMinX(rect), CGRectGetMaxY(rect) ), CGPointMake( CGRectGetMaxX(rect), CGRectGetMaxY(rect) ) );
	CGLine left		= CGLineMake( CGPointMake( CGRectGetMinX(rect), CGRectGetMinY(rect) ), CGPointMake( CGRectGetMinX(rect), CGRectGetMaxY(rect) ) );

	// ensure the line extends beyond outside the rectangle
	CGFloat topLeftToBottomRight = CGPointDistance(CGRectTopLeftPoint(rect), CGRectBottomRightPoint(rect));
	CGFloat bottomLeftToTopRight = CGPointDistance(CGRectBottomLeftPoint(rect), CGRectTopRightPoint(rect));
	CGFloat maxDimension = MT_MAX(topLeftToBottomRight, bottomLeftToTopRight);
	CGFloat scaleFactor = maxDimension / MT_MIN(CGLineLength(line), maxDimension);
	CGLine extendedLine = CGLineScale(line, scaleFactor + 3);

	CGPoint points[4] = { CGLinesIntersectAtPoint(top, extendedLine), CGLinesIntersectAtPoint(right, extendedLine), CGLinesIntersectAtPoint(bottom, extendedLine), CGLinesIntersectAtPoint(left, extendedLine) };

	for (int i = 0; i < 4; i++) {
		CGPoint p = points[i];
		if (!CGPointEqualToPoint(p, NULL_POINT)) {
			return p;
		}
	}

	return NULL_POINT;
}
Ejemplo n.º 6
0
IntRect enclosingIntRect(const CGRect& rect)
{
    int l = static_cast<int>(floorf(rect.origin.x));
    int t = static_cast<int>(floorf(rect.origin.y));
    int r = static_cast<int>(ceilf(CGRectGetMaxX(rect)));
    int b = static_cast<int>(ceilf(CGRectGetMaxY(rect)));
    return IntRect(l, t, r - l, b - t);
}
Ejemplo n.º 7
0
void drawRoundedRect(CGContextRef context, CGRect rrect)
{
    // Drawing with a white stroke color
    CGContextSetRGBStrokeColor(context, 0.3, 0.3, 0.3, 1.0);
    CGContextSetRGBFillColor(context, 0.3, 0.3, 0.3, 1.0);
    
    // Add Rect to the current path, then stroke it
    //            CGContextAddRect(context, CGRectMake(10.0, 190.0, 290.0, 73.0));
    
    
    CGContextSetLineWidth(context, 1);
    CGFloat radius = 10.0;
    
    CGFloat minx = CGRectGetMinX(rrect), midx = CGRectGetMidX(rrect), maxx = CGRectGetMaxX(rrect);
    CGFloat miny = CGRectGetMinY(rrect), midy = CGRectGetMidY(rrect), maxy = CGRectGetMaxY(rrect);
    
    // Next, we will go around the rectangle in the order given by the figure below.
    //       minx    midx    maxx
    // miny    2       3       4
    // midy   1 9              5
    // maxy    8       7       6
    // Which gives us a coincident start and end point, which is incidental to this technique, but still doesn't
    // form a closed path, so we still need to close the path to connect the ends correctly.
    // Thus we start by moving to point 1, then adding arcs through each pair of points that follows.
    // You could use a similar tecgnique to create any shape with rounded corners.
    
    // Start at 1
    CGContextMoveToPoint(context, minx, midy);
    // Add an arc through 2 to 3
    CGContextAddArcToPoint(context, minx, miny, midx, miny, radius);
    // Add an arc through 4 to 5
    CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius);
    // Add an arc through 6 to 7
    CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius);
    // Add an arc through 8 to 9
    CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius);
    // Close the path
    CGContextClosePath(context);
    // Fill & stroke the path
    CGContextDrawPath(context, kCGPathFillStroke);
    
    CGContextSetRGBStrokeColor(context, 0.0, 0.0, 0.0, 0.0);
    CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0);
    
    CGContextMoveToPoint(context, minx, midy);
    // Add an arc through 2 to 3
    CGContextAddArcToPoint(context, minx, miny, midx, miny, radius);
    // Add an arc through 4 to 5
    CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius);
    // Add an arc through 6 to 7
    CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius);
    // Add an arc through 8 to 9
    CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius);
    // Close the path
    CGContextClosePath(context);
    // Fill & stroke the path
    CGContextDrawPath(context, kCGPathFillStroke);
}
Ejemplo n.º 8
0
// -----------------------------------------------------------------------------
//	ShadeRectColor
// -----------------------------------------------------------------------------
//
OSStatus ShadeRectColor(
	const CGRGB*		inStartColor,
	const CGRGB*		inEndColor,
	const HIRect*		inRect,
	CGContextRef		inContext )
{
	OSStatus			err = noErr;
	CGColorSpaceRef		colorSpace;
	CGFunctionCallbacks	callbacks = { 0, ColorGradientEvaluate, NULL };
	CGFunctionRef		function;
	CGShadingRef		shading;
	ColorShadeData		data;
	
	// Warning: this stuff is sitting on the stack.  Be careful if you move
	// the shading code around.
	data.start = *inStartColor;
	data.range.red = inEndColor->red - inStartColor->red;
	data.range.green = inEndColor->green - inStartColor->green;
	data.range.blue = inEndColor->blue - inStartColor->blue;
	
	CGContextSaveGState( inContext );
	CGContextClipToRect( inContext, *inRect );

	colorSpace = CGColorSpaceCreateDeviceRGB();
	require_action( colorSpace != NULL, CantCreateColorSpace, err = memFullErr );

	function = CGFunctionCreate(
			&data,			// info
			1,				// domainDimension
			NULL,			// input domain NULL == no range clipping
			4,				// rangeDimension,
			NULL,			// output domain NULL == no range clipping
			&callbacks );	// CGFunctionCallbacks
	require_action( function != NULL, CantCreateFunction, err = memFullErr );

	shading = CGShadingCreateAxial(
			colorSpace,
			inRect->origin,	// start
			CGPointMake( CGRectGetMinX( *inRect ), CGRectGetMaxY( *inRect ) ),	// end
			function,
			false,			// extendStart
			false );		// extendEnd
	require_action( colorSpace != NULL, CantCreateShading, err = memFullErr );

	CGContextDrawShading( inContext, shading);

CantCreateFunction:
	CGShadingRelease( shading );

CantCreateShading:
	CGColorSpaceRelease( colorSpace );

CantCreateColorSpace:
	CGContextRestoreGState( inContext );
	
	return err;
}
Ejemplo n.º 9
0
/* Return dimensions of current main display as an array of two integers */
VALUE MW_display_size(VALUE module) {
    CGRect bounds;
    VALUE retval;

    bounds = CGDisplayBounds(CGMainDisplayID());
    retval = rb_ary_new();
    rb_ary_push(retval, INT2NUM((int)CGRectGetMaxX(bounds)));
    rb_ary_push(retval, INT2NUM((int)CGRectGetMaxY(bounds)));

    return retval;
}
Ejemplo n.º 10
0
bool CGRect::CGRectContainsPoint(const CGRect& rect, const CGPoint& point)
{
    bool bRet = false;

	if (point.x >= CGRectGetMinX(rect) && point.x <= CGRectGetMaxX(rect)
		&& point.y >= CGRectGetMinY(rect) && point.y <= CGRectGetMaxY(rect))
	{
		bRet = true;
	}

	return bRet;
}
Ejemplo n.º 11
0
void QuartzWindow::get_window_region_rect(int wh, Rect* r) {
  HIRect bounds;
  OSStatus err = HIWindowGetBounds(my_window(), wh, 
                                   kHICoordSpace72DPIGlobal, &bounds);
  if (err) {
    lprintf("HIWindowGetBounds failed: %d\n", err);
    r->left = r->top = 0; r->bottom = r->right = 1;
  } else {
    r->left   = (short) CGRectGetMinX(bounds);
    r->top    = (short) CGRectGetMinY(bounds);
    r->bottom = (short) CGRectGetMaxY(bounds);
    r->right  = (short) CGRectGetMaxX(bounds);
  }
}
Ejemplo n.º 12
0
void addRoundedRectToPath(CGContextRef context, CGRect rect, CGFloat radius) {
	CGFloat minX = CGRectGetMinX(rect);
	CGFloat minY = CGRectGetMinY(rect);
	CGFloat maxX = CGRectGetMaxX(rect);
	CGFloat maxY = CGRectGetMaxY(rect);
	CGFloat midX = CGRectGetMidX(rect);
	CGFloat midY = CGRectGetMidY(rect);

	CGContextBeginPath(context);
	CGContextMoveToPoint(context, maxX, midY);
	CGContextAddArcToPoint(context, maxX, maxY, midX, maxY, radius);
	CGContextAddArcToPoint(context, minX, maxY, minX, midY, radius);
	CGContextAddArcToPoint(context, minX, minY, midX, minY, radius);
	CGContextAddArcToPoint(context, maxX, minY, maxX, midY, radius);
	CGContextClosePath(context);
}
Ejemplo n.º 13
0
/***********************************************************************
 *              create_surface_image
 *
 * Caller must hold the surface lock.  On input, *rect is the requested
 * image rect, relative to the window whole_rect, a.k.a. visible_rect.
 * On output, it's been intersected with that part backed by the surface
 * and is the actual size of the returned image.  copy_data indicates if
 * the caller will keep the returned image beyond the point where the
 * surface bits can be guaranteed to remain valid and unchanged.  If so,
 * the bits are copied instead of merely referenced by the image.
 *
 * IMPORTANT: This function is called from non-Wine threads, so it
 *            must not use Win32 or Wine functions, including debug
 *            logging.
 */
CGImageRef create_surface_image(void *window_surface, CGRect *rect, int copy_data)
{
    CGImageRef cgimage = NULL;
    struct macdrv_window_surface *surface = get_mac_surface(window_surface);
    int width, height;

    width  = surface->header.rect.right - surface->header.rect.left;
    height = surface->header.rect.bottom - surface->header.rect.top;
    *rect = CGRectIntersection(cgrect_from_rect(surface->header.rect), *rect);
    if (!CGRectIsEmpty(*rect))
    {
        CGRect visrect;
        CGColorSpaceRef colorspace;
        CGDataProviderRef provider;
        int bytes_per_row, offset, size;
        CGImageAlphaInfo alphaInfo;

        visrect = CGRectOffset(*rect, -surface->header.rect.left, -surface->header.rect.top);

        colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
        bytes_per_row = get_dib_stride(width, 32);
        offset = CGRectGetMinX(visrect) * 4 + (height - CGRectGetMaxY(visrect)) * bytes_per_row;
        size = min(CGRectGetHeight(visrect) * bytes_per_row,
                   surface->info.bmiHeader.biSizeImage - offset);

        if (copy_data)
        {
            CFDataRef data = CFDataCreate(NULL, (UInt8*)surface->bits + offset, size);
            provider = CGDataProviderCreateWithCFData(data);
            CFRelease(data);
        }
        else
            provider = CGDataProviderCreateWithData(NULL, surface->bits + offset, size, NULL);

        alphaInfo = surface->use_alpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst;
        cgimage = CGImageCreate(CGRectGetWidth(visrect), CGRectGetHeight(visrect),
                                8, 32, bytes_per_row, colorspace,
                                alphaInfo | kCGBitmapByteOrder32Little,
                                provider, NULL, FALSE, kCGRenderingIntentDefault);
        CGDataProviderRelease(provider);
        CGColorSpaceRelease(colorspace);
    }

    return cgimage;
}
Ejemplo n.º 14
0
void
infoDisplays(void)
{
    CGDisplayErr      dErr;
    CGDisplayCount    displayCount, i;
    CGDirectDisplayID mainDisplay;
    CGDisplayCount    maxDisplays = MAX_DISPLAYS;
    CGDirectDisplayID onlineDisplays[MAX_DISPLAYS];
    
    CGEventRef ourEvent = CGEventCreate(NULL);
    CGPoint ourLoc = CGEventGetLocation(ourEvent);
    
    CFRelease(ourEvent);
    
    mainDisplay = CGMainDisplayID();
   
    dErr = CGGetOnlineDisplayList(maxDisplays, onlineDisplays, &displayCount);
    if (dErr != kCGErrorSuccess) {
        fprintf(stderr, "CGGetOnlineDisplayList: error %d.\n", dErr);
        exit(1);
    }
   
    printf("#  Display_ID  Resolution  ____Display_Bounds____  Rotation\n");
    for (i = 0; i < displayCount; i++) {
        CGDirectDisplayID dID = onlineDisplays[i];
        printf("%-2d %10p  %4lux%-4lu  %5.0f %5.0f %5.0f %5.0f    %3.0f    %s%s%s", 
               CGDisplayUnitNumber (dID), dID,
               CGDisplayPixelsWide(dID), CGDisplayPixelsHigh(dID),
               CGRectGetMinX (CGDisplayBounds (dID)),
               CGRectGetMinY (CGDisplayBounds (dID)),
               CGRectGetMaxX (CGDisplayBounds (dID)),
               CGRectGetMaxY (CGDisplayBounds (dID)),           
               CGDisplayRotation (dID),
               (CGDisplayIsActive (dID)) ? "" : "[inactive]",
               (dID == mainDisplay) ? "[main]" : "",
               (CGDisplayIsBuiltin (dID)) ? "[internal]\n" : "\n");
    }
    
    printf("Mouse Cursor Position:  ( %5.0f , %5.0f )\n",
               (float)ourLoc.x, (float)ourLoc.y);
   
    exit(0);
}
Ejemplo n.º 15
0
oop GetWindowRegion_wrap( WindowRef w, uint16 reg, void* FH) {
  // 
  // TODO: GetWindoRegion is deprecated and not avialiable in >=10.7
  // For now, we emulate with HIWindowGetBounds
  //
  HIRect bounds;
  OSStatus err = HIWindowGetBounds((WindowRef)w, reg, 
                                   kHICoordSpace72DPIGlobal, &bounds);
  if (err) {
    return  (oop)reportOSError(err, "GetWindowRegion", FH);
  }

  objVectorOop r = Memory->objVectorObj->cloneSize(4);
//  r->obj_at_put(0, as_floatOop(CGRectGetMinX(bounds)), false);
//  r->obj_at_put(1, as_floatOop(CGRectGetMinY(bounds)), false);
//  r->obj_at_put(2, as_floatOop(CGRectGetMaxX(bounds)), false);
//  r->obj_at_put(3, as_floatOop(CGRectGetMaxY(bounds)), false);
  r->obj_at_put(0, as_smiOop((short)CGRectGetMinX(bounds)), false);
  r->obj_at_put(1, as_smiOop((short)CGRectGetMinY(bounds)), false);
  r->obj_at_put(2, as_smiOop((short)CGRectGetMaxX(bounds)), false);
  r->obj_at_put(3, as_smiOop((short)CGRectGetMaxY(bounds)), false);
  
  return r;
}
Ejemplo n.º 16
0
CGPoint CGRectBottomRightPoint(CGRect rect)
{
	return CGPointMake(CGRectGetMaxX(rect), CGRectGetMaxY(rect));
}
Ejemplo n.º 17
0
static cairo_int_status_t
_cairo_quartz_init_glyph_metrics (cairo_quartz_scaled_font_t *font,
				  cairo_scaled_glyph_t *scaled_glyph)
{
    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;

    cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font);
    cairo_text_extents_t extents = {0, 0, 0, 0, 0, 0};
    CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);
    int advance;
    CGRect bbox;
    double emscale = CGFontGetUnitsPerEmPtr (font_face->cgFont);
    double xmin, ymin, xmax, ymax;

    if (glyph == INVALID_GLYPH)
	goto FAIL;

    if (!CGFontGetGlyphAdvancesPtr (font_face->cgFont, &glyph, 1, &advance) ||
	!CGFontGetGlyphBBoxesPtr (font_face->cgFont, &glyph, 1, &bbox))
	goto FAIL;

    /* broken fonts like Al Bayan return incorrect bounds for some null characters,
       see https://bugzilla.mozilla.org/show_bug.cgi?id=534260 */
    if (unlikely (bbox.origin.x == -32767 &&
                  bbox.origin.y == -32767 &&
                  bbox.size.width == 65534 &&
                  bbox.size.height == 65534)) {
        bbox.origin.x = bbox.origin.y = 0;
        bbox.size.width = bbox.size.height = 0;
    }

    bbox = CGRectMake (bbox.origin.x / emscale,
		       bbox.origin.y / emscale,
		       bbox.size.width / emscale,
		       bbox.size.height / emscale);

    /* Should we want to always integer-align glyph extents, we can do so in this way */
#if 0
    {
	CGAffineTransform textMatrix;
	textMatrix = CGAffineTransformMake (font->base.scale.xx,
					    -font->base.scale.yx,
					    -font->base.scale.xy,
					    font->base.scale.yy,
					    0.0f, 0.0f);

	bbox = CGRectApplyAffineTransform (bbox, textMatrix);
	bbox = CGRectIntegral (bbox);
	bbox = CGRectApplyAffineTransform (bbox, CGAffineTransformInvert (textMatrix));
    }
#endif

#if 0
    fprintf (stderr, "[0x%04x] bbox: %f %f %f %f\n", glyph,
	     bbox.origin.x / emscale, bbox.origin.y / emscale,
	     bbox.size.width / emscale, bbox.size.height / emscale);
#endif

    xmin = CGRectGetMinX(bbox);
    ymin = CGRectGetMinY(bbox);
    xmax = CGRectGetMaxX(bbox);
    ymax = CGRectGetMaxY(bbox);

    extents.x_bearing = xmin;
    extents.y_bearing = - ymax;
    extents.width = xmax - xmin;
    extents.height = ymax - ymin;

    extents.x_advance = (double) advance / emscale;
    extents.y_advance = 0.0;

#if 0
    fprintf (stderr, "[0x%04x] extents: bearings: %f %f dim: %f %f adv: %f\n\n", glyph,
	     extents.x_bearing, extents.y_bearing, extents.width, extents.height, extents.x_advance);
#endif

  FAIL:
    _cairo_scaled_glyph_set_metrics (scaled_glyph,
				     &font->base,
				     &extents);

    return status;
}
Ejemplo n.º 18
0
CGRect CGRectStackedWithinRectFromEdge(CGRect rect, CGSize size, int count, CGRectEdge edge, bool reverse)
{
    int max_columns = floor(rect.size.width / size.width);
    int max_rows = floor(rect.size.height / size.height);

    if (edge == CGRectMinYEdge) {
        int current_row = floor(count / max_columns);
        int current_col = (count - 1) % max_columns;
        if (reverse) current_col = max_columns - (current_col + 1);
        if (current_col > max_columns || current_row > max_rows) {
            return CGRectNull;
        }
        else {
            CGFloat x = CGRectGetMinX(rect) + (current_col * size.width);
            CGFloat y = CGRectGetMinY(rect) + (current_row * size.height);
            return CGRectMake(x, y, size.width, size.height);
        }
    }

    else if (edge == CGRectMaxYEdge) {
        int current_row = floor(count / max_columns);
        int current_col = (count - 1) % max_columns;
        if (!reverse) current_col = max_columns - (current_col + 1);
        if (current_col > max_columns || current_row > max_rows) {
            return CGRectNull;
        }
        else {
            CGFloat x = CGRectGetMinX(rect) + (current_col * size.width);
            CGFloat y = CGRectGetMaxY(rect) - size.height - (current_row * size.height);
            return CGRectMake(x, y, size.width, size.height);
        }
    }

    else if (edge == CGRectMinXEdge) {
        int current_col = floor(count / max_columns);
        int current_row = (count - 1) % max_columns;
        if (!reverse) current_row = max_rows - (current_row + 1);
        if (current_col > max_columns || current_row > max_rows) {
            return CGRectNull;
        }
        else {
            CGFloat x = CGRectGetMinX(rect) + (current_col * size.width);
            CGFloat y = CGRectGetMinY(rect) + (current_row * size.height);
            return CGRectMake(x, y, size.width, size.height);
        }
    }

    else if (edge == CGRectMaxXEdge) {
        int current_col = floor(count / max_columns);
        int current_row = (count - 1) % max_columns;
        if (reverse) current_row = max_rows - (current_row + 1);
        if (current_col > max_columns || current_row > max_rows) {
            return CGRectNull;
        }
        else {
            CGFloat x = CGRectGetMaxX(rect) - size.width - (current_col * size.width);
            CGFloat y = CGRectGetMinY(rect) + current_row * size.height;
            return CGRectMake(x, y, size.width, size.height);
        }
    }

    return CGRectNull;
}
Ejemplo n.º 19
0
CGPoint CGRectBottomLeftPoint(CGRect rect)
{
	return CGPointMake(CGRectGetMinX(rect), CGRectGetMaxY(rect));
}
static cairo_int_status_t
_cairo_quartz_init_glyph_metrics (cairo_quartz_scaled_font_t *font,
				  cairo_scaled_glyph_t *scaled_glyph)
{
    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;

    cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font);
    cairo_text_extents_t extents = {0, 0, 0, 0, 0, 0};
    CGAffineTransform textMatrix;
    CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);
    int advance;
    CGRect bbox;
    double emscale = CGFontGetUnitsPerEmPtr (font_face->cgFont);
    double xscale, yscale;
    double xmin, ymin, xmax, ymax;

    if (glyph == INVALID_GLYPH)
	goto FAIL;

    if (!CGFontGetGlyphAdvancesPtr (font_face->cgFont, &glyph, 1, &advance) ||
	!CGFontGetGlyphBBoxesPtr (font_face->cgFont, &glyph, 1, &bbox))
	goto FAIL;

    status = _cairo_matrix_compute_basis_scale_factors (&font->base.scale,
						  &xscale, &yscale, 1);
    if (status)
	goto FAIL;

    bbox = CGRectMake (bbox.origin.x / emscale,
		       bbox.origin.y / emscale,
		       bbox.size.width / emscale,
		       bbox.size.height / emscale);

    /* Should we want to always integer-align glyph extents, we can do so in this way */
#if 0
    {
	CGAffineTransform textMatrix;
	textMatrix = CGAffineTransformMake (font->base.scale.xx,
					    -font->base.scale.yx,
					    -font->base.scale.xy,
					    font->base.scale.yy,
					    0.0f, 0.0f);

	bbox = CGRectApplyAffineTransform (bbox, textMatrix);
	bbox = CGRectIntegral (bbox);
	bbox = CGRectApplyAffineTransform (bbox, CGAffineTransformInvert (textMatrix));
    }
#endif

#if 0
    fprintf (stderr, "[0x%04x] bbox: %f %f %f %f\n", glyph,
	     bbox.origin.x / emscale, bbox.origin.y / emscale,
	     bbox.size.width / emscale, bbox.size.height / emscale);
#endif

    xmin = CGRectGetMinX(bbox);
    ymin = CGRectGetMinY(bbox);
    xmax = CGRectGetMaxX(bbox);
    ymax = CGRectGetMaxY(bbox);

    extents.x_bearing = xmin;
    extents.y_bearing = - ymax;
    extents.width = xmax - xmin;
    extents.height = ymax - ymin;

    extents.x_advance = (double) advance / emscale;
    extents.y_advance = 0.0;

#if 0
    fprintf (stderr, "[0x%04x] extents: bearings: %f %f dim: %f %f adv: %f\n\n", glyph,
	     extents.x_bearing, extents.y_bearing, extents.width, extents.height, extents.x_advance);
#endif

  FAIL:
    _cairo_scaled_glyph_set_metrics (scaled_glyph,
				     &font->base,
				     &extents);

    return status;
}