Exemple #1
0
void TileGrid::drawTileMapContents(CGContextRef context, CGRect layerBounds) const
{
    CGContextSetRGBFillColor(context, 0.3, 0.3, 0.3, 1);
    CGContextFillRect(context, layerBounds);

    CGFloat scaleFactor = layerBounds.size.width / m_controller.bounds().width();

    CGFloat contextScale = scaleFactor / m_scale;
    CGContextScaleCTM(context, contextScale, contextScale);

    for (TileMap::const_iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
        const TileInfo& tileInfo = it->value;
        PlatformCALayer* tileLayer = tileInfo.layer.get();

        CGFloat red = 1;
        CGFloat green = 1;
        CGFloat blue = 1;
        CGFloat alpha = 1;
        if (tileInfo.hasStaleContent) {
            red = 0.25;
            green = 0.125;
            blue = 0;
        } else if (m_controller.shouldAggressivelyRetainTiles() && tileInfo.cohort != VisibleTileCohort) {
            red = 0.8;
            green = 0.8;
            blue = 0.8;
        }

        TileCohort newestCohort = newestTileCohort();
        TileCohort oldestCohort = oldestTileCohort();

        if (!m_controller.shouldAggressivelyRetainTiles() && tileInfo.cohort != VisibleTileCohort && newestCohort > oldestCohort)
            alpha = 1 - (static_cast<float>((newestCohort - tileInfo.cohort)) / (newestCohort - oldestCohort));

        CGContextSetRGBFillColor(context, red, green, blue, alpha);

        if (tileLayer->superlayer()) {
            CGContextSetLineWidth(context, 0.5 / contextScale);
            CGContextSetRGBStrokeColor(context, 0, 0, 0, 1);
        } else {
            CGContextSetLineWidth(context, 1 / contextScale);
            CGContextSetRGBStrokeColor(context, 0.2, 0.1, 0.9, 1);
        }

        CGRect frame = CGRectMake(tileLayer->position().x(), tileLayer->position().y(), tileLayer->bounds().size().width(), tileLayer->bounds().size().height());
        CGContextFillRect(context, frame);
        CGContextStrokeRect(context, frame);

        CGContextSetRGBFillColor(context, 0, 0, 0, 0.5);

        String repaintCount = String::number(m_tileRepaintCounts.get(tileLayer));

        CGContextSaveGState(context);

        tileLayer->drawTextAtPoint(context, frame.origin.x + 64, frame.origin.y + 192, CGSizeMake(3, -3), 58,
                                   repaintCount.ascii().data(), repaintCount.length());

        CGContextRestoreGState(context);
    }
}
void JBGStrokePathByLines(CGContextRef ctx, CGPathRef path, CGColorRef color_1, CGFloat width_1, CGColorRef color_2, CGFloat width_2, CGColorRef color_3, CGFloat width_3)
{
    if (width_1 > 0.0f)
    {
        CGContextSetLineWidth(ctx, width_1);
        CGContextAddPath(ctx, path);
        CGContextSetStrokeColorWithColor(ctx, color_1);
        CGContextStrokePath(ctx);
    }

    if (width_2 > 0.0f)
    {
        CGContextAddPath(ctx, path);
        CGContextSetStrokeColorWithColor(ctx, color_2);
        CGContextSetLineWidth(ctx, width_2);
        CGContextStrokePath(ctx);
    }
    
    if (width_3 > 0.0f)
    {
        CGContextAddPath(ctx, path);
        CGContextSetStrokeColorWithColor(ctx, color_3);
        CGContextSetLineWidth(ctx, width_3);
        CGContextStrokePath(ctx);
    }
}
void MacVegaPrinterListener::DrawEllipse(const OpRect& rect, UINT32 width)
{
	CGRect cgrect = CGRectMake(rect.x, rect.y, rect.width, rect.height);
	cgrect.origin.y = m_winHeight - cgrect.origin.y - cgrect.size.height;

	float cx = cgrect.origin.x + (cgrect.size.width / 2);
	float cy = cgrect.origin.y + (cgrect.size.height / 2);
	float radius = cgrect.size.width / 2;

	if(width != 1)
	{
		CGContextSetLineWidth(m_ctx, width);
	}
	if(cgrect.size.width != cgrect.size.height)
	{
		cy = cy * cgrect.size.width / cgrect.size.height;
		CGContextScaleCTM(m_ctx, 1.0, cgrect.size.height/cgrect.size.width);
	}

	CGContextAddArc(m_ctx, cx, cy, radius, 0, 2*M_PI, 0);

	CGContextStrokePath(m_ctx);

	if(width != 1)
	{
		CGContextSetLineWidth(m_ctx, 1);
	}
	if(cgrect.size.width != cgrect.size.height)
	{
		CGContextScaleCTM(m_ctx, 1.0, cgrect.size.width/cgrect.size.height);
	}
}
void MacVegaPrinterListener::DrawRect(const OpRect& rect, UINT32 width)
{
	if(width != 1)
	{
		CGContextSetLineWidth(m_ctx, width);
	}
	CGContextStrokeRect(m_ctx, CGRectMake(rect.x, m_winHeight-(rect.y+rect.height), rect.width, rect.height));
	if(width != 1)
	{
		CGContextSetLineWidth(m_ctx, 1);
	}
}
Exemple #5
0
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);
}
static void quartzgen_path(GVJ_t *job, int filled)
{
	CGContextRef context = (CGContextRef)job->context;
	
	/* set up colors */
	if (filled)
		CGContextSetRGBFillColor(context, job->obj->fillcolor.u.RGBA [0], job->obj->fillcolor.u.RGBA [1], job->obj->fillcolor.u.RGBA [2], job->obj->fillcolor.u.RGBA [3]);
	CGContextSetRGBStrokeColor(context, job->obj->pencolor.u.RGBA [0], job->obj->pencolor.u.RGBA [1], job->obj->pencolor.u.RGBA [2], job->obj->pencolor.u.RGBA [3]);
	
	/* set up line style */
	const CGFloat *segments;
	size_t segment_count;
	switch (job->obj->pen) {
	case PEN_DASHED:
		segments = dashed;
		segment_count = sizeof(dashed)/sizeof(CGFloat);
		break;
	case PEN_DOTTED:
		segments = dotted;
		segment_count = sizeof(dotted)/sizeof(CGFloat);
		break;
	default:
		segments = NULL;
		segment_count = 0;
		break;
	}
	CGContextSetLineDash(context, 0.0, segments, segment_count);

	/* set up line width */
	CGContextSetLineWidth(context, job->obj->penwidth); // *job->scale.x);
	
	/* draw the path */
	CGContextDrawPath(context, filled ? kCGPathFillStroke : kCGPathStroke);
}
Exemple #7
0
void map_pos_rectangle(MapGC *mgc, MapSettings *settings,
		       int x, int y, int width, int height)
{
  if (FALSE);
#ifdef HAVE_CAIRO
  else if (mgc->cairo_cr)
    {
      cairo_set_source_rgb(mgc->cairo_cr, 0, 0, 1);
      cairo_set_line_width(mgc->cairo_cr, 4);
      cairo_rectangle(mgc->cairo_cr, x, y, width, height);
      cairo_stroke(mgc->cairo_cr);
    }
#endif
#ifdef HAVE_GTK
  else if (mgc->gtk_drawable)
    {
      gdk_gc_set_foreground(mgc->gtk_gc, &settings->blue);
      gdk_gc_set_line_attributes(mgc->gtk_gc, 4, 0, 0, 0);
      gdk_draw_rectangle(mgc->gtk_drawable, mgc->gtk_gc, FALSE,
			 x, y, width, height);
    }
#endif
#ifdef HAVE_QT
  else if (mgc->qt_painter)
    {
      qt_pos_rectangle(mgc->qt_painter, settings,
		       x, y, width, height);
    }
#endif
#ifdef HAVE_QUARTZ
  else if (mgc->quartz_gc)
    {
      CGContextSetRGBStrokeColor(mgc->quartz_gc, 0, 0, 1.0, 1.0);
      CGContextSetLineWidth(mgc->quartz_gc, 4.0);
      //gdk_gc_set_line_attributes(mgc->gtk_gc, 4, 0, 0, 0);
      //gdk_draw_rectangle(mgc->gtk_drawable, mgc->gtk_gc, FALSE,
      //		 x, y, width, height);
    }
#endif
#ifdef WIN32
  else if (mgc->win_dc)
    {
	POINT	p[5];

	p[0].x = x;
	p[0].y = y;
	p[1].x = x + width;
	p[1].y = y;
	p[2].x = x + width;
	p[2].y = y + height;
	p[3].x = x;
	p[3].y = y + height;
	p[4].x = x;
	p[4].y = y;

        win32_setpen(mgc, 4, RGB(0x0, 0x0, 0xff));
	Polyline(mgc->win_dc, p, 5);
    }
#endif
}
void doStrokeWithCTM(CGContextRef context)
{
	CGContextTranslateCTM(context, 150., 180.);
	CGContextSetLineWidth(context, 10);
	// Draw ellipse 1 with a uniform stroke.
	CGContextSaveGState(context);
		// Scale the CTM so the circular arc will be elliptical.
		CGContextScaleCTM(context, 2, 1);
		CGContextBeginPath(context);
		// Create an arc that is a circle.
		CGContextAddArc(context, 0., 0., 45., 0., 2*M_PI, 0);
	// Restore the context parameters prior to stroking the path.
	// CGContextRestoreGState does not affect the path in the context.
	CGContextRestoreGState(context);
	CGContextStrokePath(context);
	
	// *** was 0, -120
	CGContextTranslateCTM(context, 220., 0.);
	// Draw ellipse 2 with non-uniform stroke.
	CGContextSaveGState(context);
		// Scale the CTM so the circular arc will be elliptical.
		CGContextScaleCTM(context, 2, 1);
		CGContextBeginPath(context);
		// Create an arc that is a circle.
		CGContextAddArc(context, 0., 0., 45., 0., 2*M_PI, 0);
		// Stroke the path with the scaled coordinate system in effect.
		CGContextStrokePath(context);
	CGContextRestoreGState(context);
}
Exemple #9
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);
}
Exemple #10
0
//-----------------------------------------------------------------------------
void CGDrawContext::setLineWidth (CCoord width)
{
	if (currentState.frameWidth == width)
		return;

	CGContextSetLineWidth (cgContext, width);

	CDrawContext::setLineWidth (width);
}
Exemple #11
0
//-----------------------------------------------------------------------------
void CGDrawContext::setLineWidth (CCoord width)
{
    if (currentState.frameWidth == width)
        return;

    CGContextSetLineWidth (cgContext, static_cast<CGFloat> (width));

    CDrawContext::setLineWidth (width);
}
void doRoundedRects(CGContextRef context)
{
	CGRect rect = {{10., 10.}, {210., 150.}};
	float ovalWidth = 100., ovalHeight = 100.;
	CGContextSetLineWidth(context, 2.);
	CGContextBeginPath(context);
	addRoundedRectToPath(context, rect, ovalWidth, ovalHeight);
	CGContextSetRGBStrokeColor(context, 1., 0., 0., 1.);
	CGContextDrawPath(context, kCGPathStroke);
}
void MacVegaPrinterListener::DrawLine(const OpPoint& from, const OpPoint& to, UINT32 width)
{
	if(width != 1)
	{
		CGContextSetLineWidth(m_ctx, width);
	}

	CGContextBeginPath(m_ctx);

	CGContextMoveToPoint(m_ctx, from.x, m_winHeight - from.y);
	CGContextAddLineToPoint(m_ctx, to.x, m_winHeight - to.y);

	CGContextStrokePath(m_ctx);

	if(width != 1)
	{
		CGContextSetLineWidth(m_ctx, 1);
	}
}
void doIndexedColorDrawGraphics(CGContextRef context)
{
	CGColorSpaceRef theBaseRGBSpace = getTheCalibratedRGBColorSpace();
	CGColorSpaceRef theIndexedSpace = NULL;
	unsigned char lookupTable[6];
	float opaqueRed[] = { 0, 1 }; // index, alpha
	float aBlue[] = { 1, 1 };   // index, alpha
	
	// Set the first 3 values in the lookup table to a red of
	// 169/255 = 0.663, no green, and blue = 8/255 = 0.031. This makes  
	// the first entry in the lookup table a shade of red.
	lookupTable[0] = 169; lookupTable[1] = 0; lookupTable[2] = 8;
	
	// Set the second 3 values in the lookup table to a red value
	// of 123/255 = 0.482, a green value of 158/255 = 0.62, and
	// a blue value of 222/255 = 0.871. This makes the second entry
	// in the lookup table a shade of blue.
	lookupTable[3] = 123; lookupTable[4] = 158; lookupTable[5] = 222;
	
	// Create the indexed color space with this color lookup table,
	// using the RGB color space as the base color space and a 2 element
	// color lookup table to characterize the indexed color space.
	theIndexedSpace = CGColorSpaceCreateIndexed(theBaseRGBSpace, 1, lookupTable);
	if(theIndexedSpace != NULL){
	    CGContextSetStrokeColorSpace(context, theIndexedSpace);
	    CGContextSetFillColorSpace(context, theIndexedSpace);
	    // Release the color space this code created since it is no
		// longer needed in this routine.
	    CGColorSpaceRelease(theIndexedSpace);

	    // Set the stroke color to an opaque blue.
	    CGContextSetStrokeColor(context, aBlue);
	    // Set the fill color to an opaque red.
	    CGContextSetFillColor(context, opaqueRed);

	    CGContextSetLineWidth(context, 8.);
	 	// Draw the first rectangle.
	    CGContextBeginPath(context);
	    CGContextAddRect(context, CGRectMake(20., 20., 100., 100.));
	    CGContextDrawPath(context, kCGPathFillStroke);

	    // Continue to use the stroke colorspace already set
	    // but change the stroke alpha value to a semitransparent value
	    // while leaving the index value unchanged.
	    aBlue[1] = 0.5;
	    CGContextSetStrokeColor(context, aBlue);
	    // Draw another rectangle to the right of the first one.
	    CGContextBeginPath(context);
	    CGContextAddRect(context, CGRectMake(140., 20., 100., 100.));
	    CGContextDrawPath(context, kCGPathFillStroke);
	}else
	    fprintf(stderr, "Couldn't make the indexed color space!\n");
}
Exemple #15
0
    bool setPen(const GiContext* ctx)
    {
        bool changed = !_ctxused[0];
        
        if (ctx && !ctx->isNullLine())
        {
            if (_gictx.getLineColor() != ctx->getLineColor()) {
                _gictx.setLineColor(ctx->getLineColor());
                changed = true;
            }
            if (_gictx.getLineWidth() != ctx->getLineWidth()) {
                _gictx.setLineWidth(ctx->getLineWidth(), ctx->isAutoScale());
                changed = true;
            }
            if (_gictx.getLineStyle() != ctx->getLineStyle()) {
                _gictx.setLineStyle(ctx->getLineStyle());
                changed = true;
            }
        }
        
        if (!ctx) ctx = &_gictx;
        if (!ctx->isNullLine() && changed)
        {
            _ctxused[0] = true;
            
            GiColor color = ctx->getLineColor();
            if (gs())
                color = gs()->calcPenColor(color);
            CGContextSetRGBStrokeColor(getContext(), 
                                       toFloat(color.r), toFloat(color.g),
                                       toFloat(color.b), toFloat(color.a));
            
            float w = ctx->getLineWidth();
            w = gs() ? gs()->calcPenWidth(w, ctx->isAutoScale()) : (w < 0 ? -w : 1);
            CGContextSetLineWidth(getContext(), _fast && w > 1 ? w - 1 : w); // 不是反走样就细一点
            
            int style = ctx->getLineStyle();
            CGFloat pattern[6];
            
            if (style >= 0 && style < sizeof(lpats)/sizeof(lpats[0])) {
                if (lpats[style].arr && !_fast) {                           // 快速画时不要线型
                    makeLinePattern(pattern, lpats[style].arr, lpats[style].n, w);
                    CGContextSetLineDash(getContext(), 0, pattern, lpats[style].n);
                }
                else {
                    CGContextSetLineDash(getContext(), 0, NULL, 0);
                }
                CGContextSetLineCap(getContext(), style > 0 ? kCGLineCapButt : kCGLineCapRound);
            }
        }

        return !ctx->isNullLine();
    }
