Exemplo n.º 1
0
PyObject *
Py_Outline_cnew(FT_Outline *outline)
{
    Py_Outline *self;

    self = (Py_Outline *)(&Py_Outline_Type)->tp_alloc(&Py_Outline_Type, 0);
    if (self == NULL) {
        return NULL;
    }

    self->points = NULL;
    self->codes = NULL;
    self->inited = 0;

    if (ftpy_exc(
            FT_Outline_New(get_ft_library(),
                           outline->n_points,
                           outline->n_contours,
                           &self->x))) {
        Py_DECREF(self);
        return NULL;
    }

    self->inited = 1;

    if (ftpy_exc(
            FT_Outline_Copy(outline, &self->x))) {
        Py_DECREF(self);
        return NULL;
    }

    self->base.owner = NULL;
    return (PyObject *)self;
}
Exemplo n.º 2
0
static PyObject*
Py_Outline_check(Py_Outline* self, PyObject* args, PyObject* kwds)
{
    if (ftpy_exc(
            FT_Outline_Check(&self->x))) {
        return NULL;
    }

    Py_RETURN_NONE;
};
Exemplo n.º 3
0
static PyObject*
Py_Outline_get_bbox(Py_Outline* self, PyObject* args, PyObject* kwds)
{
    FT_BBox bbox;

    if (ftpy_exc(
            FT_Outline_Get_BBox(&self->x, &bbox))) {
        return NULL;
    }

    return Py_BBox_cnew(&bbox, 1.0);
}
Exemplo n.º 4
0
static int
Py_Layout_init(Py_Layout *self, PyObject *args, PyObject *kwds)
{
    static char *kwlist[] = {"face", "text", "load_flags", NULL};
    PyObject *face_obj = NULL;
    Py_Face *face = NULL;
    PyObject *text_obj;
    int load_flags = FT_LOAD_DEFAULT;
    PyObject *text = NULL;
    PyObject *decoded_text = NULL;
    char *decoded_text_buf;
    Py_ssize_t decoded_text_size;
    int result = -1;

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O|i:Layout.__init__", kwlist,
                                     &Py_Face_Type, &face_obj,
                                     &text_obj,
                                     &load_flags)) {
        goto exit;
    }

    face = (Py_Face *)face_obj;

    if (face->x->charmap == NULL ||
        face->x->charmap->encoding != FT_ENCODING_UNICODE) {
        PyErr_SetString(
            PyExc_ValueError, "The layout only supports Unicode character map");
        goto exit;
    }

    text = PyUnicode_FromObject(text_obj);
    if (text == NULL) {
        goto exit;
    }

    decoded_text = PyUnicode_AsUTF32String(text);
    if (decoded_text == NULL) {
        goto exit;
    }

    if (PyBytes_AsStringAndSize(decoded_text, &decoded_text_buf, &decoded_text_size)) {
        goto exit;
    }

    decoded_text_buf += 4;
    decoded_text_size = (decoded_text_size - 4) >> 2;

    if (ftpy_exc(ftpy_calculate_simple_layout(
        face->x, load_flags,
        (uint32_t *)decoded_text_buf, decoded_text_size, &self->x))) {
        goto exit;
    }

    Py_INCREF(face_obj);
    self->base.owner = face_obj;

    result = 0;

 exit:

    Py_XDECREF(text);
    Py_XDECREF(decoded_text);

    return result;
}
Exemplo n.º 5
0
static PyObject*
Py_Outline_to_points_and_codes(Py_Outline* self, PyObject* args, PyObject* kwds)
{
    PyObject *result = NULL;
    PyObject *points = NULL;
    PyObject *codes = NULL;
    DecomposeToPointsAndCodesData data;
    const FT_Outline_Funcs funcs = {
        .move_to = Py_Outline_to_points_and_codes_moveto_func,
        .line_to = Py_Outline_to_points_and_codes_lineto_func,
        .conic_to = Py_Outline_to_points_and_codes_conicto_func,
        .cubic_to = Py_Outline_to_points_and_codes_cubicto_func,

        .shift = 0,
        .delta = 0
    };
    int error;

    if (!self->points || !self->codes) {
        memset(&data, 0, sizeof(DecomposeToPointsAndCodesData));

        error = FT_Outline_Decompose(&self->x, &funcs, &data);
        if (PyErr_Occurred()) {
            PyMem_Free(data.points);
            PyMem_Free(data.codes);
            goto exit;
        } else if (ftpy_exc(error)) {
            PyMem_Free(data.points);
            PyMem_Free(data.codes);
            goto exit;
        }

        self->points = data.points;
        self->codes = data.codes;
        self->n_points = data.cursor;
    }

    points = Py_Outline_Decomposed_Points_Buffer_cnew((PyObject *)self);
    if (points == NULL) {
        goto exit;
    }

    codes = Py_Outline_Codes_Buffer_cnew((PyObject *)self);
    if (codes == NULL) {
        Py_DECREF(points);
        goto exit;
    }

    result = Py_BuildValue("(OO)", points, codes);
    if (result == NULL) {
        Py_DECREF(points);
        Py_DECREF(codes);
        goto exit;
    }

 exit:

    return result;
}


