Esempio n. 1
0
//-----------------------------------------------------------------------------
void CGDrawContext::drawLines (const CPoint* points, const int32_t& numLines)
{
	CGContextRef context = beginCGContext (true, currentState.drawMode.integralMode ());
	if (context) 
	{
		applyLineStyle (context);

		if ((((int32_t)currentState.frameWidth) % 2))
			CGContextTranslateCTM (context, 0.5f, -0.5f);

		CGPoint* cgPoints = new CGPoint[numLines*2];
		for (int32_t i = 0; i < numLines * 2; i += 2)
		{
			if (currentState.drawMode.integralMode ())
			{
				cgPoints[i].x = round (points[i].x);
				cgPoints[i+1].x = round (points[i+1].x);
				cgPoints[i].y = round (points[i].y);
				cgPoints[i+1].y = round (points[i+1].y);
			}
			else
			{
				cgPoints[i].x = points[i].x;
				cgPoints[i+1].x = points[i+1].x;
				cgPoints[i].y = points[i].y;
				cgPoints[i+1].y = points[i+1].y;
			}
		}
		CGContextStrokeLineSegments (context, cgPoints, numLines*2);
		delete [] cgPoints;

		releaseCGContext (context);
	}
}
Esempio n. 2
0
//-----------------------------------------------------------------------------
void CGDrawContext::drawLines (const LineList& lines)
{
    if (lines.size () == 0)
        return;
    CGContextRef context = beginCGContext (true, getDrawMode ().integralMode ());
    if (context)
    {
        applyLineStyle (context);

        CGPoint* cgPoints = new CGPoint[lines.size () * 2];
        uint32_t index = 0;
        VSTGUI_RANGE_BASED_FOR_LOOP(LineList, lines, LinePair, line)
        cgPoints[index] = CGPointFromCPoint (line.first);
        cgPoints[index+1] = CGPointFromCPoint (line.second);
        if (getDrawMode ().integralMode ())
        {
            cgPoints[index] = pixelAlligned (cgPoints[index]);
            cgPoints[index+1] = pixelAlligned (cgPoints[index+1]);
        }
        index += 2;
        VSTGUI_RANGE_BASED_FOR_LOOP_END

        if (getDrawMode ().integralMode ())
        {
            int32_t frameWidth = static_cast<int32_t> (currentState.frameWidth);
            if (frameWidth % 2)
                CGContextTranslateCTM (context, 0.5, 0.5);
        }

        CGContextStrokeLineSegments (context, cgPoints, lines.size () * 2);
        delete [] cgPoints;

        releaseCGContext (context);
    }
}
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 GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& point, int width, bool grammar)
{
    if (paintingDisabled())
        return;

    // These are the same for misspelling or bad grammar
    const int patternHeight = 3; // 3 rows
    ASSERT(cMisspellingLineThickness == patternHeight);
    const int patternWidth = 4; // 4 pixels
    ASSERT(patternWidth == cMisspellingLinePatternWidth);

    // Make sure to draw only complete dots.
    // NOTE: Code here used to shift the underline to the left and increase the width
    // to make sure everything gets underlined, but that results in drawing out of
    // bounds (e.g. when at the edge of a view) and could make it appear that the
    // space between adjacent misspelled words was underlined.
    // allow slightly more considering that the pattern ends with a transparent pixel
    int widthMod = width % patternWidth;
    if (patternWidth - widthMod > cMisspellingLinePatternGapWidth)
        width -= widthMod;
      
    // Draw the underline
    CGContextRef context = platformContext();
    CGContextSaveGState(context);

    const Color& patternColor = grammar ? grammarPatternColor() : spellingPatternColor();
    setCGStrokeColor(context, patternColor);

    wkSetPatternPhaseInUserSpace(context, point);
    CGContextSetBlendMode(context, kCGBlendModeNormal);
    
    // 3 rows, each offset by half a pixel for blending purposes
    const CGPoint upperPoints [] = {{point.x(), point.y() + patternHeight - 2.5 }, {point.x() + width, point.y() + patternHeight - 2.5}};
    const CGPoint middlePoints [] = {{point.x(), point.y() + patternHeight - 1.5 }, {point.x() + width, point.y() + patternHeight - 1.5}};
    const CGPoint lowerPoints [] = {{point.x(), point.y() + patternHeight - 0.5 }, {point.x() + width, point.y() + patternHeight - 0.5 }};
    
    // Dash lengths for the top and bottom of the error underline are the same.
    // These are magic.
    static const float edge_dash_lengths[] = {2.0f, 2.0f};
    static const float middle_dash_lengths[] = {2.76f, 1.24f};
    static const float edge_offset = -(edge_dash_lengths[1] - 1.0f) / 2.0f;
    static const float middle_offset = -(middle_dash_lengths[1] - 1.0f) / 2.0f;

    // Line opacities.  Once again, these are magic.
    const float upperOpacity = 0.33f;
    const float middleOpacity = 0.75f;
    const float lowerOpacity = 0.88f;

    //Top line
    CGContextSetLineDash(context, edge_offset, edge_dash_lengths, 
                         sizeof(edge_dash_lengths) / sizeof(edge_dash_lengths[0]));
    CGContextSetAlpha(context, upperOpacity);
    CGContextStrokeLineSegments(context, upperPoints, 2);
 
    // Middle line
    CGContextSetLineDash(context, middle_offset, middle_dash_lengths, 
                         sizeof(middle_dash_lengths) / sizeof(middle_dash_lengths[0]));
    CGContextSetAlpha(context, middleOpacity);
    CGContextStrokeLineSegments(context, middlePoints, 2);
    
    // Bottom line
    CGContextSetLineDash(context, edge_offset, edge_dash_lengths,
                         sizeof(edge_dash_lengths) / sizeof(edge_dash_lengths[0]));
    CGContextSetAlpha(context, lowerOpacity);
    CGContextStrokeLineSegments(context, lowerPoints, 2);

    CGContextRestoreGState(context);
}