Exemple #16
0
static void Quartz_SetLineWidth(double lwd, NewDevDesc *dd)
{
 	QuartzDesc *xd = (QuartzDesc*)dd->deviceSpecific;

	if(lwd < 1)
	 lwd=1;

 	xd->lineWidth = lwd;


    CGContextSetLineWidth( GetContext(xd), lwd );

}
Exemple #17
0
void PlatformCALayer::drawRepaintIndicator(CGContextRef context, PlatformCALayer* platformCALayer, int repaintCount, CGColorRef customBackgroundColor)
{
    char text[16]; // that's a lot of repaints
    snprintf(text, sizeof(text), "%d", repaintCount);
    
    FloatRect indicatorBox = platformCALayer->bounds();\
    indicatorBox.setLocation( { 1, 1 } );
    indicatorBox.setSize(FloatSize(12 + 10 * strlen(text), 27));

    CGContextStateSaver stateSaver(context);
    
    CGContextSetAlpha(context, 0.5f);
    CGContextBeginTransparencyLayerWithRect(context, indicatorBox, 0);
    
    if (customBackgroundColor)
        CGContextSetFillColorWithColor(context, customBackgroundColor);
    else
        CGContextSetRGBFillColor(context, 0, 0.5f, 0.25f, 1);
    
    if (platformCALayer->isOpaque())
        CGContextFillRect(context, indicatorBox);
    else {
        Path boundsPath;
        boundsPath.moveTo(indicatorBox.maxXMinYCorner());
        boundsPath.addLineTo(indicatorBox.maxXMaxYCorner());
        boundsPath.addLineTo(indicatorBox.minXMaxYCorner());

        const float cornerChunk = 8;
        boundsPath.addLineTo(FloatPoint(indicatorBox.x(), indicatorBox.y() + cornerChunk));
        boundsPath.addLineTo(FloatPoint(indicatorBox.x() + cornerChunk, indicatorBox.y()));
        boundsPath.closeSubpath();

        CGContextAddPath(context, boundsPath.platformPath());
        CGContextFillPath(context);
    }

    if (platformCALayer->owner()->isUsingDisplayListDrawing(platformCALayer)) {
        CGContextSetRGBStrokeColor(context, 0, 0, 0, 0.65);
        CGContextSetLineWidth(context, 2);
        CGContextStrokeRect(context, indicatorBox);
    }

    if (platformCALayer->acceleratesDrawing())
        CGContextSetRGBFillColor(context, 1, 0, 0, 1);
    else
        CGContextSetRGBFillColor(context, 1, 1, 1, 1);
    
    platformCALayer->drawTextAtPoint(context, indicatorBox.x() + 5, indicatorBox.y() + 22, CGSizeMake(1, -1), 22, text, strlen(text));
    
    CGContextEndTransparencyLayer(context);
}
DISABLED_DRAW_TEST_F(CGContext, Shadow, WhiteBackgroundTest) {
    CGContextRef context = GetDrawingContext();
    CGRect bounds = GetDrawingBounds();

    CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0);
    CGContextSetLineWidth(context, 5);

    CGContextSetShadow(context, CGSize{ 10.f, 10.f }, 1.0);

    CGPoint center = _CGRectGetCenter(bounds);
    CGRect rect = _CGRectCenteredOnPoint({ 150, 150 }, center);

    CGContextStrokeRect(context, rect);
}
void doEgg(CGContextRef context)
{
	CGPoint p0 = {0., 0.}, p1 = {0., 200.};
	CGPoint c1 = {140., 5.}, c2 = {80., 198.};
	CGContextTranslateCTM(context, 100., 5.);
	CGContextBeginPath(context);
	
	CGContextMoveToPoint(context, p0.x, p0.y);
	// Create the BŽzier path segment for the right side of the egg.
	CGContextAddCurveToPoint(context, c1.x, c1.y, c2.x, c2.y, p1.x, p1.y);
	// Create the BŽzier path segment for the left side of the egg.
	CGContextAddCurveToPoint(context, -c2.x, c2.y, -c1.x, c1.y, p0.x, p0.y);
	CGContextClosePath(context);
	CGContextSetLineWidth(context, 2);
	CGContextDrawPath(context, kCGPathStroke);
}
void GraphicsContext::drawLineForText(const IntPoint& point, int width, bool printing)
{
    if (paintingDisabled())
        return;
    
    // Note: This function assumes that point.x and point.y are integers (and that's currently always the case).
    float x = point.x();
    float y = point.y();

    float thickness = strokeThickness();
    if (printing) {
        // When printing, use a minimum thickness of 0.5 in user space.
        // See bugzilla bug 4255 for details of why 0.5 is the right minimum thickness to use while printing.
        if (thickness < 0.5)
            thickness = 0.5;

        // When printing, use antialiasing instead of putting things on integral pixel boundaries.
    } else {
        // On screen, use a minimum thickness of 1.0 in user space (later rounded to an integral number in device space).
        if (thickness < 1)
            thickness = 1;

        // On screen, round all parameters to integer boundaries in device space.
        CGRect lineRect = roundToDevicePixels(FloatRect(x, y, width, thickness));
        x = lineRect.origin.x;
        y = lineRect.origin.y;
        width = (int)(lineRect.size.width);
        thickness = lineRect.size.height;
    }

    // FIXME: How about using a rectangle fill instead of drawing a line?
    CGContextSaveGState(platformContext());
    
    CGContextSetLineWidth(platformContext(), thickness);
    CGContextSetShouldAntialias(platformContext(), printing);

    float halfThickness = thickness / 2;

    CGPoint linePoints[2];
    linePoints[0].x = x + halfThickness;
    linePoints[0].y = y + halfThickness;
    linePoints[1].x = x + width - halfThickness;
    linePoints[1].y = y + halfThickness;
    CGContextStrokeLineSegments(platformContext(), linePoints, 2);

    CGContextRestoreGState(platformContext());
}
void doPixelAlignedFillAndStroke(CGContextRef context)
{
    CGPoint p1 = CGPointMake(16.7, 17.8);
    CGPoint p2 = CGPointMake(116.7, 17.8);
    CGRect r = CGRectMake(16.7, 20.8, 100.6, 100.6);
    CGSize s;
    
    CGContextSetLineWidth(context, 2);
    CGContextSetRGBFillColor(context, 1., 0., 0., 1.);
    CGContextSetRGBStrokeColor(context, 1., 0., 0., 1.);
    
    // Unaligned drawing.
    CGContextBeginPath(context);
    CGContextMoveToPoint(context, p1.x, p1.y);
    CGContextAddLineToPoint(context, p2.x, p2.y);
    CGContextStrokePath(context);
    CGContextFillRect(context, r);
    
    // Translate to the right before drawing along
    // aligned coordinates.
    CGContextTranslateCTM(context, 106, 0);
    
    // Aligned drawing.
    
    // Compute the length of the line in user space.
    s = CGSizeMake(p2.x - p1.x, p2.y - p1.y);
    
    CGContextBeginPath(context);
    // Align the starting point to a device
    // pixel boundary.
    p1 = alignPointToUserSpace(context, p1);
    // Establish the starting point of the line.
    CGContextMoveToPoint(context, p1.x, p1.y);
    // Compute the line length as an integer
    // number of device pixels.
    s = alignSizeToUserSpace(context, s);
    CGContextAddLineToPoint(context, 
				p1.x + s.width, 
				p1.y + s.height);
    CGContextStrokePath(context);
    // Compute a rect that is aligned to device
    // space with a width that is an integer
    // number of device pixels.
    r = alignRectToUserSpace(context, r);
    CGContextFillRect(context, r);
}
void drawWithColorRefs(CGContextRef context)
{
	static CGColorRef opaqueRedColor = NULL, opaqueBlueColor = NULL, transparentBlueColor = NULL;

	// Initialize the CGColorRefs if necessary
	if(opaqueRedColor == NULL){
		// Initialize the color array to an opaque red 
		// in the generic calibrated RGB color space.
		float color[4] = { 0.663, 0.0, 0.031, 1.0 };
		CGColorSpaceRef theColorSpace = getTheCalibratedRGBColorSpace();
		// Create a CGColorRef for opaque red.
		opaqueRedColor = CGColorCreate(theColorSpace, color);
		// Make the color array correspond to an opaque blue color.
		color[0] = 0.482; color[1] = 0.62; color[2] = 0.871;
		// Create another CGColorRef for opaque blue.
		opaqueBlueColor = CGColorCreate(theColorSpace, color);
		// Create a new CGColorRef from the opaqueBlue CGColorRef 
		// but with a different alpha value.
		transparentBlueColor = CGColorCreateCopyWithAlpha(opaqueBlueColor, 0.5);
		if(!(opaqueRedColor && opaqueBlueColor && transparentBlueColor)){
		    fprintf(stderr, "Couldn't create one of the CGColorRefs!!!\n");
		    return;
		}
	}

	// Set the fill color to the opaque red CGColor object.
	CGContextSetFillColorWithColor(context, opaqueRedColor);
	// Set the stroke color to the opaque blue CGColor object.
	CGContextSetStrokeColorWithColor(context, opaqueBlueColor);
	
	CGContextSetLineWidth(context, 8.);
	// Draw the first rectangle.
	CGContextBeginPath(context);
	CGContextAddRect(context, CGRectMake(20., 20., 100., 100.));
	CGContextDrawPath(context, kCGPathFillStroke);
    
	// Set the stroke color to be that of the transparent blue 
	// CGColor object.
	CGContextSetStrokeColorWithColor(context, transparentBlueColor);	
	// Draw a second rectangle to the right of the first one.
	CGContextBeginPath(context);
 	CGContextAddRect(context, CGRectMake(140., 20., 100., 100.));
	CGContextDrawPath(context, kCGPathFillStroke);
}
DISABLED_DRAW_TEST_F(CGContext, ShadowWithRotatedCTM, WhiteBackgroundTest) {
    CGContextRef context = GetDrawingContext();
    CGRect bounds = GetDrawingBounds();

    CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0);
    CGContextSetLineWidth(context, 5);

    CGContextSetShadow(context, CGSize{ 10.f, 10.f }, 1.0);

    CGPoint center = _CGRectGetCenter(bounds);
    CGRect rect = _CGRectCenteredOnPoint({ 150, 150 }, center);
    CGPoint rectCenter = _CGRectGetCenter(rect);

    CGContextTranslateCTM(context, rectCenter.x, rectCenter.y);
    CGContextRotateCTM(context, 15.f * M_PI / 180.f);
    CGContextTranslateCTM(context, -rectCenter.x, -rectCenter.y);

    CGContextStrokeRect(context, rect);
}
void doColorSpaceFillAndStroke(CGContextRef context)
{
	CGColorSpaceRef theColorSpace = getTheCalibratedRGBColorSpace();
	float opaqueRed[] = { 0.663, 0.0, 0.031, 1.0 }; // red,green,blue,alpha
	float aBlue[] = { 0.482, 0.62, 0.871, 1.0 };	// red,green,blue,alpha
	
	// Set the fill color space to be the generic calibrated RGB color space.
	CGContextSetFillColorSpace(context, theColorSpace);
	// Set the fill color to opaque red. The number of elements in the
	// array passed to this function must be the number of color
	// components in the current fill color space plus 1 for alpha.
	CGContextSetFillColor(context, opaqueRed);
	
	// Set the stroke color space to be the generic calibrated RGB color space.
	CGContextSetStrokeColorSpace(context, theColorSpace);
	// Set the stroke color to opaque blue. The number of elements
	// in the array passed to this function must be the number of color
	// components in the current stroke color space plus 1 for alpha.
	CGContextSetStrokeColor(context, aBlue);
	
	CGContextSetLineWidth(context, 8.);
 	// Rectangle 1.
	CGContextBeginPath(context);
	CGContextAddRect(context, CGRectMake(20., 20., 100., 100.));
	CGContextDrawPath(context, kCGPathFillStroke);
    
	// Continue to use the stroke colorspace already set
	// but change the stroke alpha value to a semitransparent blue.
	aBlue[3] = 0.5;
	CGContextSetStrokeColor(context, aBlue);
 	// Rectangle 2.
	CGContextBeginPath(context);
	CGContextAddRect(context, CGRectMake(140., 20., 100., 100.));
	CGContextDrawPath(context, kCGPathFillStroke);
    
	// Don't release the color space since this routine 
	// didn't create it.
}
Exemple #25
0
void GraphicsContext::setPlatformStrokeThickness(float thickness)
{
    if (paintingDisabled())
        return;
    CGContextSetLineWidth(platformContext(), thickness);
}
void RSTileRendererDrawTile(
                 CGContextRef c,
                 CGRect bounds,
                 uint8_t *data,
                 uint32_t dataSize,
                 uint32_t zoom,
                 RSTileRendererGraphicsSpace graphicsSpace)
{
    CGFloat width = (CGFloat)bounds.size.width;
    CGFloat height = (CGFloat)bounds.size.height;
    
    const CGFloat backgroundColor[4] = {0.5, 0.5, 0.5, 1};
    const CGFloat fillColors[8][4] = {
        {0, 0, 0, 0},
        {(210 / 255.0), (173 / 255.0), (104 / 255.0), 1}, // Building = 1,
        {(66 / 255.0), (66 / 255.0), (255 / 255.0), 1}, // HighwayMotorway = 2,
        {(255 / 255.0), (66 / 255.0), (66 / 255.0), 1}, // HighwayPrimary = 3,
        {(255 / 255.0), (155 / 255.0), (66 / 255.0), 1}, // HighwaySecondary = 4,
        {(255 / 255.0), (255 / 255.0), (66 / 255.0), 1}, // HighwayTertiary = 5,
        {(255 / 255.0), (255 / 255.0), (255 / 255.0), 1}, // HighwayResidential = 6,
        {(255 / 255.0), (255 / 255.0), (255 / 255.0), 1} // HighwayService = 7,
    };
    const CGFloat strokeColors[8][4] = {
        {0, 0, 0, 0},
        {(140 / 255.0), (93 / 255.0), (33 / 255.0), 1}, // Building = 1,
        {(44 / 255.0), (44 / 255.0), (200 / 255.0), 1}, // HighwayMotorway = 2,
        {(200 / 255.0), (44 / 255.0), (44 / 255.0), 1}, // HighwayPrimary = 3,
        {(200 / 255.0), (100 / 255.0), (44 / 255.0), 1}, // HighwaySecondary = 4,
        {(200 / 255.0), (200 / 255.0), (44 / 255.0), 1}, // HighwayTertiary = 5,
        {(200 / 255.0), (200 / 255.0), (200 / 255.0), 1}, // HighwayResidential = 6,
        {(200 / 255.0), (200 / 255.0), (200 / 255.0), 1} // HighwayService = 7,
    };
    
    CGContextSetFillColor(c, backgroundColor);
    CGContextFillRect(c, bounds);
    
    uint32_t pos = 0;
    
    uint32_t resolutionBits = 8;
    double intToFloat = width / (1 << resolutionBits);
    
    int32_t ix, iy;
    double x, y, firstX, firstY;
    
    while (pos < dataSize) {
        ix = 0;
        iy = 0;
        RSTiledataThingType thingType = (RSTiledataThingType)RSVarintRead(data, &pos);
        uint32_t numNodes = RSVarintRead(data, &pos);
        for (uint32_t i = 0; i < numNodes; i++) {
            ix += RSVarintSignedRead(data, &pos);
            iy += RSVarintSignedRead(data, &pos);
            x = intToFloat * ix;
            y = intToFloat * iy;
            if (graphicsSpace == RSTileRendererGraphicsSpaceQuadrantOne) {
                y = height - y;
            }
            if (i == 0) {
                firstX = x;
                firstY = y;
                CGContextMoveToPoint(c, x, y);
            } else {
                CGContextAddLineToPoint(c, x, y);
            }
        }
        CGContextSetFillColor(c, fillColors[thingType]);
        CGContextSetStrokeColor(c, strokeColors[thingType]);
        switch (thingType) {
            case RSTiledataBuilding:
                CGContextSetLineWidth(c, 4);
                break;
            case RSTiledataHighwayMotorway:
            case RSTiledataHighwayPrimary:
            case RSTiledataHighwaySecondary:
            case RSTiledataHighwayTertiary:
            case RSTiledataHighwayResidential:
            case RSTiledataHighwayService:
                CGContextSetLineWidth(c, 12);
                break;
        }
        if (RSTiledataThingTypeIsClosedWay(thingType)) {
            CGContextAddLineToPoint(c, firstX, firstY);
            CGContextDrawPath(c, kCGPathFillStroke);
        } else {
            CGContextStrokePath(c);
        }
    }
}
Exemple #27
0
void QuartzWindow::set_thickness(int t) {
  CGContextSetLineWidth(myContext, max(1, t));
}
Exemple #28
0
static void MusicBoxDrawIndicator(HIViewRef view, CGContextRef mboxctx)
{
	if (!showIndicator)
		return;

	// Bar

	const double	length[] = { 1.0, 1.0 };

	CGContextSetLineWidth(mboxctx, mbxBarWidth);
	CGContextSetLineDash(mboxctx, 0, length, 2);
	CGContextSetLineJoin(mboxctx, kCGLineJoinMiter);

	CGContextBeginPath(mboxctx);

	double   x = mbxOffsetX + mbxMarginX + mbxBarWidth / 2.0;
	for (int h = 0; h < 8; h++)
	{
		// Inactive

		CGContextSetRGBStrokeColor(mboxctx, (196.0 / 256.0), (200.0 / 256.0), (176.0 / 256.0), 1.0);

		CGContextMoveToPoint   (mboxctx, x,                mbxOffsetY + mbxMarginY);
		CGContextAddLineToPoint(mboxctx, x,                mbxOffsetY + mbxMarginY + mbxBarHeight);

		CGContextMoveToPoint   (mboxctx, x + mbxRightBarX, mbxOffsetY + mbxMarginY);
		CGContextAddLineToPoint(mboxctx, x + mbxRightBarX, mbxOffsetY + mbxMarginY + mbxBarHeight);

		CGContextStrokePath(mboxctx);

		// Max

		Channel	*ch = &SoundData.channels[h];

		ch->envx = ch->xenvx >> 4;
		ch-> left_vol_level = (ch->xenvx * ch->volume_left ) >> 11;
		ch->right_vol_level = (ch->xenvx * ch->volume_right) >> 11;

		short		vl = ch-> left_vol_level;
		short		vr = ch->right_vol_level;
		long long	currentTime;

		if (vl <= 0) vl = 0; else if (vl > 64) vl = 64; else vl = (short) (yyscale * sqrt((double) vl)) & (~0 << 1);
		if (vr <= 0) vr = 0; else if (vr > 64) vr = 64; else vr = (short) (yyscale * sqrt((double) vr)) & (~0 << 1);

		if (vl < prevLVol[h]) vl = ((prevLVol[h] + vl) >> 1);
		if (vr < prevRVol[h]) vr = ((prevRVol[h] + vr) >> 1);

		Microseconds((UnsignedWide *) &currentTime);

		// left

		if ((vl >= prevLMax[h]) && (vl > prevLVol[h]))
		{
			barTimeL[h] = currentTime;
			prevLMax[h] = vl;
		}
		else
		if ((prevLMax[h] > 0) && (barTimeL[h] + 1000000 > currentTime))
		{
			CGContextSetRGBStrokeColor(mboxctx, (22.0 / 256.0), (156.0 / 256.0), (20.0 / 256.0), (double) (barTimeL[h] + 1000000 - currentTime) / 1000000.0);

			CGContextMoveToPoint   (mboxctx, x, mbxOffsetY + mbxMarginY + (double) (prevLMax[h] - 2));
			CGContextAddLineToPoint(mboxctx, x, mbxOffsetY + mbxMarginY + (double) (prevLMax[h]    ));

			CGContextStrokePath(mboxctx);
		}
		else
			prevLMax[h] = 0;

		prevLVol[h] = vl;

		// right

		if ((vr >= prevRMax[h]) && (vr > prevRVol[h]))
		{
			barTimeR[h] = currentTime;
			prevRMax[h] = vr;
		}
		else
		if ((prevRMax[h] > 0) && (barTimeR[h] + 1000000 > currentTime))
		{
			CGContextSetRGBStrokeColor(mboxctx, (22.0 / 256.0), (156.0 / 256.0), (20.0 / 256.0), (double) (barTimeR[h] + 1000000 - currentTime) / 1000000.0);

			CGContextMoveToPoint   (mboxctx, x + mbxRightBarX, mbxOffsetY + mbxMarginY + (double) (prevRMax[h] - 2));
			CGContextAddLineToPoint(mboxctx, x + mbxRightBarX, mbxOffsetY + mbxMarginY + (double) (prevRMax[h]    ));

			CGContextStrokePath(mboxctx);
		}
		else
			prevRMax[h] = 0;

		prevRVol[h] = vr;

		// Active

		CGContextSetRGBStrokeColor(mboxctx, (22.0 / 256.0), (22.0 / 256.0), (20.0 / 256.0), 1.0);

		CGContextMoveToPoint   (mboxctx, x,                mbxOffsetY + mbxMarginY);
		CGContextAddLineToPoint(mboxctx, x,                mbxOffsetY + mbxMarginY + (double) vl);
		CGContextStrokePath(mboxctx);
		CGContextMoveToPoint   (mboxctx, x + mbxRightBarX, mbxOffsetY + mbxMarginY);
		CGContextAddLineToPoint(mboxctx, x + mbxRightBarX, mbxOffsetY + mbxMarginY + (double) vr);
		CGContextStrokePath(mboxctx);

		x += (mbxBarWidth + mbxBarSpace);
	}
}
Exemple #29
0
static pascal OSStatus CustomSpotViewHandler(EventHandlerCallRef inCaller, EventRef inEvent, void* inRefcon)
{
	OSStatus result = eventNotHandledErr;
	CustomSpotViewData* myData = (CustomSpotViewData*)inRefcon;
	
	switch (GetEventClass(inEvent))
	{
		case kEventClassHIObject:
			switch (GetEventKind(inEvent))
			{
				case kEventHIObjectConstruct:
				{
					myData = (CustomSpotViewData*) calloc(1, sizeof(CustomSpotViewData));
					GetEventParameter(inEvent, kEventParamHIObjectInstance, typeHIObjectRef, NULL, sizeof(myData->view), NULL, &myData->view);
					result = SetEventParameter(inEvent, kEventParamHIObjectInstance, typeVoidPtr, sizeof(myData), &myData);
					break;
				}
					
				case kEventHIObjectInitialize:
				{
					HIRect bounds;
					GetEventParameter(inEvent, kEventParamBounds, typeHIRect, NULL, sizeof(bounds), NULL, &bounds);
					myData->spot.x = CGRectGetMidX(bounds) - CGRectGetMinX(bounds);
					myData->spot.y = CGRectGetMidY(bounds) - CGRectGetMinY(bounds);
					HIViewSetVisible(myData->view, true);
					break;
				}
					
				case kEventHIObjectDestruct:
				{
					free(myData);
					result = noErr;
					break;
				}
					
				default:
					break;
			}
			break;
			
		case kEventClassControl:
			switch (GetEventKind(inEvent))
			{
				case kEventControlDraw:
				{
					CGContextRef	context;
					HIRect			bounds;
					result = GetEventParameter(inEvent, kEventParamCGContextRef, typeCGContextRef, NULL, sizeof(context), NULL, &context);
					HIViewGetBounds(myData->view, &bounds);
					
					if (!IsControlActive(myData->view))
					{
						CGContextSetGrayStrokeColor(context, 0.5, 0.3);
						CGContextSetGrayFillColor(context, 0.5, 0.3);
					}
					else
					{
						CGContextSetRGBStrokeColor(context, 0.0, 0.0, 0.0, 0.7);
						CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 0.7);
					}
					
					CGContextSetLineWidth(context, 3.0);
					CGContextStrokeRect(context, bounds);
					
					HIRect spot = { {myData->spot.x - 4.0, myData->spot.y - 4.0}, {8.0, 8.0} };
					CGContextFillRect(context, spot);
					
					result = noErr;
					break;
				}
					
				case kEventControlBoundsChanged:
				{
					HIRect newHIBounds;
					GetEventParameter(inEvent, kEventParamCurrentBounds, typeHIRect, NULL, sizeof(newHIBounds), NULL, &newHIBounds);
					myData->spot.x = CGRectGetMidX(newHIBounds) - CGRectGetMinX(newHIBounds);
					myData->spot.y = CGRectGetMidY(newHIBounds) - CGRectGetMinY(newHIBounds);
					break;
				}
					
				case kEventControlHitTest:
				{
					HIPoint	pt;
					HIRect	bounds;
					GetEventParameter(inEvent, kEventParamMouseLocation, typeHIPoint, NULL, sizeof(pt), NULL, &pt);
					HIViewGetBounds(myData->view, &bounds);
					ControlPartCode part = (CGRectContainsPoint(bounds, pt))?kControlButtonPart:kControlNoPart;
					result = SetEventParameter(inEvent, kEventParamControlPart, typeControlPartCode, sizeof(part), &part);
					break;
				}
					
				case kEventControlTrack:
				{
					Point qdPoint;
					Rect qdWindowBounds;
					HIPoint hiPoint;
					HIRect hiViewBounds;
					MouseTrackingResult mouseStatus = kMouseTrackingMouseDown;
					
					HIViewGetBounds(myData->view, &hiViewBounds);
					GetWindowBounds(GetControlOwner(myData->view), kWindowStructureRgn, &qdWindowBounds);
					
					// handle the first mouseDown before moving
					GetEventParameter(inEvent, kEventParamMouseLocation, typeHIPoint, NULL, sizeof(hiPoint), NULL, &hiPoint);
					
					while (mouseStatus != kMouseTrackingMouseUp)
					{
						if (CGRectContainsPoint(hiViewBounds, hiPoint))
						{
							if (hiPoint.x < hiViewBounds.origin.x+4) hiPoint.x = hiViewBounds.origin.x+4;
							if (hiPoint.x > hiViewBounds.origin.x+hiViewBounds.size.width-4) hiPoint.x = hiViewBounds.origin.x+hiViewBounds.size.width-4;
							if (hiPoint.y < hiViewBounds.origin.y+4) hiPoint.y = hiViewBounds.origin.y+4;
							if (hiPoint.y > hiViewBounds.origin.y+hiViewBounds.size.height-4) hiPoint.y = hiViewBounds.origin.y+hiViewBounds.size.height-4;
							myData->spot = hiPoint;
							HIViewSetNeedsDisplay(myData->view, true);
						}
						
						// a -1 GrafPtr to TrackMouseLocation yields global coordinates
						TrackMouseLocation((GrafPtr)-1L, &qdPoint, &mouseStatus);						
						
						// convert to window-relative coordinates
						hiPoint.x = qdPoint.h - qdWindowBounds.left;
						hiPoint.y = qdPoint.v - qdWindowBounds.top;
						
						// convert to view-relative coordinates
						HIViewConvertPoint(&hiPoint, NULL, myData->view);
					}
					break;
				}
					
					
				default:
					break;
			}
			break;
			
		default:
			break;
	}
	
	return result;
}
Exemple #30
0
// Draws the current ATSUI data.  Takes a GrafPtr as an argument so
// that it can handle printing as well as drawing into a window.
//
void DrawATSUIStuff(GrafPtr drawingPort)
{
    GrafPtr                             savedPort;
    Rect                                portBounds, quarterRect2, quarterRect3;
    float								windowHeight, quarter;
    CGContextRef						context;
    TXNTextBoxOptionsData				optionsData;
    Boolean								needToUseCGStrokeMethod;

    // Set up the GrafPort
    GetPort(&savedPort);
    SetPort(drawingPort);
    GetPortBounds(drawingPort, &portBounds);
    EraseRect(&portBounds);

    // Divide the window into vertical quarters, and draw the text in the middle two quarters
    windowHeight = portBounds.bottom - portBounds.top;
    quarter = windowHeight / 4.0;
    MacSetRect(&quarterRect2, portBounds.left, portBounds.top + quarter, portBounds.right, portBounds.bottom - (quarter * 2.0));
    FrameRect(&quarterRect2);
    MacSetRect(&quarterRect3, portBounds.left, portBounds.top + (quarter * 2.0), portBounds.right, portBounds.bottom - quarter);
    FrameRect(&quarterRect3);

    // Set up the CGContext
    if (gNewCG) QDBeginCGContext(drawingPort, &context); else CreateCGContextForPort(drawingPort, &context);

    // Setup the options to pass into TXNDrawUnicodeTextBox
    optionsData.optionTags = kTXNUseCGContextRefMask | kTXNSetFlushnessMask | kTXNUseFontFallBackMask;
    optionsData.flushness = X2Frac(0.5);   // Center the text horizontally, just for this demo.
    optionsData.options = (void *)context; // This parameter really needs to be renamed, see 3198383.

    // Draw the text once without the extr bold
    verify_noerr( TXNDrawUnicodeTextBox(gText, gLength, &quarterRect2, gStyle, &optionsData) );

    // ----------------------------------------------------------
    //
    // Here is where we change the setting to do the extra stroke
    // The value of gStrokeThicknessFactor determines how thick the extra stroke is.
    //   The "standard" value used by ATSUI is 0.024;
    //     this was changed to 0.044 for bug 3189696,
    //     and will probably be changed back, so if you
    //     want the extra stroke, you will have to do it
    //     manually, as is done below.
    //
    // The extra stroke method:
    //  - will look good on-screen when CG anti-aliasing is ON
    //  - will look good when printing
    //  - will *NOT* look good on-screen when CG anti-aliasing is OFF
    //     (just use kATSUQDBoldfaceTag in that case)
    //
    needToUseCGStrokeMethod = gCurrentlyPrinting || IsAntiAliased(gPointSize);
    if ( needToUseCGStrokeMethod ) {
        CGContextSaveGState(context);
        CGContextSetTextDrawingMode(context, kCGTextFillStroke);
        CGContextSetLineWidth(context, gStrokeThicknessFactor * Fix2X(gPointSize));
        // You might want to call CGContextSetStrokeColor() here,
        // just to make certain it is the same as the text/fill color.
    }
    else
        MySetBoldfaceTag(gStyle); // This will look very strong on-screen when CG anti-aliasing is off

    // Draw the text again with the extra bold for comparison
    verify_noerr( TXNDrawUnicodeTextBox(gText, gLength, &quarterRect3, gStyle, &optionsData) );

    // Undo the previous CG text mode setting
    if ( needToUseCGStrokeMethod )
        CGContextRestoreGState(context);
    else
        MyClearBoldfaceTag(gStyle);

    // Tear down the CGContext since we are done with it
    if (gNewCG) QDEndCGContext(drawingPort, &context); else CGContextRelease(context);    

    // Restore the GrafPort
    SetPort(savedPort);
}