Ejemplo n.º 1
0
static void copyClosingSubpathsApplierFunction(void* info, const CGPathElement* element)
{
    CGMutablePathRef path = static_cast<CGMutablePathRef>(info);
    CGPoint* points = element->points;
    
    switch (element->type) {
    case kCGPathElementMoveToPoint:
        if (!CGPathIsEmpty(path)) // to silence a warning when trying to close an empty path
            CGPathCloseSubpath(path); // This is the only change from CGPathCreateMutableCopy
        CGPathMoveToPoint(path, 0, points[0].x, points[0].y);
        break;
    case kCGPathElementAddLineToPoint:
        CGPathAddLineToPoint(path, 0, points[0].x, points[0].y);
        break;
    case kCGPathElementAddQuadCurveToPoint:
        CGPathAddQuadCurveToPoint(path, 0, points[0].x, points[0].y, points[1].x, points[1].y);
        break;
    case kCGPathElementAddCurveToPoint:
        CGPathAddCurveToPoint(path, 0, points[0].x, points[0].y, points[1].x, points[1].y, points[2].x, points[2].y);
        break;
    case kCGPathElementCloseSubpath:
        CGPathCloseSubpath(path);
        break;
    }
}
Ejemplo n.º 2
0
void
PathBuilderCG::BezierTo(const Point &aCP1,
                         const Point &aCP2,
                         const Point &aCP3)
{
  if (!aCP1.IsFinite() || !aCP2.IsFinite() || !aCP3.IsFinite()) {
    return;
  }

  if (CGPathIsEmpty(mCGPath))
    MoveTo(aCP1);
  CGPathAddCurveToPoint(mCGPath, nullptr,
                          aCP1.x, aCP1.y,
                          aCP2.x, aCP2.y,
                          aCP3.x, aCP3.y);

}
Ejemplo n.º 3
0
 static void
 TranformCGPathApplierFunc(void *vinfo, const CGPathElement *element)
 {
   TransformApplier *info = reinterpret_cast<TransformApplier*>(vinfo);
   switch (element->type) {
     case kCGPathElementMoveToPoint:
       {
         CGPoint pt = element->points[0];
         CGPathMoveToPoint(info->path, &info->transform, pt.x, pt.y);
         break;
       }
     case kCGPathElementAddLineToPoint:
       {
         CGPoint pt = element->points[0];
         CGPathAddLineToPoint(info->path, &info->transform, pt.x, pt.y);
         break;
       }
     case kCGPathElementAddQuadCurveToPoint:
       {
         CGPoint cpt = element->points[0];
         CGPoint pt  = element->points[1];
         CGPathAddQuadCurveToPoint(info->path, &info->transform, cpt.x, cpt.y, pt.x, pt.y);
         break;
       }
     case kCGPathElementAddCurveToPoint:
       {
         CGPoint cpt1 = element->points[0];
         CGPoint cpt2 = element->points[1];
         CGPoint pt   = element->points[2];
         CGPathAddCurveToPoint(info->path, &info->transform, cpt1.x, cpt1.y, cpt2.x, cpt2.y, pt.x, pt.y);
         break;
       }
     case kCGPathElementCloseSubpath:
       {
         CGPathCloseSubpath(info->path);
         break;
       }
   }
 }