static PyObject*
Py_Outline_to_string(Py_Outline* self, PyObject* args, PyObject* kwds)
{
    PyObject *result = NULL;
    DecomposeToStringData data;
    const FT_Outline_Funcs funcs = {
        .move_to = Py_Outline_to_string_moveto_func,
        .line_to = Py_Outline_to_string_lineto_func,
        .conic_to = Py_Outline_to_string_conicto_func,
        .cubic_to = Py_Outline_to_string_cubicto_func,

        .shift = 0,
        .delta = 0
    };
    int error;

    const char* keywords[] = {
        "move_command", "line_command", "cubic_command", "conic_command",
        "prefix", NULL};

    data.prefix = 0;
    data.conic_command = NULL;

    if (!PyArg_ParseTupleAndKeywords(
            args, kwds, "sss|si:to_string", (char **)keywords,
            &data.move_command, &data.line_command,
            &data.cubic_command, &data.conic_command,
            &data.prefix)) {
        return NULL;
    }

    data.buffer = PyMem_Malloc(BUFFER_CHUNK_SIZE);
    if (data.buffer == NULL) {
        return NULL;
    }
    data.buffer[0] = 0;
    data.buffer_size = BUFFER_CHUNK_SIZE;
    data.cursor = 0;
    data.last_x = 0;
    data.last_y = 0;

    error = FT_Outline_Decompose(&self->x, &funcs, &data);
    if (PyErr_Occurred()) {
        goto exit;
    } else if (ftpy_exc(error)) {
        goto exit;
    }

    result = PyBytes_FromStringAndSize(data.buffer, data.cursor);
    if (result == NULL) {
        goto exit;
    }

 exit:
    PyMem_Free(data.buffer);

    return result;
}


static PyObject*
Py_Outline_translate(Py_Outline* self, PyObject* args, PyObject* kwds)
{
    long xOffset;
    long yOffset;

    /* TODO: What is the scale of these arguments? */

    const char* keywords[] = {"x_offset", "y_offset", NULL};

    if (!PyArg_ParseTupleAndKeywords(
            args, kwds, "ll:translate", (char **)keywords,
            &xOffset, &yOffset)) {
        return NULL;
    }

    FT_Outline_Translate(&self->x, xOffset, yOffset);

    Py_RETURN_NONE;
};
Exemplo n.º 6
0
static PyObject*
Py_Outline_decompose(Py_Outline* self, PyObject* args, PyObject* kwds)
{
    /* TODO: Also implement this as an iterator */

    DecomposeData data;
    PyObject *obj;
    const FT_Outline_Funcs funcs = {
        .move_to = Py_Outline_moveto_func,
        .line_to = Py_Outline_lineto_func,
        .conic_to = Py_Outline_conicto_func,
        .cubic_to = Py_Outline_cubicto_func,

        .shift = 0,
        .delta = 0
    };
    int error;

    const char* keywords[] = {"obj", "shift", "delta", NULL};

    if (!PyArg_ParseTupleAndKeywords(
            args, kwds, "O|ii:decompose", (char **)keywords,
            &obj, &funcs.shift, &funcs.delta)) {
        return NULL;
    }

    if (!PyObject_HasAttrString(obj, "move_to")) {
        PyErr_SetString(PyExc_AttributeError, "obj has no move_to method");
        return NULL;
    }
    if (!PyObject_HasAttrString(obj, "line_to")) {
        PyErr_SetString(PyExc_AttributeError, "obj has no line_to method");
        return NULL;
    }
    if (!PyObject_HasAttrString(obj, "cubic_to")) {
        PyErr_SetString(PyExc_AttributeError, "obj has no cubic_to method");
        return NULL;
    }
    data.has_conic_to = PyObject_HasAttrString(obj, "conic_to");
    data.callback = obj;
    data.last_x = 0;
    data.last_y = 0;

    error = FT_Outline_Decompose(&self->x, &funcs, &data);
    if (PyErr_Occurred()) {
        return NULL;
    } else if (ftpy_exc(error)) {
        return NULL;
    }

    Py_RETURN_NONE;
};


static PyObject*
Py_Outline_embolden(Py_Outline* self, PyObject* args, PyObject* kwds)
{
    double strength;

    const char* keywords[] = {"strength", NULL};

    if (!PyArg_ParseTupleAndKeywords(
            args, kwds, "d:embolden", (char **)keywords,
            &strength)) {
        return NULL;
    }

    if (ftpy_exc(
            FT_Outline_Embolden(&self->x, TO_F26DOT6(strength)))) {
        return NULL;
    }

    Py_RETURN_NONE;
};