コード例 #1
0
ps_bool PICAPI ps_get_font_info(ps_context* ctx, ps_font_info* info)
{
    if (!picasso::is_valid_system_device()) {
        global_status = STATUS_DEVICE_ERROR;
        return False;
    }

    if (!ctx || !info) {
        global_status = STATUS_INVALID_ARGUMENT;
        return False;
    }

    if (create_device_font(ctx)) {
        info->size = SCALAR_TO_FLT(ctx->fonts->current_font()->height());
        info->ascent = SCALAR_TO_FLT(ctx->fonts->current_font()->ascent());
        info->descent = SCALAR_TO_FLT(ctx->fonts->current_font()->descent());
        info->leading = SCALAR_TO_FLT(ctx->fonts->current_font()->leading());
        info->unitsEM = SCALAR_TO_INT(ctx->fonts->current_font()->units_per_em());
        global_status = STATUS_SUCCEED;
        return True;
    }

    global_status = STATUS_UNKNOWN_ERROR;
    return False;
}
コード例 #2
0
ps_size PICAPI ps_get_text_extent(ps_context* ctx, const void* text, unsigned int len)
{
    ps_size size = {0 , 0};

    if (!picasso::is_valid_system_device()) {
        global_status = STATUS_DEVICE_ERROR;
        return size;
    }

    if (!ctx || !text || !len) {
        global_status = STATUS_INVALID_ARGUMENT;
        return size;
    }

    scalar width = 0;

    if (create_device_font(ctx)) {

        if (ctx->state->font->desc.charset() == CHARSET_ANSI) {
            const char* p = (const char*)text;
            while (*p && len) {
                register char c = *p;
                const picasso::glyph* glyph = ctx->fonts->current_font()->get_glyph(c);
                if (glyph) 
                    width += glyph->advance_x;
                
                len--;
                p++;
            }
        } else {
            const ps_uchar16* p = (const ps_uchar16*)text;
            while (*p && len) {
                register ps_uchar16 c = *p;
                const picasso::glyph* glyph = ctx->fonts->current_font()->get_glyph(c);
                if (glyph) 
                    width += glyph->advance_x;
                
                len--;
                p++;
            }
        }
    }

    size.h = SCALAR_TO_FLT(ctx->fonts->current_font()->height());
    size.w = SCALAR_TO_FLT(width);
    global_status = STATUS_SUCCEED;
    return size;
}
コード例 #3
0
ファイル: picasso_path.cpp プロジェクト: corefan/img_picasso
ps_path_cmd PICAPI ps_path_get_vertex(const ps_path* path, unsigned int index, ps_point* point)
{
    if (!picasso::is_valid_system_device()) {
        global_status = STATUS_DEVICE_ERROR;
        return PATH_CMD_STOP;
    }

    if (!path || !point || (index > path->path.total_vertices()-1)) {
        global_status = STATUS_INVALID_ARGUMENT;
        return PATH_CMD_STOP;
    }

    scalar x = 0, y = 0;
    unsigned int cmd = path->path.vertex(index, &x, &y);
    point->x = SCALAR_TO_FLT(x);
    point->y = SCALAR_TO_FLT(y);
    global_status = STATUS_SUCCEED;
    return (ps_path_cmd)cmd;
}
コード例 #4
0
ps_size PICAPI ps_glyph_get_extent(const ps_glyph* g)
{
    ps_size size = {0 , 0};
    if (!picasso::is_valid_system_device()) {
        global_status = STATUS_DEVICE_ERROR;
        return size;
    }

    if (!g) {
        global_status = STATUS_INVALID_ARGUMENT;
        return size;
    }

    if (g->glyph) {
        const picasso::glyph* gp = reinterpret_cast<const picasso::glyph*>(g->glyph);
        size.w = SCALAR_TO_FLT(gp->advance_x);
        size.h = SCALAR_TO_FLT(gp->height); //Note: advance_y is 0
    }
    global_status = STATUS_SUCCEED;
    return size;
}
コード例 #5
0
ファイル: picasso_path.cpp プロジェクト: corefan/img_picasso
float PICAPI ps_path_get_length(const ps_path* path)
{
    if (!picasso::is_valid_system_device()) {
        global_status = STATUS_DEVICE_ERROR;
        return (0.0);
    }

    if (!path) {
        global_status = STATUS_INVALID_ARGUMENT;
        return (0.0);
    }

    global_status = STATUS_SUCCEED;
    return SCALAR_TO_FLT(picasso::path_length(const_cast<ps_path*>(path)->path, 0));
}
コード例 #6
0
void* gfx_font_adapter::create_storage(byte* buf, unsigned int len, scalar x, scalar y)
{
    m_impl->cur_font_storage_bin.init(buf, len, SCALAR_TO_FLT(Ceil(x)), SCALAR_TO_FLT(Ceil(y)));
    return (void*)&m_impl->cur_font_storage_bin;
}
コード例 #7
0
ファイル: picasso_path.cpp プロジェクト: corefan/img_picasso
void PICAPI ps_path_tangent_arc_to(ps_path* path, float r, const ps_point* tp, const ps_point* ep)
{
    if (!picasso::is_valid_system_device()) {
        global_status = STATUS_DEVICE_ERROR;
        return;
    }

    if (!path || !tp || !ep || r < 0) {
        global_status = STATUS_INVALID_ARGUMENT;
        return;
    }

    ps_point sp;
    sp.x = SCALAR_TO_FLT(path->path.last_x());
    sp.y = SCALAR_TO_FLT(path->path.last_y());
    if ((tp->x == sp.x && tp->y == sp.y) || (tp->x == ep->x && tp->y == ep->y) || r == 0.f) {
        ps_path_line_to(path, tp);
        global_status = STATUS_SUCCEED;
        return;
    }
    ps_point p1p0 = {(sp.x - tp->x), (sp.y - tp->y)};
    ps_point p1p2 = {(ep->x - tp->x), (ep->y - tp->y)};
    float p1p0_length = sqrtf(p1p0.x * p1p0.x + p1p0.y * p1p0.y);
    float p1p2_length = sqrtf(p1p2.x * p1p2.x + p1p2.y * p1p2.y);

    float cos_phi = (p1p0.x * p1p2.x + p1p0.y * p1p2.y) / (p1p0_length * p1p2_length);
    // all points on a line logic
    if (cos_phi == -1.0f) {
        ps_path_line_to(path, tp);
        global_status = STATUS_SUCCEED;
        return;
    }

    if (cos_phi == 1.0f) {
        // add infinite far away point
        unsigned int max_length = 65535;
        float factor_max = max_length / p1p0_length;
        ps_point np  = {(sp.x + factor_max * p1p0.x), (sp.y + factor_max * p1p0.y)};
        ps_path_line_to(path, &np);
        global_status = STATUS_SUCCEED;
        return;
    }


    float tangent = r / tanf(acosf(cos_phi) / 2);
    float factor_p1p0 = tangent / p1p0_length;
    ps_point t_p1p0 = {(tp->x + factor_p1p0 * p1p0.x), (tp->y + factor_p1p0 * p1p0.y)};

    ps_point orth_p1p0 = {p1p0.y, -p1p0.x};
    float orth_p1p0_length = sqrtf(orth_p1p0.x * orth_p1p0.x + orth_p1p0.y * orth_p1p0.y);
    float factor_ra = r / orth_p1p0_length;

    // angle between orth_p1p0 and p1p2 to get the right vector orthographic to p1p0
    float cos_alpha = (orth_p1p0.x * p1p2.x + orth_p1p0.y * p1p2.y) / (orth_p1p0_length * p1p2_length);
    if (cos_alpha < 0.f) {
        orth_p1p0.x = -orth_p1p0.x;
        orth_p1p0.y = -orth_p1p0.y;
    }

    ps_point p = {(t_p1p0.x + factor_ra * orth_p1p0.x), (t_p1p0.y + factor_ra * orth_p1p0.y)};

    // calculate angles for addArc
    orth_p1p0.x = -orth_p1p0.x;
    orth_p1p0.y = -orth_p1p0.y;
    float sa = acosf(orth_p1p0.x / orth_p1p0_length);
    if (orth_p1p0.y < 0.f)
        sa = 2 * PI - sa;

    // clockwise logic
    ps_bool clockwise = True;

    float factor_p1p2 = tangent / p1p2_length;
    ps_point t_p1p2 = {(tp->x + factor_p1p2 * p1p2.x), (tp->y + factor_p1p2 * p1p2.y)};
    ps_point orth_p1p2 = {(t_p1p2.x - p.x),(t_p1p2.y - p.y)};
    float orth_p1p2_length = sqrtf(orth_p1p2.x * orth_p1p2.x + orth_p1p2.y * orth_p1p2.y);
    float ea = acosf(orth_p1p2.x / orth_p1p2_length);
    if (orth_p1p2.y < 0)
        ea = 2 * PI - ea;
    if ((sa > ea) && ((sa - ea) < PI))
        clockwise = False;
    if ((sa < ea) && ((ea - sa) > PI))
        clockwise = False;

    ps_path_line_to(path, &t_p1p0);

    ps_path_add_arc(path, &p, r, sa, ea, clockwise);
    global_status = STATUS_SUCCEED;
}
コード例 #8
0
void PICAPI ps_draw_text(ps_context* ctx, const ps_rect* area, const void* text, unsigned int len,
                                                                ps_draw_text_type type, ps_text_align align)
{
    if (!picasso::is_valid_system_device()) {
        global_status = STATUS_DEVICE_ERROR;
        return;
    }

    if (!ctx || !area || !text || !len) {
        global_status = STATUS_INVALID_ARGUMENT;
        return;
    }

    scalar x = FLT_TO_SCALAR(area->x);
    scalar y = FLT_TO_SCALAR(area->y);

    picasso::graphic_path text_path;

    ps_bool text_antialias = ctx->font_antialias;
    ctx->font_antialias = True;
    if (create_device_font(ctx)) {

        // align layout
        scalar w = 0, h = 0;
        const picasso::glyph* glyph_test = 0;

        if (ctx->state->font->desc.charset() == CHARSET_ANSI) {
            const char* p = (const char*)text;
            glyph_test = ctx->fonts->current_font()->get_glyph(*p);
        } else {
            const ps_uchar16* p = (const ps_uchar16*)text;
            glyph_test = ctx->fonts->current_font()->get_glyph(*p);
        }

        if (glyph_test) {
            w = glyph_test->advance_x;
            h = glyph_test->height; //Note: advance_y always 0.
        }

        w *= len; //FIXME: estimate!

        if (align & TEXT_ALIGN_LEFT)
            x = FLT_TO_SCALAR(area->x);
        else if (align & TEXT_ALIGN_RIGHT)
            x = FLT_TO_SCALAR(area->x + (area->w - w));
        else
            x = FLT_TO_SCALAR(area->x + (area->w - w)/2);

        if (align & TEXT_ALIGN_TOP) {
            y = FLT_TO_SCALAR(area->y);
            y += ctx->fonts->current_font()->ascent();
        } else if (align & TEXT_ALIGN_BOTTOM) {
            y = FLT_TO_SCALAR(area->y + (area->h - SCALAR_TO_FLT(h)));
            y -= ctx->fonts->current_font()->descent();
        } else {
            y = FLT_TO_SCALAR(area->y + (area->h - SCALAR_TO_FLT(h))/2);
            y += (ctx->fonts->current_font()->ascent() - ctx->fonts->current_font()->descent())/2;
        }

        // draw the text
        if (ctx->state->font->desc.charset() == CHARSET_ANSI) {
            const char* p = (const char*)text;
            while (*p && len) {
                register char c = *p;
                const picasso::glyph* glyph = ctx->fonts->current_font()->get_glyph(c);
                if (glyph) {
                    if (ctx->font_kerning)
                        ctx->fonts->current_font()->add_kerning(&x, &y);
                    if (ctx->fonts->current_font()->generate_raster(glyph, x, y))
                        _add_glyph_to_path(ctx, text_path);

                    x += glyph->advance_x;
                    y += glyph->advance_y;
                }
                len--;
                p++;
            }
        } else {
            const ps_uchar16* p = (const ps_uchar16*)text;
            while (*p && len) {
                register ps_uchar16 c = *p;
                const picasso::glyph* glyph = ctx->fonts->current_font()->get_glyph(c);
                if (glyph) {
                    if (ctx->font_kerning)
                        ctx->fonts->current_font()->add_kerning(&x, &y);
                    if (ctx->fonts->current_font()->generate_raster(glyph, x, y))
                        _add_glyph_to_path(ctx, text_path);

                    x += glyph->advance_x;
                    y += glyph->advance_y;
                }
                len--;
                p++;
            }
        }
    }

    text_path.close_polygon();
    ctx->font_antialias = text_antialias;

    //store the old color
    picasso::rgba bc = ctx->state->brush.color;
    picasso::rgba pc = ctx->state->pen.color;

    ctx->state->brush.color = ctx->state->font_fcolor;
    ctx->state->pen.color = ctx->state->font_scolor;

    switch (type) {
        case DRAW_TEXT_FILL:
            ctx->canvas->p->render_shadow(ctx->state, text_path, true, false);
            ctx->canvas->p->render_fill(ctx->state, ctx->raster, text_path);
            ctx->canvas->p->render_blur(ctx->state);
            break;
        case DRAW_TEXT_STROKE:
            ctx->canvas->p->render_shadow(ctx->state, text_path, false, true);
            ctx->canvas->p->render_stroke(ctx->state, ctx->raster, text_path);
            ctx->canvas->p->render_blur(ctx->state);
            break;
        case DRAW_TEXT_BOTH:
            ctx->canvas->p->render_shadow(ctx->state, text_path, true, true);
            ctx->canvas->p->render_paint(ctx->state, ctx->raster, text_path);
            ctx->canvas->p->render_blur(ctx->state);
            break;
    }

    ctx->state->brush.color = bc;
    ctx->state->pen.color = pc;
    ctx->raster.reset();
    global_status = STATUS_SUCCEED;
}