Ejemplo n.º 4
0
static CGPathRef createPathForGlyph(HDC hdc, Glyph glyph)
{
    CGMutablePathRef path = CGPathCreateMutable();

    static const MAT2 identity = { 0, 1,  0, 0,  0, 0,  0, 1 };
    GLYPHMETRICS glyphMetrics;
    // GGO_NATIVE matches the outline perfectly when Windows font smoothing is off.
    // GGO_NATIVE | GGO_UNHINTED does not match perfectly either when Windows font smoothing is on or off.
    DWORD outlineLength = GetGlyphOutline(hdc, glyph, GGO_GLYPH_INDEX | GGO_NATIVE, &glyphMetrics, 0, 0, &identity);
    ASSERT(outlineLength >= 0);
    if (outlineLength < 0)
        return path;

    Vector<UInt8> outline(outlineLength);
    GetGlyphOutline(hdc, glyph, GGO_GLYPH_INDEX | GGO_NATIVE, &glyphMetrics, outlineLength, outline.data(), &identity);

    unsigned offset = 0;
    while (offset < outlineLength) {
        LPTTPOLYGONHEADER subpath = reinterpret_cast<LPTTPOLYGONHEADER>(outline.data() + offset);
        ASSERT(subpath->dwType == TT_POLYGON_TYPE);
        if (subpath->dwType != TT_POLYGON_TYPE)
            return path;

        CGPathMoveToPoint(path, 0, toCGFloat(subpath->pfxStart.x), toCGFloat(subpath->pfxStart.y));

        unsigned subpathOffset = sizeof(*subpath);
        while (subpathOffset < subpath->cb) {
            LPTTPOLYCURVE segment = reinterpret_cast<LPTTPOLYCURVE>(reinterpret_cast<UInt8*>(subpath) + subpathOffset);
            switch (segment->wType) {
            case TT_PRIM_LINE:
                for (unsigned i = 0; i < segment->cpfx; i++)
                    CGPathAddLineToPoint(path, 0, toCGFloat(segment->apfx[i].x), toCGFloat(segment->apfx[i].y));
                break;

            case TT_PRIM_QSPLINE:
                for (unsigned i = 0; i < segment->cpfx; i++) {
                    CGFloat x = toCGFloat(segment->apfx[i].x);
                    CGFloat y = toCGFloat(segment->apfx[i].y);
                    CGFloat cpx;
                    CGFloat cpy;

                    if (i == segment->cpfx - 2) {
                        cpx = toCGFloat(segment->apfx[i + 1].x);
                        cpy = toCGFloat(segment->apfx[i + 1].y);
                        i++;
                    } else {
                        cpx = (toCGFloat(segment->apfx[i].x) + toCGFloat(segment->apfx[i + 1].x)) / 2;
                        cpy = (toCGFloat(segment->apfx[i].y) + toCGFloat(segment->apfx[i + 1].y)) / 2;
                    }

                    CGPathAddQuadCurveToPoint(path, 0, x, y, cpx, cpy);
                }
                break;

            case TT_PRIM_CSPLINE:
                for (unsigned i = 0; i < segment->cpfx; i += 3) {
                    CGFloat cp1x = toCGFloat(segment->apfx[i].x);
                    CGFloat cp1y = toCGFloat(segment->apfx[i].y);
                    CGFloat cp2x = toCGFloat(segment->apfx[i + 1].x);
                    CGFloat cp2y = toCGFloat(segment->apfx[i + 1].y);
                    CGFloat x = toCGFloat(segment->apfx[i + 2].x);
                    CGFloat y = toCGFloat(segment->apfx[i + 2].y);

                    CGPathAddCurveToPoint(path, 0, cp1x, cp1y, cp2x, cp2y, x, y);
                }
                break;

            default:
                ASSERT_NOT_REACHED();
                return path;
            }

            subpathOffset += sizeof(*segment) + (segment->cpfx - 1) * sizeof(segment->apfx[0]);
        }
        CGPathCloseSubpath(path);
        offset += subpath->cb;
    }
    return path;
}
Ejemplo n.º 5
0
void Path::addBezierCurveTo(const FloatPoint& cp1, const FloatPoint& cp2, const FloatPoint& p)
{
    CGPathAddCurveToPoint(m_path, 0, cp1.x(), cp1.y(), cp2.x(), cp2.y(), p.x(), p.y());
}
Ejemplo n.º 6
0
void Path::addBezierCurveTo(const FloatPoint& cp1, const FloatPoint& cp2, const FloatPoint& p)
{
    CGPathAddCurveToPoint(ensurePlatformPath(), 0, cp1.x(), cp1.y(), cp2.x(), cp2.y(), p.x(), p.y());
}