void GiCanvasIos::endPaint(bool draw) { if (m_draw->getContext()) { if (draw && m_draw->_buffctx && m_draw->_context) { CGContextRef context = m_draw->_context; CGImageRef image = CGBitmapContextCreateImage(m_draw->_buffctx); CGRect rect = CGRectMake(0, 0, m_draw->width(), m_draw->height()); // 逻辑宽高点数 if (image) { CGAffineTransform af = CGAffineTransformMake(1, 0, 0, -1, 0, m_draw->height()); CGContextConcatCTM(context, af); // 图像是朝上的,上下文坐标系朝下,上下颠倒显示 CGInterpolationQuality old = CGContextGetInterpolationQuality(context); CGContextSetInterpolationQuality(context, kCGInterpolationNone); CGContextDrawImage(context, rect, image); CGContextSetInterpolationQuality(context, old); CGContextConcatCTM(context, CGAffineTransformInvert(af)); // 恢复成坐标系朝下 CGImageRelease(image); } } if (m_draw->_buffctx) { CGContextRelease(m_draw->_buffctx); m_draw->_buffctx = NULL; } m_draw->_context = NULL; if (owner()) owner()->_endPaint(); } }
void drawSkewedCoordinateSystem(CGContextRef context) { // alpha is 22.5 degrees and beta is 15 degrees. float alpha = M_PI/8, beta = M_PI/12; CGAffineTransform skew; // Create a rectangle that is 72 units on a side // with its origin at (0,0). CGRect r = CGRectMake(0, 0, 72, 72); CGContextTranslateCTM(context, 144, 144); // Draw the coordinate axes untransformed. drawCoordinateAxes(context); // Fill the rectangle. CGContextFillRect(context, r); // Create an affine transform that skews the coordinate system, // skewing the x-axis by alpha radians and the y-axis by beta radians. skew = CGAffineTransformMake(1, tan(alpha), tan(beta), 1, 0, 0); // Apply that transform to the context coordinate system. CGContextConcatCTM(context, skew); // Set the fill and stroke color to a dark blue. CGContextSetRGBStrokeColor(context, 0.11, 0.208, 0.451, 1); CGContextSetRGBFillColor(context, 0.11, 0.208, 0.451, 1); // Draw the coordinate axes again, now transformed. drawCoordinateAxes(context); // Set the fill color again but with a partially transparent alpha. CGContextSetRGBFillColor(context, 0.11, 0.208, 0.451, 0.7); // Fill the rectangle in the transformed coordinate system. CGContextFillRect(context, r); }
bool GiCanvasIos::drawImage(CGImageRef image, const Point2d& centerM, bool autoScale) { CGContextRef context = m_draw->getContext(); bool ret = false; if (context && image) { Point2d ptD = centerM * m_draw->xf().modelToDisplay(); float w = CGImageGetWidth(image); float h = CGImageGetHeight(image); if (autoScale) { w *= m_draw->xf().getViewScale(); h *= m_draw->xf().getViewScale(); } CGAffineTransform af = CGAffineTransformMake(1, 0, 0, -1, 0, m_draw->height()); af = CGAffineTransformTranslate(af, ptD.x - w * 0.5f, m_draw->height() - (ptD.y + h * 0.5f)); CGContextConcatCTM(context, af); CGContextDrawImage(context, CGRectMake(0, 0, w, h), image); CGContextConcatCTM(context, CGAffineTransformInvert(af)); ret = true; } return ret; }
static inline cairo_status_t _cairo_matrix_to_unit_quartz_matrix (const cairo_matrix_t *m, CGAffineTransform *txout, double *xout, double *yout) { CGAffineTransform transform; double xscale, yscale; cairo_status_t status; status = _cairo_matrix_compute_basis_scale_factors (m, &xscale, &yscale, 1); if (status) return status; transform = CGAffineTransformMake (m->xx, - m->yx, - m->xy, m->yy, 0.0f, 0.0f); if (xout) *xout = xscale; if (yout) *yout = yscale; if (xscale) xscale = 1.0 / xscale; if (yscale) yscale = 1.0 / yscale; *txout = CGAffineTransformScale (transform, xscale, yscale); return CAIRO_STATUS_SUCCESS; }
bool GiCanvasIos::drawCachedBitmap2(const GiCanvas* p, float x, float y, bool secondBmp) { bool ret = false; if (p && p->getCanvasType() == getCanvasType()) { GiCanvasIos* gs = (GiCanvasIos*)p; int index = secondBmp ? 1 : 0; CGImageRef image = gs->m_draw->_cacheserr[index] ? NULL : gs->m_draw->_caches[index]; CGContextRef context = m_draw->getContext(); if (context && image) { CGRect rect = CGRectMake(x, y, m_draw->width(), m_draw->height()); CGAffineTransform af = CGAffineTransformMake(1, 0, 0, -1, 0, m_draw->height()); CGContextConcatCTM(context, af); CGInterpolationQuality oldQuality = CGContextGetInterpolationQuality(context); CGContextSetInterpolationQuality(context, kCGInterpolationNone); CGContextDrawImage(context, rect, image); CGContextSetInterpolationQuality(context, oldQuality); CGContextConcatCTM(context, CGAffineTransformInvert(af)); ret = true; } } return ret; }
CGImageRef GiCanvasIos::cachedBitmap(bool invert) { CGImageRef image = m_draw->_caches[0]; if (!image || !invert) return image; // 调用者不能释放图像 size_t w = CGImageGetWidth(image); // 图像宽度,像素单位,不是点单位 size_t h = CGImageGetHeight(image); CGImageRef newimg = NULL; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, w * 4, colorSpace, kCGImageAlphaPremultipliedLast); CGColorSpaceRelease(colorSpace); if (context) { CGAffineTransform af = CGAffineTransformMake(1, 0, 0, -1, 0, h); CGContextConcatCTM(context, af); // 图像是朝上的,上下文坐标系朝下,上下颠倒显示 CGContextDrawImage(context, CGRectMake(0, 0, w, h), image); CGContextConcatCTM(context, CGAffineTransformInvert(af)); newimg = CGBitmapContextCreateImage(context); // 得到上下颠倒的新图像 CGContextRelease(context); } return newimg; // 由调用者释放图像, CGImageRelease }
static void TransformHIViewToCG(CGContextRef ctx, HIViewRef theView) { // Undo the HIView coordinate flipping HIRect bounds; HIViewGetBounds(theView, &bounds); CGContextConcatCTM(ctx, CGAffineTransformMake(1, 0, 0, -1, 0, bounds.size.height)); }
void addOvalToPath(CGContextRef context, CGRect r) { CGAffineTransform matrix; // Save the context's state because we are going to transform and scale it CGContextSaveGState(context); // Create a transform to scale the context so that a radius of 1 // is equal to the bounds of the rectangle, and transform the origin // of the context to the center of the bounding rectangle. The // center of the bounding rectangle will now be the center of // the oval. matrix = CGAffineTransformMake((r.size.width)/2, 0, 0, (r.size.height)/2, r.origin.x + (r.size.width)/2, r.origin.y + (r.size.height)/2); // Apply the transform to the context CGContextConcatCTM(context, matrix); // Signal the start of a path CGContextBeginPath(context); // Add a circle to the path. After the circle is transformed by the // context's transformation matrix, it will become an oval lying // just inside the bounding rectangle. CGContextAddArc(context, 0, 0, 1, 0, 2*pi, true); // Restore the context's state. This removes the translation and scaling but leaves // the path, since the path is not part of the graphics state. CGContextRestoreGState(context); }
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; }
AffineTransform::operator CGAffineTransform() const { return CGAffineTransformMake(narrowPrecisionToCGFloat(a()), narrowPrecisionToCGFloat(b()), narrowPrecisionToCGFloat(c()), narrowPrecisionToCGFloat(d()), narrowPrecisionToCGFloat(e()), narrowPrecisionToCGFloat(f())); }
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; }
CATransform3D CATransform3DSkew (CATransform3D t,CGFloat angleX, CGFloat angleY) { CGAffineTransform affineTransform = CGAffineTransformMake(1, tanf(-angleX*M_PI/180.0f), tanf(-angleY*M_PI/180.0f), 1, 0, 0); CATransform3D skewTransform = CATransform3DMakeAffineTransform(affineTransform); return CATransform3DConcat(t, skewTransform); }
FX_BOOL CQuartz2D::drawGraphicsString(void* graphics, void* font, FX_FLOAT fontSize, FX_WORD* glyphIndices, CGPoint* glyphPositions, FX_INT32 charsCount, FX_ARGB argb, CFX_AffineMatrix* matrix ) { if (!graphics) { return FALSE; } CGContextRef context = (CGContextRef) graphics; CGContextSetFont(context, (CGFontRef)font); CGContextSetFontSize(context, fontSize); if (matrix) { CGAffineTransform m = CGContextGetTextMatrix(context); m = CGAffineTransformConcat(m, CGAffineTransformMake(matrix->a, matrix->b, matrix->c, matrix->d, matrix->e, matrix->f)); CGContextSetTextMatrix(context, m); } 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); CGContextSaveGState(context); #if CGFLOAT_IS_DOUBLE CGPoint* glyphPositionsCG = new CGPoint[charsCount]; if (!glyphPositionsCG) { return FALSE; } for (int index = 0; index < charsCount; ++index) { glyphPositionsCG[index].x = glyphPositions[index].x; glyphPositionsCG[index].y = glyphPositions[index].y; } #else CGPoint* glyphPositionsCG = (CGPoint*)glyphPositions; #endif CGContextShowGlyphsAtPositions(context, (CGGlyph *) glyphIndices, glyphPositionsCG, charsCount); #if CGFLOAT_IS_DOUBLE delete[] glyphPositionsCG; #endif CGContextRestoreGState(context); return TRUE; }
TEST(AffineTransform, CGAffineTransformConstruction) { CGAffineTransform cgTransform = CGAffineTransformMake(6.0, 5.0, 4.0, 3.0, 2.0, 1.0); WebCore::AffineTransform test(cgTransform); testValueConstruction(test); testGetAndSet(test); ASSERT_FALSE(test.isIdentity()); }
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 cairo_int_status_t _cairo_quartz_init_glyph_path (cairo_quartz_scaled_font_t *font, cairo_scaled_glyph_t *scaled_glyph) { cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font); CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph); CGAffineTransform textMatrix; CGPathRef glyphPath; cairo_path_fixed_t *path; if (glyph == INVALID_GLYPH) { _cairo_scaled_glyph_set_path (scaled_glyph, &font->base, _cairo_path_fixed_create()); return CAIRO_STATUS_SUCCESS; } textMatrix = CGAffineTransformMake (font->base.scale.xx, -font->base.scale.yx, -font->base.scale.xy, font->base.scale.yy, font->base.scale.x0, font->base.scale.y0); textMatrix = CGAffineTransformConcat (textMatrix, CGAffineTransformMake (1.0, 0.0, 0.0, -1.0, 0.0, 0.0)); glyphPath = CGFontGetGlyphPathPtr (font_face->cgFont, &textMatrix, 0, glyph); if (!glyphPath) return CAIRO_INT_STATUS_UNSUPPORTED; path = _cairo_path_fixed_create (); if (!path) { CGPathRelease (glyphPath); return _cairo_error(CAIRO_STATUS_NO_MEMORY); } CGPathApply (glyphPath, path, _cairo_quartz_path_apply_func); CGPathRelease (glyphPath); _cairo_scaled_glyph_set_path (scaled_glyph, &font->base, path); return CAIRO_STATUS_SUCCESS; }
JNIEXPORT void JNICALL OS_NATIVE(CGAffineTransformMake) (JNIEnv *env, jclass that, jfloat arg0, jfloat arg1, jfloat arg2, jfloat arg3, jfloat arg4, jfloat arg5, jfloatArray arg6) { jfloat *lparg6=NULL; OS_NATIVE_ENTER(env, that, CGAffineTransformMake_FUNC); if (arg6) if ((lparg6 = (*env)->GetFloatArrayElements(env, arg6, NULL)) == NULL) goto fail; *(CGAffineTransform *)lparg6 = CGAffineTransformMake(arg0, arg1, arg2, arg3, arg4, arg5); fail: if (arg6 && lparg6) (*env)->ReleaseFloatArrayElements(env, arg6, lparg6, 0); OS_NATIVE_EXIT(env, that, CGAffineTransformMake_FUNC); }
//----------------------------------------------------------------------------- void CGDrawContext::init () { CGContextSaveGState (cgContext); CGContextSetShouldAntialias (cgContext, false); CGContextSetFillColorSpace (cgContext, GetCGColorSpace ()); CGContextSetStrokeColorSpace (cgContext, GetCGColorSpace ()); CGContextSaveGState (cgContext); CGAffineTransform cgCTM = CGAffineTransformMake (1.0, 0.0, 0.0, -1.0, 0.0, 0.0); CGContextSetTextMatrix (cgContext, cgCTM); CDrawContext::init (); }
TEST(AffineTransform, CoreGraphicsCasting) { WebCore::AffineTransform test(6.0, 5.0, 4.0, 3.0, 2.0, 1.0); CGAffineTransform test2 = CGAffineTransformMake(6.0, 5.0, 4.0, 3.0, 2.0, 1.0); ASSERT_TRUE(CGAffineTransformEqualToTransform(test, test2)); WebCore::AffineTransform test3; ASSERT_FALSE(CGAffineTransformEqualToTransform(test, test3)); }
void Font::drawGlyphs(GraphicsContext* graphicsContext, const FontData* font, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const { CGContextRef cgContext = graphicsContext->platformContext(); uint32_t oldFontSmoothingStyle = wkSetFontSmoothingStyle(cgContext); const FontPlatformData& platformData = font->platformData(); //NSFont* drawFont; //if ([gContext isDrawingToScreen]) { // drawFont = [platformData.font screenFont]; // if (drawFont != platformData.font) // // We are getting this in too many places (3406411); use ERROR so it only prints on debug versions for now. (We should debug this also, eventually). // LOG_ERROR("Attempting to set non-screen font (%@) when drawing to screen. Using screen font anyway, may result in incorrect metrics.", // [[[platformData.font fontDescriptor] fontAttributes] objectForKey:NSFontNameAttribute]); //} else { // drawFont = [platformData.font printerFont]; // if (drawFont != platformData.font) // NSLog(@"Attempting to set non-printer font (%@) when printing. Using printer font anyway, may result in incorrect metrics.", // [[[platformData.font fontDescriptor] fontAttributes] objectForKey:NSFontNameAttribute]); //} CGContextSetFont(cgContext, platformData.cgFont()); CGAffineTransform matrix = CGAffineTransformIdentity; matrix.b = -matrix.b; matrix.d = -matrix.d; if (platformData.syntheticOblique()) { static float skew = -tanf(syntheticObliqueAngle * acosf(0) / 90); matrix = CGAffineTransformConcat(matrix, CGAffineTransformMake(1, 0, skew, 1, 0, 0)); } // Uniscribe gives us offsets to help refine the positioning of combining glyphs. FloatSize translation = glyphBuffer.offsetAt(from); if (translation.width() || translation.height()) CGAffineTransformTranslate(matrix, translation.width(), translation.height()); CGContextSetTextMatrix(cgContext, matrix); //wkSetCGFontRenderingMode(cgContext, drawFont); CGContextSetFontSize(cgContext, platformData.size()); CGContextSetTextPosition(cgContext, point.x(), point.y()); CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs); if (font->m_syntheticBoldOffset) { CGContextSetTextPosition(cgContext, point.x() + font->m_syntheticBoldOffset, point.y()); CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs); } wkRestoreFontSmoothingStyle(cgContext, oldFontSmoothingStyle); }
static CGAffineTransform matrix_to_transform(CGContextRef cg, const SkMatrix& ctm) { SkMatrix matrix; matrix.setScale(1, -1); matrix.postTranslate(0, SkIntToScalar(CGBitmapContextGetHeight(cg))); matrix.preConcat(ctm); return CGAffineTransformMake(matrix[SkMatrix::kMScaleX], matrix[SkMatrix::kMSkewY], matrix[SkMatrix::kMSkewX], matrix[SkMatrix::kMScaleY], matrix[SkMatrix::kMTransX], matrix[SkMatrix::kMTransY]); }
void CFX_QuartzDeviceDriver::CG_SetImageTransform(int dest_left, int dest_top, int dest_width, int dest_height, CGRect* rect ) { int flip_y = _foxitDevice2User.d * dest_height < 0 ? 1 : -1; int flip_x = _foxitDevice2User.a * dest_width > 0 ? 1 : -1; if (flip_y < 0 || flip_x < 0) { if (dest_height < 0) { dest_height = -dest_height; dest_top -= dest_height; } CGRect rt = CGRectApplyAffineTransform(CGRectMake(dest_left, dest_top, dest_width, dest_height), _foxitDevice2User); CGFloat offset_x = (rt.origin.x) + rt.size.width / 2.f, offset_y = (rt.origin.y) + rt.size.height / 2.f; CGAffineTransform transform = CGAffineTransformIdentity; transform = CGAffineTransformConcat(transform, CGAffineTransformMake(1, 0, 0, 1, -offset_x, -offset_y)); transform = CGAffineTransformConcat(transform, CGAffineTransformMake(flip_x, 0, 0, flip_y, 0, 0)); transform = CGAffineTransformConcat(transform, CGAffineTransformMake(1, 0, 0, 1, offset_x, offset_y)); CGContextConcatCTM(_context, transform); if (rect) { *rect = CGRectApplyAffineTransform(*rect, transform); } } }
void CQuartz2D::setGraphicsTextMatrix(void* graphics, CFX_AffineMatrix* matrix) { if (!graphics || !matrix) { return; } CGContextRef context = (CGContextRef) graphics; CGFloat ty = CGBitmapContextGetHeight(context) - matrix->f; CGContextSetTextMatrix(context, CGAffineTransformMake(matrix->a, matrix->b, matrix->c, matrix->d, matrix->e, ty)); }
//----------------------------------------------------------------------------- void CGDrawContext::init () { CGContextSaveGState (cgContext); CGContextSetAllowsAntialiasing (cgContext, true); CGContextSetAllowsFontSmoothing (cgContext, true); CGContextSetAllowsFontSubpixelPositioning (cgContext, true); CGContextSetAllowsFontSubpixelQuantization (cgContext, true); CGContextSetShouldAntialias (cgContext, false); CGContextSetFillColorSpace (cgContext, GetCGColorSpace ()); CGContextSetStrokeColorSpace (cgContext, GetCGColorSpace ()); CGContextSaveGState (cgContext); CGAffineTransform cgCTM = CGAffineTransformMake (1.0, 0.0, 0.0, -1.0, 0.0, 0.0); CGContextSetTextMatrix (cgContext, cgCTM); CDrawContext::init (); }
static CGAffineTransform SkMatrixToCGAffineTransform(const SkMatrix& matrix) { // CGAffineTransforms don't support perspective transforms, so make sure // we don't get those. ASSERT(!matrix[SkMatrix::kMPersp0]); ASSERT(!matrix[SkMatrix::kMPersp1]); ASSERT(matrix[SkMatrix::kMPersp2] == 1.0f); return CGAffineTransformMake( matrix[SkMatrix::kMScaleX], matrix[SkMatrix::kMSkewY], matrix[SkMatrix::kMSkewX], matrix[SkMatrix::kMScaleY], matrix[SkMatrix::kMTransX], matrix[SkMatrix::kMTransY]); }
static cairo_int_status_t _cairo_quartz_init_glyph_path (cairo_quartz_scaled_font_t *font, cairo_scaled_glyph_t *scaled_glyph) { cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font); CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph); CGAffineTransform textMatrix; CGPathRef glyphPath; CTFontRef ctFont; cairo_path_fixed_t *path; if (glyph == INVALID_GLYPH) { _cairo_scaled_glyph_set_path (scaled_glyph, &font->base, _cairo_path_fixed_create()); return CAIRO_STATUS_SUCCESS; } /* scale(1,-1) * font->base.scale */ textMatrix = CGAffineTransformMake (font->base.scale.xx, font->base.scale.yx, -font->base.scale.xy, -font->base.scale.yy, 0, 0); // glyphPath = CGFontGetGlyphPathPtr (font_face->cgFont, &textMatrix, 0, glyph); ctFont = CTFontCreateWithGraphicsFont (font_face->cgFont, 0.0, NULL, NULL); glyphPath = CTFontCreatePathForGlyph (ctFont, glyph, &textMatrix); CFRelease (ctFont); if (!glyphPath) return CAIRO_INT_STATUS_UNSUPPORTED; path = _cairo_path_fixed_create (); if (!path) { CGPathRelease (glyphPath); return _cairo_error(CAIRO_STATUS_NO_MEMORY); } CGPathApply (glyphPath, path, _cairo_quartz_path_apply_func); CGPathRelease (glyphPath); _cairo_scaled_glyph_set_path (scaled_glyph, &font->base, path); return CAIRO_STATUS_SUCCESS; }
FX_BOOL CFX_QuartzDeviceDriver::SetClip_PathStroke(const CFX_PathData* pathData, const CFX_AffineMatrix* matrix, const CFX_GraphStateData* graphState ) { SaveState(); 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); FX_FLOAT lineWidth = getLineWidth(graphState, m); setStrokeInfo(graphState, 0xFF000000, lineWidth); setPathToContext(pathData); CGContextReplacePathWithStrokedPath(_context); RestoreState(FALSE); CGContextClip(_context); return TRUE; }
FX_BOOL CFX_QuartzDeviceDriver::SetClip_PathFill(const CFX_PathData* pathData, const CFX_AffineMatrix* matrix, int fillMode ) { SaveState(); 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); setPathToContext(pathData); RestoreState(FALSE); if ((fillMode & 3) == FXFILL_WINDING) { CGContextClip(_context); } else { CGContextEOClip(_context); } return TRUE; }
CFX_QuartzDeviceDriver::CFX_QuartzDeviceDriver(CGContextRef context, FX_INT32 deviceClass) { m_saveCount = 0; _context = context; _deviceClass = deviceClass; CGContextRetain(_context); CGRect r = CGContextGetClipBoundingBox(context); _width = FXSYS_round(r.size.width); _height = FXSYS_round(r.size.height); _renderCaps = FXRC_SOFT_CLIP | FXRC_BLEND_MODE | FXRC_ALPHA_PATH | FXRC_ALPHA_IMAGE | FXRC_BIT_MASK | FXRC_ALPHA_MASK; if (_deviceClass != FXDC_DISPLAY) { } else { CGImageRef image = CGBitmapContextCreateImage(_context); if (image) { _renderCaps |= FXRC_GET_BITS; _width = CGImageGetWidth(image); _height = CGImageGetHeight(image); CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(image); if (kCGImageAlphaPremultipliedFirst == alphaInfo || kCGImageAlphaPremultipliedLast == alphaInfo || kCGImageAlphaOnly == alphaInfo) { _renderCaps |= FXRC_ALPHA_OUTPUT; } } CGImageRelease(image); } CGAffineTransform ctm = CGContextGetCTM(_context); CGContextSaveGState(_context); m_saveCount++; if (ctm.d >= 0) { CGFloat offset_x, offset_y; offset_x = ctm.tx; offset_y = ctm.ty; CGContextTranslateCTM(_context, -offset_x, -offset_y); CGContextConcatCTM(_context, CGAffineTransformMake(1, 0, 0, -1, offset_x, _height + offset_y)); } _foxitDevice2User = CGAffineTransformIdentity; _user2FoxitDevice = CGAffineTransformInvert(_foxitDevice2User); }
bool GiCanvasIos::drawImage(CGImageRef image, const Box2d& rectM) { CGContextRef context = m_draw->getContext(); bool ret = false; if (context && image) { Point2d ptD = rectM.center() * m_draw->xf().modelToDisplay(); Box2d rect = rectM * m_draw->xf().modelToDisplay(); CGAffineTransform af = CGAffineTransformMake(1, 0, 0, -1, 0, m_draw->height()); af = CGAffineTransformTranslate(af, ptD.x - rect.width() * 0.5f, m_draw->height() - (ptD.y + rect.height() * 0.5f)); CGContextConcatCTM(context, af); CGContextDrawImage(context, CGRectMake(0, 0, rect.width(), rect.height()), image); CGContextConcatCTM(context, CGAffineTransformInvert(af)); ret = true; } return ret; }