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; }
CGPoint CGPointRotatedAroundPoint(CGPoint point, CGPoint pivot, CGFloat degrees) { CGAffineTransform translation, rotation; translation = CGAffineTransformMakeTranslation(-pivot.x, -pivot.y); point = CGPointApplyAffineTransform(point, translation); rotation = CGAffineTransformMakeRotation(degrees * M_PI/180.0); point = CGPointApplyAffineTransform(point, rotation); translation = CGAffineTransformMakeTranslation(pivot.x, pivot.y); point = CGPointApplyAffineTransform(point, translation); return point; }
CGRect CGRectApplyAffineTransform(CGRect rect,CGAffineTransform transform) { if (fabs(rect.origin.x)==CGFLOAT_MAX || fabs(rect.origin.y)==CGFLOAT_MAX) { return rect; } CGPoint points[4]; points[0]=rect.origin; points[1]=CGPointMake(rect.origin.x,rect.origin.y+rect.size.height); points[2]=CGPointMake(rect.origin.x+rect.size.width,rect.origin.y+rect.size.height); points[3]=CGPointMake(rect.origin.x+rect.size.width,rect.origin.y); for (size_t i=0;i!=countof(points);++i) { points[i]=CGPointApplyAffineTransform(points[i],transform); } CGPoint topLeft=points[0]; CGPoint rightBottom=points[0]; for (size_t i=0;i!=countof(points);++i) { if (topLeft.x>points[i].x) { topLeft.x=points[i].x; } if (rightBottom.x<points[i].x) { rightBottom.x=points[i].x; } if (topLeft.y>points[i].y) { topLeft.y=points[i].y; } if (rightBottom.y<points[i].y) { rightBottom.y=points[i].y; } } rect.origin=topLeft; rect.size.width=rightBottom.x-topLeft.x; rect.size.height=rightBottom.y-topLeft.y; return rect; }
FX_BOOL CFX_QuartzDeviceDriver::GetDIBits(CFX_DIBitmap* bitmap, FX_INT32 left, FX_INT32 top, void* pIccTransform, FX_BOOL bDEdge) { if (FXDC_PRINTER == _deviceClass) { return FALSE; } if (bitmap->GetBPP() < 32) { return FALSE; } if (!(_renderCaps | FXRC_GET_BITS)) { return FALSE; } CGPoint pt = CGPointMake(left, top); pt = CGPointApplyAffineTransform(pt, _foxitDevice2User); CGAffineTransform ctm = CGContextGetCTM(_context); pt.x *= FXSYS_fabs(ctm.a); pt.y *= FXSYS_fabs(ctm.d); CGImageRef image = CGBitmapContextCreateImage(_context); if (NULL == image) { return FALSE; } CGFloat width = (CGFloat) bitmap->GetWidth(); CGFloat height = (CGFloat) bitmap->GetHeight(); if (width + pt.x > _width) { width -= (width + pt.x - _width); } if (height + pt.y > _height) { height -= (height + pt.y - _height); } CGImageRef subImage = CGImageCreateWithImageInRect(image, CGRectMake(pt.x, pt.y, width, height)); CGContextRef context = createContextWithBitmap(bitmap); CGRect rect = CGContextGetClipBoundingBox(context); CGContextClearRect(context, rect); CGContextDrawImage(context, rect, subImage); CGContextRelease(context); CGImageRelease(subImage); CGImageRelease(image); if (bitmap->HasAlpha()) { for (int row = 0; row < bitmap->GetHeight(); row ++) { FX_LPBYTE pScanline = (FX_LPBYTE)bitmap->GetScanline(row); for (int col = 0; col < bitmap->GetWidth(); col ++) { if (pScanline[3] > 0) { pScanline[0] = (pScanline[0] * 255.f / pScanline[3] + .5f); pScanline[1] = (pScanline[1] * 255.f / pScanline[3] + .5f); pScanline[2] = (pScanline[2] * 255.f / pScanline[3] + .5f); } pScanline += 4; } } } return TRUE; }
CGPoint CGPointRotateAround(CGPoint point, CGPoint pivot, CGFloat angle) { CGPoint result = CGPointApplyAffineTransform(CGPointSubtract(point, pivot), CGAffineTransformMakeRotation(angle)); result = CGPointAdd(result, pivot); return result; }
void wkSetPatternPhaseInUserSpace(CGContextRef context, CGPoint phasePoint) { CGAffineTransform userToBase = CGAffineTransformConcat(CGContextGetCTM(context), CGAffineTransformInvert(CGContextGetBaseCTM(context))); CGPoint phase = CGPointApplyAffineTransform(phasePoint, userToBase); CGContextSetPatternPhase(context, CGSizeMake(phase.x, phase.y)); }
//----------------------------------------------------------------------------- void CGDrawContext::drawCGImageRef (CGContextRef context, CGImageRef image, CGLayerRef layer, double bitmapScaleFactor, const CRect& inRect, const CPoint& inOffset, float alpha, CBitmap* bitmap) { CRect rect (inRect); CPoint offset (inOffset); CGContextSetAlpha (context, (CGFloat)alpha*currentState.globalAlpha); CGRect dest; dest.origin.x = static_cast<CGFloat> (rect.left - offset.x); dest.origin.y = static_cast<CGFloat> (-(rect.top) - (bitmap->getHeight () - offset.y)); dest.size.width = static_cast<CGFloat> (bitmap->getWidth ()); dest.size.height = static_cast<CGFloat> (bitmap->getHeight ()); CGRect clipRect; clipRect.origin.x = static_cast<CGFloat> (rect.left); clipRect.origin.y = static_cast<CGFloat> (-(rect.top) - rect.getHeight ()); clipRect.size.width = static_cast<CGFloat> (rect.getWidth ()); clipRect.size.height = static_cast<CGFloat> (rect.getHeight ()); if (bitmapScaleFactor != 1.) { CGContextConcatCTM (context, CGAffineTransformMakeScale (static_cast<CGFloat> (1./bitmapScaleFactor), static_cast<CGFloat> (1./bitmapScaleFactor))); CGAffineTransform transform = CGAffineTransformMakeScale (static_cast<CGFloat> (bitmapScaleFactor), static_cast<CGFloat> (bitmapScaleFactor)); clipRect.origin = CGPointApplyAffineTransform (clipRect.origin, transform); clipRect.size = CGSizeApplyAffineTransform (clipRect.size, transform); dest.origin = CGPointApplyAffineTransform (dest.origin, transform); dest.size = CGSizeApplyAffineTransform (dest.size, transform); } dest = pixelAlligned (dest); clipRect = pixelAlligned (clipRect); CGContextClipToRect (context, clipRect); if (layer) { CGContextDrawLayerInRect (context, dest, layer); } else { CGContextDrawImage (context, dest, image); } }
JNIEXPORT void JNICALL OS_NATIVE(CGPointApplyAffineTransform) (JNIEnv *env, jclass that, jobject arg0, jfloatArray arg1, jobject arg2) { CGPoint _arg0, *lparg0=NULL; jfloat *lparg1=NULL; CGPoint _arg2, *lparg2=NULL; OS_NATIVE_ENTER(env, that, CGPointApplyAffineTransform_FUNC); if (arg0) if ((lparg0 = getCGPointFields(env, arg0, &_arg0)) == NULL) goto fail; if (arg1) if ((lparg1 = (*env)->GetFloatArrayElements(env, arg1, NULL)) == NULL) goto fail; if (arg2) if ((lparg2 = getCGPointFields(env, arg2, &_arg2)) == NULL) goto fail; *(CGPoint *)lparg2 = CGPointApplyAffineTransform(*(CGPoint *)lparg0, *(CGAffineTransform *)lparg1); fail: if (arg2 && lparg2) setCGPointFields(env, arg2, lparg2); if (arg1 && lparg1) (*env)->ReleaseFloatArrayElements(env, arg1, lparg1, JNI_ABORT); OS_NATIVE_EXIT(env, that, CGPointApplyAffineTransform_FUNC); }
void AffineTransform::map(double x, double y, double *x2, double *y2) const { CGPoint result = CGPointApplyAffineTransform(CGPointMake(x,y),m_transform); *x2 = result.x; *y2 = result.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; }
FX_BOOL CFX_QuartzDeviceDriver::CG_DrawGlypRun(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont, CFX_FontCache* pCache, const CFX_AffineMatrix* pGlyphMatrix, const CFX_AffineMatrix* pObject2Device, FX_FLOAT font_size, FX_DWORD argb, int alpha_flag, void* pIccTransform) { if (nChars == 0) { return TRUE; } CQuartz2D& quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d; if (!pFont->m_pPlatformFont) { if (pFont->GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) { return FALSE; } pFont->m_pPlatformFont = quartz2d.CreateFont(pFont->m_pFontData, pFont->m_dwSize); if (NULL == pFont->m_pPlatformFont) { return FALSE; } } CFX_FixedBufGrow<FX_WORD, 32> glyph_indices(nChars); CFX_FixedBufGrow<CGPoint, 32> glyph_positions(nChars); for (int i = 0; i < nChars; i++ ) { glyph_indices[i] = pCharPos[i].m_ExtGID; glyph_positions[i].x = pCharPos[i].m_OriginX; glyph_positions[i].y = pCharPos[i].m_OriginY; } CFX_AffineMatrix text_matrix; if (pObject2Device) { text_matrix.Concat(*pObject2Device); } CGAffineTransform matrix_cg = CGAffineTransformMake(text_matrix.a, text_matrix.b, text_matrix.c, text_matrix.d, text_matrix.e, text_matrix.f); matrix_cg = CGAffineTransformConcat(matrix_cg, _foxitDevice2User); CGContextSetTextMatrix(_context, matrix_cg); CGContextSetFont(_context, (CGFontRef)pFont->m_pPlatformFont); CGContextSetFontSize(_context, FXSYS_fabs(font_size)); FX_INT32 a, r, g, b; ArgbDecode(argb, a, r, g, b); CGContextSetRGBFillColor(_context, r / 255.f, g / 255.f, b / 255.f, a / 255.f); SaveState(); if (pGlyphMatrix) { CGPoint origin = CGPointMake( glyph_positions[0].x, glyph_positions[0].y); origin = CGPointApplyAffineTransform(origin, matrix_cg); CGContextTranslateCTM(_context, origin.x, origin.y); CGAffineTransform glyph_matrix = CGAffineTransformMake(pGlyphMatrix->a, pGlyphMatrix->b, pGlyphMatrix->c, pGlyphMatrix->d, pGlyphMatrix->e, pGlyphMatrix->f); if (_foxitDevice2User.d < 0) { glyph_matrix = CGAffineTransformInvert(glyph_matrix); } CGContextConcatCTM(_context, glyph_matrix); CGContextTranslateCTM(_context, -origin.x, -origin.y); } CGContextShowGlyphsAtPositions(_context, (CGGlyph*)glyph_indices, glyph_positions, nChars); RestoreState(FALSE); return TRUE; }