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; }
void SelectTranslation(const WCHAR *exePath=NULL) { LANGID langId = GetUserDefaultUILanguage(); int idx = GetLanguageIndex(langId); if (-1 == idx) { // try a neutral language if the specific sublanguage isn't available langId = MAKELANGID(PRIMARYLANGID(langId), SUBLANG_NEUTRAL); idx = GetLanguageIndex(langId); } if (-1 != idx) { gTranslationIdx = idx; plogf("sp: Detected language %s (%d)", gLanguages[idx / gTranslationsCount], idx); } // try to extract the language used by SumatraPDF ScopedMem<WCHAR> path; if (exePath) { path.Set(path::GetDir(exePath)); path.Set(path::Join(path, PREFS_FILE_NAME)); } if (!file::Exists(path)) { path.Set(GetSpecialFolder(CSIDL_APPDATA)); path.Set(path::Join(path, L"SumatraPDF\\" PREFS_FILE_NAME)); } if (!file::Exists(path)) return; plogf("sp: Found preferences at %S", path); ScopedMem<char> prefsData(file::ReadAll(path, NULL)); SquareTree sqt(prefsData); const char *langCode = sqt.root ? sqt.root->GetValue("UiLanguage") : NULL; if (langCode) { plogf("sp: UiLanguage from preferences: %s", langCode); for (int i = 0; gLanguages[i]; i++) { if (str::Eq(gLanguages[i], langCode)) { gTranslationIdx = i * gTranslationsCount; break; } } } }
int main(int argc, char **argv) { if (argc != 3) { printf("usage: render_tree <input> <output>\n"); exit(1); } int pt_count; FILE *f = fopen(argv[1], "r"); if (!f) { printf("error: could not open points file: %s\n", argv[1]); exit(1); } fscanf(f, "%d", &pt_count); if (pt_count < 0) { printf("error: invalid point count %d\n", pt_count); exit(1); } Point *pts = new Point[pt_count]; double x, y; for (int i = 0; i < pt_count; ++i) { fscanf(f, "%lf, %lf", &x, &y); pts[i][0] = x; pts[i][1] = y; } fclose(f); SkipQuadtree<Point> sqt(2, pts, pt_count); printf("completed building tree...\n "); f = fopen(argv[2], "w"); if (!f) { printf("error: could not open output file: %s\n", argv[2]); exit(1); } fprintf(f, "%%%%!PS-Adobe-2.0\n"); fprintf(f, "%%%%Pages: %d\n", sqt.levels.size()); fprintf(f, "/page-begin {\n"); fprintf(f, "gsave\n"); fprintf(f, "} def\n"); fprintf(f, "/page-end {\n"); fprintf(f, " grestore\n"); fprintf(f, " showpage\n"); fprintf(f, "} def\n"); //define point function for later fprintf(f, "/draw-point {\n"); fprintf(f, " /y exch def\n"); fprintf(f, " /x exch def\n"); fprintf(f, " gsave\n"); fprintf(f, " newpath\n"); fprintf(f, " 0.5 0.5 0.7 setrgbcolor\n"); fprintf(f, " x y 2 0 360 arc\n"); fprintf(f, " closepath\n"); fprintf(f, " fill\n"); fprintf(f, " newpath\n"); fprintf(f, " 0.4 setgray\n"); fprintf(f, " x y 2 0 360 arc\n"); fprintf(f, " closepath\n"); fprintf(f, " stroke\n"); fprintf(f, " grestore\n"); fprintf(f, "} def\n"); //node bounding box fprintf(f, "/node-bounds {\n"); fprintf(f, " /y2 exch def\n"); fprintf(f, " /y1 exch def\n"); fprintf(f, " /x2 exch def\n"); fprintf(f, " /x1 exch def\n"); fprintf(f, " gsave\n"); fprintf(f, " 0.7 setgray\n"); fprintf(f, " newpath\n"); fprintf(f, " x2 y2 moveto\n"); fprintf(f, " x1 y2 lineto\n"); fprintf(f, " x1 y1 lineto\n"); fprintf(f, " x2 y1 lineto\n"); fprintf(f, " closepath\n"); fprintf(f, " stroke \n"); fprintf(f, " grestore\n"); fprintf(f, "} def\n"); for (size_t i = 0; i < sqt.levels.size(); ++i) { fprintf(f, "%%%%Page: %d\n", i + 1); fprintf(f, "page-begin\n"); render_tree(f, sqt.levels[i], 0); fprintf(f, "page-end\n"); } fclose(f); }