Exemplo n.º 1
0
static Vec<PageAnnotation> *ParseFileModifications(const char *data)
{
    if (!data)
        return NULL;

    SquareTree sqt(data);
    if (!sqt.root || sqt.root->data.Count() == 0)
        return NULL;
    SquareTreeNode::DataItem& item = sqt.root->data.At(0);
    if (!item.isChild || !str::EqI(item.key, "@meta"))
        return NULL;
    if (!item.value.child->GetValue("version")) {
        // don't check the version value - rather extend the format
        // in a way to ensure backwards compatibility
        return NULL;
    }

    Vec<PageAnnotation> *list = new Vec<PageAnnotation>();
    for (SquareTreeNode::DataItem *i = sqt.root->data.IterStart(); i; i = sqt.root->data.IterNext()) {
        PageAnnotType type = str::EqI(i->key, "highlight") ? Annot_Highlight :
                             str::EqI(i->key, "underline") ? Annot_Underline :
                             str::EqI(i->key, "strikeout") ? Annot_StrikeOut :
                             str::EqI(i->key, "squiggly")  ? Annot_Squiggly  :
                             Annot_None;
        CrashIf(!i->isChild);
        if (Annot_None == type || !i->isChild)
            continue;

        int pageNo;
        geomutil::RectT<float> rect;
        PageAnnotation::Color color;
        float opacity;
        int r, g, b;

        SquareTreeNode *node = i->value.child;
        const char *value = node->GetValue("page");
        if (!value || !str::Parse(value, "%d%$", &pageNo))
            continue;
        value = node->GetValue("rect");
        if (!value || !str::Parse(value, "%f %f %f %f%$", &rect.x, &rect.y, &rect.dx, &rect.dy))
            continue;
        value = node->GetValue("color");
        if (!value || !str::Parse(value, "#%2x%2x%2x%$", &r, &g, &b))
            continue;
        value = node->GetValue("opacity");
        if (!value || !str::Parse(value, "%f%$", &opacity))
            opacity = 1.0f;
        color = PageAnnotation::Color((uint8_t)r, (uint8_t)g, (uint8_t)b, (uint8_t)(255 * opacity));
        list->Append(PageAnnotation(type, pageNo, rect.Convert<double>(), color));
    }

    return list;
}
Exemplo n.º 2
0
Vec<PageAnnotation> *LoadFileModifications(const WCHAR *filepath)
{
    ScopedMem<WCHAR> modificationsPath(str::Join(filepath, SMX_FILE_EXT));
    size_t len;
    ScopedMem<char> data(file::ReadAll(modificationsPath, &len));
    if (!data)
        return NULL;

    CssPullParser parser(data, len);
    if (!parser.NextRule())
        return NULL;
    const CssSelector *sel = parser.NextSelector();
    if (!sel || !IsSelector(sel, "@meta") || parser.NextSelector())
        return NULL;
    const CssProperty *prop = parser.NextProperty();
    if (!prop || Css_Version != prop->type || !str::Parse(prop->s, prop->sLen, SMX_CURR_VERSION "%$"))
        return NULL;

    Vec<PageAnnotation> *list = new Vec<PageAnnotation>();
    while (parser.NextRule()) {
        sel = parser.NextSelector();
        if (!sel)
            continue;
        PageAnnotType type = IsSelector(sel, "highlight") ? Annot_Highlight :
                             IsSelector(sel, "underline") ? Annot_Underline :
                             IsSelector(sel, "strikeout") ? Annot_StrikeOut :
                             IsSelector(sel, "squiggly")  ? Annot_Squiggly  :
                             Annot_None;
        if (Annot_None == type || parser.NextSelector())
            continue;

        int pageNo = 0;
        RectT<float> rect;
        PageAnnotation::Color color;
        while ((prop = parser.NextProperty())) {
            switch (prop->type) {
            case Css_Page:
                if (!str::Parse(prop->s, prop->sLen, "%d%$", &pageNo))
                    pageNo = 0;
                break;
            case Css_Rect:
                if (!str::Parse(prop->s, prop->sLen, "%f %f %f %f%$",
                                &rect.x, &rect.y, &rect.dx, &rect.dy))
                    rect = RectT<float>();
                break;
            case Css_Color:
                int r, g, b, a;
                if (str::Parse(prop->s, prop->sLen, "#%2x%2x%2x%2x%$", &a, &r, &g, &b))
                    color = PageAnnotation::Color(r, g, b, a);
                else if (str::Parse(prop->s, prop->sLen, "#%2x%2x%2x%$", &r, &g, &b))
                    color = PageAnnotation::Color(r, g, b);
                break;
            }
        }
        if (pageNo <= 0 || rect.IsEmpty())
            continue;
        list->Append(PageAnnotation(type, pageNo, rect.Convert<double>(), color));
    }

    return list;
}