static void Quartz_SetLineMitre(double lmitre, NewDevDesc *dd) { QuartzDesc *xd = (QuartzDesc*)dd->deviceSpecific; if (lmitre < 1) error(_("Invalid line mitre")); CGContextSetMiterLimit( GetContext(xd), lmitre); }
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; }
static void quartzgen_begin_page(GVJ_t *job) { CGRect bounds = CGRectMake(0.0, 0.0, job->width, job->height); if (!job->context) { switch (job->device.id) { case FORMAT_PDF: { /* create the auxiliary info for PDF content, author and title */ CFStringRef auxiliaryKeys[] = { kCGPDFContextCreator, kCGPDFContextTitle }; CFStringRef auxiliaryValues[] = { CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s %s"), job->common->info[0], job->common->info[1]), job->obj->type == ROOTGRAPH_OBJTYPE ? CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)job->obj->u.g->name, strlen(job->obj->u.g->name), kCFStringEncodingUTF8, false, kCFAllocatorNull) : CFSTR("") }; CFDictionaryRef auxiliaryInfo = CFDictionaryCreate( kCFAllocatorDefault, (const void **)&auxiliaryKeys, (const void **)&auxiliaryValues, sizeof(auxiliaryValues)/sizeof(auxiliaryValues[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); /* create a PDF for drawing into */ CGDataConsumerRef data_consumer = CGDataConsumerCreate(job, &device_data_consumer_callbacks); job->context = CGPDFContextCreate(data_consumer, &bounds, auxiliaryInfo); /* clean up */ CGDataConsumerRelease(data_consumer); CFRelease(auxiliaryInfo); int i; for (i = 0; i < sizeof(auxiliaryValues)/sizeof(auxiliaryValues[0]); ++i) CFRelease(auxiliaryValues[i]); } break; default: /* bitmap formats */ { size_t bytes_per_row = (job->width * BYTES_PER_PIXEL + BYTE_ALIGN) & ~BYTE_ALIGN; void* buffer = NULL; #if __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 20000 /* iPhoneOS has no swap files for memory, so if we're short of memory we need to make our own temp scratch file to back it */ size_t buffer_size = job->height * bytes_per_row; mach_msg_type_number_t vm_info_size = HOST_VM_INFO_COUNT; vm_statistics_data_t vm_info; if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vm_info, &vm_info_size) != KERN_SUCCESS || buffer_size * 2 > vm_info.free_count * vm_page_size) { FILE* temp_file = tmpfile(); if (temp_file) { int temp_file_descriptor = fileno(temp_file); if (temp_file_descriptor >= 0 && ftruncate(temp_file_descriptor, buffer_size) == 0) { buffer = mmap( NULL, buffer_size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, temp_file_descriptor, 0); if (buffer == (void*)-1) buffer = NULL; } fclose(temp_file); } } if (!buffer) buffer = mmap( NULL, buffer_size, PROT_READ | PROT_WRITE, MAP_ANON| MAP_SHARED, -1, 0); #endif /* create a true color bitmap for drawing into */ CGColorSpaceRef color_space = CGColorSpaceCreateDeviceRGB(); job->context = CGBitmapContextCreate( buffer, /* data: MacOSX lets system allocate, iPhoneOS use manual memory mapping */ job->width, /* width in pixels */ job->height, /* height in pixels */ BITS_PER_COMPONENT, /* bits per component */ bytes_per_row, /* bytes per row: align to 16 byte boundary */ color_space, /* color space: device RGB */ kCGImageAlphaPremultipliedFirst /* bitmap info: premul ARGB has best support in OS X */ ); job->imagedata = CGBitmapContextGetData((CGContextRef)job->context); /* clean up */ CGColorSpaceRelease(color_space); } break; } } /* start the page (if this is a paged context) and graphics state */ CGContextRef context = (CGContextRef)job->context; CGContextBeginPage(context, &bounds); CGContextSaveGState(context); CGContextSetMiterLimit(context, 1.0); CGContextSetLineJoin(context, kCGLineJoinRound); /* set up the context transformation */ CGContextScaleCTM(context, job->scale.x, job->scale.y); CGContextRotateCTM(context, -job->rotation * M_PI / 180.0); CGContextTranslateCTM(context, job->translation.x, job->translation.y); }
void GraphicsContext::setMiterLimit(float limit) { if (paintingDisabled()) return; CGContextSetMiterLimit(platformContext(), limit); }
void MyTimerProc ( EventLoopTimerRef inTimer, void *inUserData ) { WindowRef window = (WindowRef)inUserData; static int i = 0; static int j = 0; static int step = 5; GrafPtr curPort; CGContextRef context; CGrafPtr windowPort = GetWindowPort( window ); GetPort(&curPort); SetPort(windowPort); CreateCGContextForPort( windowPort, &context ); // Do our drawing in here CGContextSetGrayFillColor( context, 0.0, 1.0 ); CGContextFillRect( context, CGRectMake( 0, 0, 800, 600 ) ); CGContextSetGrayFillColor( context, 1.0, 1.0 ); CGContextSetRGBStrokeColor( context, 1.0, 0.0, 0.0, 1.0 ); CGContextSetLineWidth( context, 5.0 ); CGContextSetLineCap( context, kCGLineCapRound ); CGContextSetLineJoin( context, kCGLineJoinRound ); CGContextSetMiterLimit( context, 5 ); // Draw each of the 4 transform demos // // 1. Translate - move the origin, draw the graphic // Place the origin in the llh corner of the upper left quadrant CGContextSaveGState( context ); CGContextTranslateCTM( context, i / 2, i / 2 + 300 ); CGContextRotateCTM( context, -2.0 * 3.1416 / 8 ); drawGraphic( context, 0, 0 ); CGContextRestoreGState( context ); // 2. Rotate - move origin, do rotation, draw the graphic // Put the origin back into the llh corner of the upper right quadrant CGContextSaveGState( context ); if ( j < 1000/2 ) { // Rotate around left circle CGContextTranslateCTM( context, 500, 450 ); CGContextRotateCTM( context, -j * 3.1416 * 2.0 / 500.0 - 3.1416 ); CGContextTranslateCTM( context, -100, -20 ); drawGraphic( context, 0, 0 ); } if ( j >= 1000/2 ) { // Rotate under bottom half and over top right 1/4 CGContextTranslateCTM( context, 700, 450 ); CGContextRotateCTM( context, j * 3.1416 * 2.0 / 500.0 ); CGContextScaleCTM( context, 1, 1 ); CGContextTranslateCTM( context, -100, 20 ); CGContextRotateCTM( context, 3.1416 ); drawGraphic( context, 0, 0 ); } CGContextRestoreGState( context ); // 3. Scale - move origin, set scale, draw the graphic CGContextSaveGState( context ); CGContextScaleCTM( context, i * 400.0 / 500.0 / 40.0, i * 300.0 / 500.0 / 40.0 ); CGContextRotateCTM( context, -3.1416 / 4 ); drawGraphic( context, 0, 0 ); CGContextRestoreGState( context ); // 4. Show the basic graphic CGContextTranslateCTM( context, 600, 150 ); drawGraphic( context, 0, 0 ); CGContextFlush( context ); CGContextRelease( context ); SetPort ( curPort ); i += step; j += abs( step ); if ( i >= 500 ) { step = -step; } if ( i <= 0 ) { step = -step; j = 0; } }