Esempio n. 1
0
int RenderCurses::render(Pagination* pagination, unsigned int pageNum, bool doBlit)
{
    clc::Log::info("ocher.render.ncurses", "render page %u %u", pageNum, doBlit);
    m_x = 0;
    m_y = 0;
    if (m_height) {
        wclear(m_scr);
    }

    unsigned int layoutOffset;
    unsigned int strOffset;
    if (!pageNum) {
        layoutOffset = 0;
        strOffset = 0;
    } else if (! pagination->get(pageNum-1, &layoutOffset, &strOffset)) {
        // Previous page not already paginated?
        // Perhaps at end of book?
        clc::Log::error("ocher.renderer.ncurses", "page %u not found", pageNum);
        return -1;
    }

    const unsigned int N = m_layout.size();
    const char *raw = m_layout.data();
    ASSERT(layoutOffset < N);
    for (unsigned int i = layoutOffset; i < N; ) {
        ASSERT(i+2 <= N);
        uint16_t code = *(uint16_t*)(raw+i);
        i += 2;

        unsigned int opType = (code>>12)&0xf;
        unsigned int op = (code>>8)&0xf;
        unsigned int arg = code & 0xff;
        switch (opType) {
            case Layout::OpPushTextAttr:
                clc::Log::debug("ocher.render.ncurses", "OpPushTextAttr");
                switch (op) {
                    case Layout::AttrBold:
                        pushAttrs();
                        a[ai].b = 1;
                        if (doBlit)
                            applyAttrs(1);
                        break;
                    case Layout::AttrUnderline:
                        pushAttrs();
                        a[ai].ul = 1;
                        if (doBlit)
                            applyAttrs(1);
                        break;
                    case Layout::AttrItalics:
                        pushAttrs();
                        a[ai].em = 1;
                        if (doBlit)
                            applyAttrs(1);
                        break;
                    case Layout::AttrSizeRel:
                        pushAttrs();
                        break;
                    case Layout::AttrSizeAbs:
                        pushAttrs();
                        break;
                    default:
                        clc::Log::error("ocher.render.ncurses", "unknown OpPushTextAttr");
                        ASSERT(0);
                        break;
                }
                break;
            case Layout::OpPushLineAttr:
                clc::Log::debug("ocher.render.ncurses", "OpPushLineAttr");
                switch (op) {
                    case Layout::LineJustifyLeft:
                        break;
                    case Layout::LineJustifyCenter:
                        break;
                    case Layout::LineJustifyFull:
                        break;
                    case Layout::LineJustifyRight:
                        break;
                    default:
                        clc::Log::error("ocher.render.ncurses", "unknown OpPushLineAttr");
                        ASSERT(0);
                        break;
                }
                break;
            case Layout::OpCmd:
                switch (op) {
                    case Layout::CmdPopAttr:
                        clc::Log::trace("ocher.render.ncurses", "OpCmd CmdPopAttr");
                        if (arg == 0)
                            arg = 1;
                        while (arg--)
                            popAttrs();
                        break;
                    case Layout::CmdOutputStr: {
                        clc::Log::trace("ocher.render.ncurses", "OpCmd CmdOutputStr");
                        ASSERT(i + sizeof(clc::Buffer*) <= N);
                        clc::Buffer *str = *(clc::Buffer**)(raw+i);
                        ASSERT(strOffset <= str->size());
                        int breakOffset = outputWrapped(str, strOffset, doBlit);
                        strOffset = 0;
                        if (breakOffset >= 0) {
                            pagination->set(pageNum, i-2, breakOffset);
                            if (doBlit) {
                                refreshCDKScreen(m_screen);
                            }
                            clc::Log::debug("ocher.renderer.ncurses", "page %u break", pageNum);
                            return 0;
                        }
                        i += sizeof(clc::Buffer*);
                        break;
                    }
                    case Layout::CmdForcePage:
                        clc::Log::trace("ocher.render.ncurses", "OpCmd CmdForcePage");
                        break;
                    default:
                        clc::Log::error("ocher.render.ncurses", "unknown OpCmd");
                        ASSERT(0);
                        break;
                }
                break;
            case Layout::OpSpacing:
                break;
            case Layout::OpImage:
                break;
            default:
                clc::Log::error("ocher.render.ncurses", "unknown op type");
                ASSERT(0);
                break;

        };
    }
    clc::Log::debug("ocher.renderer.ncurses", "page %u done", pageNum);
    refreshCDKScreen(m_screen);
    return 1;
}
Esempio n. 2
0
// TODO:  speed stats
// TODO:  faster: max_advance_width
int RenderFb::render(Pagination* pagination, unsigned int pageNum, bool doBlit)
{
    clc::Log::info("ocher.renderer.fb", "render page %u %u", pageNum, doBlit);
    m_penX = settings.marginLeft;
    m_penY = settings.marginTop + g_ft->getAscender();
    if (doBlit)
        m_fb->clear();

    unsigned int layoutOffset;
    unsigned int strOffset;
    if (!pageNum) {
        layoutOffset = 0;
        strOffset = 0;
    } else if (! pagination->get(pageNum-1, &layoutOffset, &strOffset)) {
        // Previous page not already paginated?
        // Perhaps at end of book?
        clc::Log::error("ocher.renderer.fb", "page %u not found", pageNum);
        return -1;
    }

    const unsigned int N = m_layout.size();
    const char *raw = m_layout.data();
    Rect fullPage(0, 0, m_fb->width(), m_fb->height());
    ASSERT(layoutOffset < N);
    for (unsigned int i = layoutOffset; i < N; ) {
        ASSERT(i+2 <= N);
        uint16_t code = *(uint16_t*)(raw+i);
        i += 2;

        unsigned int opType = (code>>12)&0xf;
        unsigned int op = (code>>8)&0xf;
        unsigned int arg = code & 0xff;
        switch (opType) {
            case Layout::OpPushTextAttr:
                clc::Log::trace("ocher.render.fb", "OpPushTextAttr");
                switch (op) {
                    case Layout::AttrBold:
                        pushAttrs();
                        a[ai].b = 1;
                        break;
                    case Layout::AttrUnderline:
                        pushAttrs();
                        a[ai].ul = 1;
                        break;
                    case Layout::AttrItalics:
                        pushAttrs();
                        a[ai].em = 1;
                        break;
                    case Layout::AttrSizeRel:
                        pushAttrs();
                        clc::Log::debug("ocher.render.fb", "font rel %d", (int)arg);
                        a[ai].pts += (int)arg;
                        m_ft->setSize(a[ai].pts);
                        break;
                    case Layout::AttrSizeAbs:
                        pushAttrs();
                        clc::Log::debug("ocher.render.fb", "font abs %d", (int)arg);
                        a[ai].pts = (int)arg;
                        m_ft->setSize(a[ai].pts);
                        break;
                    default:
                        clc::Log::error("ocher.render.fb", "unknown OpPushTextAttr");
                        ASSERT(0);
                        break;
                }
                break;
            case Layout::OpPushLineAttr:
                clc::Log::debug("ocher.render.fb", "OpPushLineAttr");
                switch (op) {
                    case Layout::LineJustifyLeft:
                        break;
                    case Layout::LineJustifyCenter:
                        break;
                    case Layout::LineJustifyFull:
                        break;
                    case Layout::LineJustifyRight:
                        break;
                    default:
                        clc::Log::error("ocher.render.fb", "unknown OpPushLineAttr");
                        ASSERT(0);
                        break;
                }
                break;
            case Layout::OpCmd:
                switch (op) {
                    case Layout::CmdPopAttr:
                        clc::Log::trace("ocher.render.fb", "OpCmd CmdPopAttr");
                        if (arg == 0)
                            arg = 1;
                        while (arg--)
                            popAttrs();
                        // TODO:  only reset what has changed
                        clc::Log::debug("ocher.render.fb", "font pop %d", a[ai].pts);
                        m_ft->setSize(a[ai].pts);
                        break;
                    case Layout::CmdOutputStr: {
                        clc::Log::trace("ocher.render.fb", "OpCmd CmdOutputStr");
                        ASSERT(i + sizeof(clc::Buffer*) <= N);
                        clc::Buffer *str = *(clc::Buffer**)(raw+i);
                        ASSERT(strOffset <= str->size());
                        int breakOffset = outputWrapped(str, strOffset, doBlit);
                        strOffset = 0;
                        if (breakOffset >= 0) {
                            pagination->set(pageNum, i-2, breakOffset);
                            clc::Log::debug("ocher.renderer.fb", "page %u break", pageNum);
                            if (doBlit)
                                m_fb->update(&fullPage, false);
                            return 0;
                        }
                        i += sizeof(clc::Buffer*);
                        break;
                    }
                    case Layout::CmdForcePage:
                        clc::Log::trace("ocher.render.fb", "OpCmd CmdForcePage");
                        break;
                    default:
                        clc::Log::error("ocher.render.fb", "unknown OpCmd");
                        ASSERT(0);
                        break;
                }
                break;
            case Layout::OpSpacing:
                break;
            case Layout::OpImage:
                break;
            default:
                clc::Log::error("ocher.render.fb", "unknown op type");
                ASSERT(0);
                break;
        };
    }
    clc::Log::debug("ocher.renderer.fb", "page %u done", pageNum);
    if (doBlit)
        m_fb->update(&fullPage, false);
    return 1;
}
Esempio n. 3
0
int RenderFb::render(unsigned int pageNum, bool doBlit)
{
    m_penX = settings.marginLeft;
    m_penY = settings.marginTop;
    m_fb->clear();

    unsigned int layoutOffset;
    unsigned int strOffset;
    if (!pageNum) {
        layoutOffset = 0;
        strOffset = 0;
    } else if (! m_pagination.get(pageNum-1, &layoutOffset, &strOffset)) {
        // Previous page not already paginated?
        // Perhaps at end of book?
        return -1;
    }

    const unsigned int N = m_layout.size();
    const char *raw = m_layout.data();
    ASSERT(layoutOffset < N);
    for (unsigned int i = layoutOffset; i < N; ) {
        ASSERT(i+2 <= N);
        uint16_t code = *(uint16_t*)(raw+i);
        i += 2;

        unsigned int opType = (code>>12)&0xf;
        unsigned int op = (code>>8)&0xf;
        unsigned int arg = code & 0xff;
        switch (opType) {
            case Layout::OpPushTextAttr:
                clc::Log::debug("ocher.render.fb", "OpPushTextAttr");
                switch (op) {
                    case Layout::AttrBold:
                        pushAttrs();
                        a[ai].b = 1;
                        break;
                    case Layout::AttrUnderline:
                        pushAttrs();
                        a[ai].ul = 1;
                        break;
                    case Layout::AttrItalics:
                        pushAttrs();
                        a[ai].em = 1;
                        break;
                    case Layout::AttrSizeRel:
                        pushAttrs();
                        break;
                    case Layout::AttrSizeAbs:
                        pushAttrs();
                        break;
                    default:
                        clc::Log::error("ocher.render.fb", "unknown OpPushTextAttr");
                        ASSERT(0);
                        break;
                }
                break;
            case Layout::OpPushLineAttr:
                clc::Log::debug("ocher.render.fb", "OpPushLineAttr");
                switch (op) {
                    case Layout::LineJustifyLeft:
                        break;
                    case Layout::LineJustifyCenter:
                        break;
                    case Layout::LineJustifyFull:
                        break;
                    case Layout::LineJustifyRight:
                        break;
                    default:
                        clc::Log::error("ocher.render.fb", "unknown OpPushLineAttr");
                        ASSERT(0);
                        break;
                }
                break;
            case Layout::OpCmd:
                switch (op) {
                    case Layout::CmdPopAttr:
                        clc::Log::debug("ocher.render.fb", "OpCmd CmdPopAttr");
                        if (arg == 0)
                            arg = 1;
                        while (arg--)
                            popAttrs();
                        break;
                    case Layout::CmdOutputStr: {
                        clc::Log::debug("ocher.render.fb", "OpCmd CmdOutputStr");
                        ASSERT(i + sizeof(clc::Buffer*) <= N);
                        clc::Buffer *str = *(clc::Buffer**)(raw+i);
                        ASSERT(strOffset <= str->size());
                        int breakOffset = outputWrapped(str, strOffset, doBlit);
                        strOffset = 0;
                        if (breakOffset >= 0) {
                            if (!doBlit) {
                                m_pagination.set(pageNum, i-2, breakOffset);
                            }
                            m_fb->update(0, 0, m_fb->width(), m_fb->height(), false); // DDD
                            return 0;
                        }
                        i += sizeof(clc::Buffer*);
                        break;
                    }
                    case Layout::CmdForcePage:
                        clc::Log::debug("ocher.render.fb", "OpCmd CmdForcePage");
                        break;
                    default:
                        clc::Log::error("ocher.render.fb", "unknown OpCmd");
                        ASSERT(0);
                        break;
                }
                break;
            case Layout::OpSpacing:
                break;
            case Layout::OpImage:
                break;
            default:
                clc::Log::error("ocher.render.fb", "unknown op type");
                ASSERT(0);
                break;
        };
    }
    m_fb->update(0, 0, m_fb->width(), m_fb->height(), false); // DDD
    return 1;
}