bool GiCanvasIos::beginPaintBuffered(bool fast, bool autoscale) { if (m_draw->getContext() || !gs() || !m_draw->createBufferBitmap(m_draw->width(), m_draw->height(), autoscale ? m_draw->_scale : 1.f)) { return false; } RECT_2D clipBox = { 0, 0, m_draw->width(), m_draw->height() }; owner()->_beginPaint(clipBox); m_draw->_fast = fast; m_draw->_ctxused[0] = false; m_draw->_ctxused[1] = false; CGContextRef context = m_draw->getContext(); bool antiAlias = !fast && gs()->isAntiAliasMode(); CGContextSetAllowsAntialiasing(context, antiAlias); CGContextSetShouldAntialias(context, antiAlias); CGContextSetFlatness(context, fast ? 20 : 1); CGContextSetLineCap(context, kCGLineCapRound); CGContextSetLineJoin(context, kCGLineJoinRound); owner()->setMaxPenWidth(-1, 0.5f / m_draw->_scale); return true; }
bool GiCanvasIos::beginPaint(CGContextRef context, bool fast, bool buffered) { if (m_draw->getContext() || !context) return false; if (gs()) { CGRect rc = CGContextGetClipBoundingBox(context); RECT_2D clipBox = { rc.origin.x, rc.origin.y, rc.origin.x + rc.size.width, rc.origin.y + rc.size.height }; owner()->_beginPaint(clipBox); } m_draw->_context = context; m_draw->_fast = fast; m_draw->_ctxused[0] = false; m_draw->_ctxused[1] = false; if (buffered && gs()) { m_draw->createBufferBitmap(m_draw->width(), m_draw->height(), m_draw->_scale); context = m_draw->getContext(); } bool antiAlias = !fast && (!gs() || gs()->isAntiAliasMode()); CGContextSetAllowsAntialiasing(context, antiAlias); CGContextSetShouldAntialias(context, antiAlias); CGContextSetFlatness(context, fast ? 20 : 1); CGContextSetLineCap(context, kCGLineCapRound); CGContextSetLineJoin(context, kCGLineJoinRound); if (owner()) // 设置最小线宽为0.5像素,使用屏幕放大倍数以便得到实际像素值 owner()->setMaxPenWidth(-1, 0.5f / m_draw->_scale); return true; }
static void quartzPrepareLine (GraphicsScreen me) { CGContextSetLineJoin (my d_macGraphicsContext, kCGLineJoinRound); if (my duringXor) { CGContextSetBlendMode (my d_macGraphicsContext, kCGBlendModeDifference); CGContextSetAllowsAntialiasing (my d_macGraphicsContext, false); CGContextSetRGBStrokeColor (my d_macGraphicsContext, 1.0, 1.0, 1.0, 1.0); } else { CGContextSetRGBStrokeColor (my d_macGraphicsContext, my d_macColour.red / 65536.0, my d_macColour.green / 65536.0, my d_macColour.blue / 65536.0, 1.0); } double lineWidth_pixels = LINE_WIDTH_IN_PIXELS (me); CGContextSetLineWidth (my d_macGraphicsContext, lineWidth_pixels); CGFloat lengths [4]; if (my lineType == Graphics_DOTTED) lengths [0] = my resolution > 192 ? my resolution / 100.0 : 2, lengths [1] = my resolution > 192 ? my resolution / 75.0 + lineWidth_pixels : 2; if (my lineType == Graphics_DASHED) lengths [0] = my resolution > 192 ? my resolution / 25 : 6, lengths [1] = my resolution > 192 ? my resolution / 50.0 + lineWidth_pixels : 2; if (my lineType == Graphics_DASHED_DOTTED) lengths [0] = my resolution > 192 ? my resolution / 25 : 6, lengths [1] = my resolution > 192 ? my resolution / 50.0 + lineWidth_pixels : 2; lengths [2] = my resolution > 192 ? my resolution / 100.0 : 2; lengths [3] = my resolution > 192 ? my resolution / 50.0 + lineWidth_pixels : 2; CGContextSetLineDash (my d_macGraphicsContext, 0.0, my lineType == Graphics_DRAWN ? NULL : lengths, my lineType == 0 ? 0 : my lineType == Graphics_DASHED_DOTTED ? 4 : 2); }
void GiCanvasIos::_antiAliasModeChanged(bool antiAlias) { if (m_draw->getContext()) { antiAlias = !m_draw->_fast && antiAlias; CGContextSetAllowsAntialiasing(m_draw->getContext(), antiAlias); CGContextSetShouldAntialias(m_draw->getContext(), antiAlias); } }
//----------------------------------------------------------------------------- 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 void quartzRevertLine (GraphicsScreen me) { if (my duringXor) { CGContextSetBlendMode (my d_macGraphicsContext, kCGBlendModeNormal); CGContextSetAllowsAntialiasing (my d_macGraphicsContext, true); } }
Memsubfont* mksubfont(XFont *f, char *name, int lo, int hi, int size, int antialias) { CFStringRef s; CGColorSpaceRef color; CGContextRef ctxt; CTFontRef font; CTFontDescriptorRef desc; CGRect bbox; Memimage *m, *mc, *m1; int x, y, y0; int i, height, ascent; Fontchar *fc, *fc0; Memsubfont *sf; CGFloat whitef[] = { 1.0, 1.0 }; CGColorRef white; s = c2mac(name); desc = CTFontDescriptorCreateWithNameAndSize(s, size); CFRelease(s); if(desc == nil) return nil; font = CTFontCreateWithFontDescriptor(desc, 0, nil); CFRelease(desc); if(font == nil) return nil; bbox = CTFontGetBoundingBox(font); x = (int)(bbox.size.width*2 + 0.99999999); fontheight(f, size, &height, &ascent); y = height; y0 = height - ascent; m = allocmemimage(Rect(0, 0, x*(hi+1-lo)+1, y+1), GREY8); if(m == nil) return nil; mc = allocmemimage(Rect(0, 0, x+1, y+1), GREY8); if(mc == nil){ freememimage(m); return nil; } memfillcolor(m, DBlack); memfillcolor(mc, DBlack); fc = malloc((hi+2 - lo) * sizeof fc[0]); sf = malloc(sizeof *sf); if(fc == nil || sf == nil) { freememimage(m); freememimage(mc); free(fc); free(sf); return nil; } fc0 = fc; color = CGColorSpaceCreateWithName(kCGColorSpaceGenericGray); ctxt = CGBitmapContextCreate(byteaddr(mc, mc->r.min), Dx(mc->r), Dy(mc->r), 8, mc->width*sizeof(u32int), color, kCGImageAlphaNone); white = CGColorCreate(color, whitef); CGColorSpaceRelease(color); if(ctxt == nil) { freememimage(m); freememimage(mc); free(fc); free(sf); return nil; } CGContextSetAllowsAntialiasing(ctxt, antialias); CGContextSetTextPosition(ctxt, 0, 0); // XXX #if OSX_VERSION >= 101400 CGContextSetAllowsFontSmoothing(ctxt, false); #endif x = 0; for(i=lo; i<=hi; i++, fc++) { char buf[20]; CFStringRef str; CFDictionaryRef attrs; CFAttributedStringRef attrString; CTLineRef line; CGRect r; CGPoint p1; CFStringRef keys[] = { kCTFontAttributeName, kCTForegroundColorAttributeName }; CFTypeRef values[] = { font, white }; sprint(buf, "%C", (Rune)mapUnicode(name, i)); str = c2mac(buf); // See https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/CoreText_Programming/LayoutOperations/LayoutOperations.html#//apple_ref/doc/uid/TP40005533-CH12-SW2 attrs = CFDictionaryCreate(kCFAllocatorDefault, (const void**)&keys, (const void**)&values, sizeof(keys) / sizeof(keys[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); attrString = CFAttributedStringCreate(kCFAllocatorDefault, str, attrs); CFRelease(str); CFRelease(attrs); line = CTLineCreateWithAttributedString(attrString); CGContextSetTextPosition(ctxt, 0, y0); r = CTLineGetImageBounds(line, ctxt); memfillcolor(mc, DBlack); CTLineDraw(line, ctxt); CFRelease(line); fc->x = x; fc->top = 0; fc->bottom = Dy(m->r); // fprint(2, "printed %#x: %g %g\n", mapUnicode(i), p1.x, p1.y); p1 = CGContextGetTextPosition(ctxt); if(p1.x <= 0 || mapUnicode(name, i) == 0xfffd) { fc->width = 0; fc->left = 0; if(i == 0) { drawpjw(m, fc, x, (int)(bbox.size.width + 0.99999999), y, y - y0); x += fc->width; } continue; } memimagedraw(m, Rect(x, 0, x + p1.x, y), mc, ZP, memopaque, ZP, S); fc->width = p1.x; fc->left = 0; x += p1.x; } fc->x = x; // round up to 32-bit boundary // so that in-memory data is same // layout as in-file data. if(x == 0) x = 1; if(y == 0) y = 1; if(antialias) x += -x & 3; else x += -x & 31; m1 = allocmemimage(Rect(0, 0, x, y), antialias ? GREY8 : GREY1); memimagedraw(m1, m1->r, m, m->r.min, memopaque, ZP, S); freememimage(m); freememimage(mc); sf->name = nil; sf->n = hi+1 - lo; sf->height = Dy(m1->r); sf->ascent = Dy(m1->r) - y0; sf->info = fc0; sf->bits = m1; return sf; }