bool PdfExport::writePagesindex() { XOJ_CHECK_TYPE(PdfExport); this->xref->setXref(1, this->writer->getDataCount()); //Pages root this->writer->write("1 0 obj\n"); this->writer->write("<</Type /Pages\n"); this->writer->write("/Kids ["); int pageCount = 0; for (GList* l = this->pageIds; l != NULL; l = l->next) { int id = *((int*) l->data); this->writer->writef("%i 0 R ", id); pageCount++; } this->writer->write("]\n"); this->writer->writef("/Count %i\n", pageCount); PageRef page = doc->getPage(0); this->writer->writef("/MediaBox [0 0 %.2F %.2F]\n", page->getWidth(), page->getHeight()); this->writer->write(">>\n"); this->writer->write("endobj\n"); return true; }
/** * Draw the full page, usually you would like to call this method * @param page The page to draw * @param cr Draw to thgis context * @param dontRenderEditingStroke false to draw currently drawing stroke * @param hideBackground true to hide the background */ void DocumentView::drawPage(PageRef page, cairo_t* cr, bool dontRenderEditingStroke, bool hideBackground) { XOJ_CHECK_TYPE(DocumentView); initDrawing(page, cr, dontRenderEditingStroke); bool backgroundVisible = page->isLayerVisible(0); if (!hideBackground && backgroundVisible) { drawBackground(); } if (!backgroundVisible) { drawTransparentBackgroundPattern(); } int layer = 0; for (Layer* l : *page->getLayers()) { if (!page->isLayerVisible(l)) { continue; } drawLayer(cr, l); layer++; } finializeDrawing(); }
/** * Drawing first step * @param page The page to draw * @param cr Draw to thgis context * @param dontRenderEditingStroke false to draw currently drawing stroke */ void DocumentView::initDrawing(PageRef page, cairo_t* cr, bool dontRenderEditingStroke) { XOJ_CHECK_TYPE(DocumentView); this->cr = cr; this->page = page; this->width = page->getWidth(); this->height = page->getHeight(); this->dontRenderEditingStroke = dontRenderEditingStroke; }
void LoadHandler::parseBgPixmap() { XOJ_CHECK_TYPE(LoadHandler); const char* domain = getAttrib("domain"); const char* filename = getAttrib("filename"); String fileToLoad; bool loadFile = false; if (!strcmp(domain, "absolute")) { fileToLoad = filename; loadFile = true; } else if (!strcmp(domain, "attach")) { fileToLoad = this->filename; fileToLoad += "."; fileToLoad += filename; loadFile = true; } if (loadFile) { GError* error = NULL; BackgroundImage img; img.loadFile(fileToLoad, &error); if (error) { error(_("could not read image: %s, Error message: %s"), fileToLoad.c_str(), error->message); g_error_free(error); } this->page->setBackgroundImage(img); } else if (!strcmp(domain, "clone")) { PageRef p = doc.getPage(atoi(filename)); if (p.isValid()) { this->page->setBackgroundImage(p->getBackgroundImage()); } } else { error(_("Unknown pixmap::domain type: %s"), domain); } this->page->setBackgroundType(BACKGROUND_TYPE_IMAGE); }
void MainWindow::updateLayerCombobox() { XOJ_CHECK_TYPE(MainWindow); PageRef p = control->getCurrentPage(); int layer = 0; if (p) { layer = p.getSelectedLayerId(); toolbar->setLayerCount(p.getLayerCount(), layer); } else { toolbar->setLayerCount(-1, -1); } control->fireEnableAction(ACTION_DELETE_LAYER, layer > 0); }
void SidebarIndexPage::askInsertPdfPage(size_t pdfPage) { XOJ_CHECK_TYPE(SidebarIndexPage); GtkWidget* dialog = gtk_message_dialog_new((GtkWindow*) *control->getWindow(), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, "%s", FC(_F("Your current document does not contain PDF Page no {1}\n" "Would you like to insert this page?\n\n" "Tip: You can select Journal → Paper Background → PDF Background " "to insert a PDF page.") % (pdfPage + 1))); gtk_dialog_add_button(GTK_DIALOG(dialog), "Cancel", 1); gtk_dialog_add_button(GTK_DIALOG(dialog), "Insert after", 2); gtk_dialog_add_button(GTK_DIALOG(dialog), "Insert at end", 3); gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(this->control->getWindow()->getWindow())); int res = gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); if (res == 1) { return; } int position = 0; Document* doc = control->getDocument(); if (res == 2) { position = control->getCurrentPageNo() + 1; } else if (res == 3) { position = doc->getPageCount(); } doc->lock(); XojPopplerPage* pdf = doc->getPdfPage(pdfPage); doc->unlock(); if (pdf) { PageRef page = new XojPage(pdf->getWidth(), pdf->getHeight()); page->setBackgroundPdfPageNr(pdfPage); control->insertPage(page, position); } }
/** * Finishes all pending changes, move the elements, scale the elements and add * them to new layer if any or to the old if no new layer */ void EditSelection::finalizeSelection() { XOJ_CHECK_TYPE(EditSelection); PageView * v = getBestMatchingPageView(); if (v == NULL) { this->view->getXournal()->deleteSelection(this); } else { PageRef page = this->view->getPage(); Layer * layer = page.getSelectedLayer(); this->contents->finalizeSelection(this->x, this->y, this->width, this->height, this->aspectRatio, layer, page, this->view, this->undo); this->view->rerenderRect(this->x, this->y, this->width, this->height); // This is needed if the selection not was 100% on a page this->view->getXournal()->repaintSelection(true); } }
bool ImageHandler::insertImage(GFile * file, double x, double y) { XOJ_CHECK_TYPE(ImageHandler); GError * err = NULL; GFileInputStream * in = g_file_read(file, NULL, &err); g_object_unref(file); GdkPixbuf * pixbuf = NULL; if (!err) { pixbuf = gdk_pixbuf_new_from_stream(G_INPUT_STREAM(in), NULL, &err); g_input_stream_close(G_INPUT_STREAM(in), NULL, NULL); } else { GtkWidget * dialog = gtk_message_dialog_new((GtkWindow*) *control->getWindow(), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("This image could not be loaded. Error message: %s"), err->message); gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(this->control->getWindow()->getWindow())); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); g_error_free(err); return false; } Image * img = new Image(); img->setX(x); img->setY(y); img->setImage(pixbuf); int width = gdk_pixbuf_get_width(pixbuf); int height = gdk_pixbuf_get_height(pixbuf); gdk_pixbuf_unref(pixbuf); double zoom = 1; PageRef page = view->getPage(); if (x + width > page.getWidth() || y + height > page.getHeight()) { double maxZoomX = (page.getWidth() - x) / width; double maxZoomY = (page.getHeight() - y) / height; if (maxZoomX < maxZoomY) { zoom = maxZoomX; } else { zoom = maxZoomY; } } img->setWidth(width * zoom); img->setHeight(height * zoom); page.getSelectedLayer()->addElement(img); InsertUndoAction * insertUndo = new InsertUndoAction(page, page.getSelectedLayer(), img, view); control->getUndoRedoHandler()->addUndoAction(insertUndo); view->rerenderElement(img); return true; }
void InputHandler::onButtonReleaseEvent(GdkEventButton * event, PageRef page) { XOJ_CHECK_TYPE(InputHandler); if (!this->tmpStroke) { return; } // Backward compatibility and also easier to handle for me;-) // I cannot draw a line with one point, to draw a visible line I need two points, // twice the same Point is also OK if (this->tmpStroke->getPointCount() == 1) { ArrayIterator<Point> it = this->tmpStroke->pointIterator(); if (it.hasNext()) { this->tmpStroke->addPoint(it.next()); } // No pressure sensitivity this->tmpStroke->clearPressure(); } this->tmpStroke->freeUnusedPointItems(); if (page.getSelectedLayerId() < 1) { // This creates a layer if none exists page.getSelectedLayer(); page.setSelectedLayerId(1); xournal->getControl()->getWindow()->updateLayerCombobox(); } Layer * layer = page.getSelectedLayer(); UndoRedoHandler * undo = xournal->getControl()->getUndoRedoHandler(); undo->addUndoAction(new InsertUndoAction(page, layer, this->tmpStroke, this->redrawable)); ToolHandler * h = xournal->getControl()->getToolHandler(); if (h->isShapeRecognizer()) { if (this->reco == NULL) { this->reco = new ShapeRecognizer(); } ShapeRecognizerResult * result = this->reco->recognizePatterns(this->tmpStroke); if (result != NULL) { UndoRedoHandler * undo = xournal->getControl()->getUndoRedoHandler(); Stroke * recognized = result->getRecognized(); RecognizerUndoAction * recognizerUndo = new RecognizerUndoAction(page, this->redrawable, layer, this->tmpStroke, recognized); undo->addUndoAction(recognizerUndo); layer->addElement(result->getRecognized()); Range range(recognized->getX(), recognized->getY()); range.addPoint(recognized->getX() + recognized->getElementWidth(), recognized->getY() + recognized->getElementHeight()); range.addPoint(this->tmpStroke->getX(), this->tmpStroke->getY()); range.addPoint(this->tmpStroke->getX() + this->tmpStroke->getElementWidth(), this->tmpStroke->getY() + this->tmpStroke->getElementHeight()); ListIterator<Stroke *> l = result->getSources(); while (l.hasNext()) { Stroke * s = l.next(); layer->removeElement(s, false); recognizerUndo->addSourceElement(s); range.addPoint(s->getX(), s->getY()); range.addPoint(s->getX() + s->getElementWidth(), s->getY() + s->getElementHeight()); } this->redrawable->rerenderRange(range); // delete the result object, this is not needed anymore, the stroke are not deleted with this delete result; } else { layer->addElement(this->tmpStroke); this->redrawable->rerenderElement(this->tmpStroke); } } else { layer->addElement(this->tmpStroke); this->redrawable->rerenderElement(this->tmpStroke); } this->tmpStroke = NULL; if (currentInputDevice == event->device) { currentInputDevice = NULL; INPUTDBG("currentInputDevice = NULL\n", 0); } this->tmpStrokeDrawElem = 0; }
bool PdfExport::writePage(int pageNr) { XOJ_CHECK_TYPE(PdfExport); PageRef page = doc->getPage(pageNr); if (!page) { return false; } int* pageId = (int*) g_malloc(sizeof(int)); *pageId = this->writer->getObjectId(); this->pageIds = g_list_append(this->pageIds, pageId); this->writer->writeObj(); this->writer->write("<</Type /Page\n"); this->writer->write("/Parent 1 0 R\n"); this->writer->writef("/MediaBox [0 0 %.2F %.2F]\n", page->getWidth(), page->getHeight()); this->writer->write("/Resources 2 0 R\n"); // if (isset($this->PageLinks[$n])) { // //Links // $annots = '/Annots ['; //foreach ($this->PageLinks[$n] as $pl) // { // $rect=sprintf('%.2F %.2F %.2F %.2F',$pl[0],$pl[1],$pl[0]+$pl[2],$pl[1]-$pl[3]); // $annots.='<</Type /Annot /Subtype /Link /Rect ['.$rect.'] /Border [0 0 0] '; // if(is_string($pl[4])) // $annots.='/A <</S /URI /URI '.$this->_textstring($pl[4]).'>>>>'; // else // { // $l=$this->links[$pl[4]]; // $h=isset($this->PageSizes[$l[0]]) ? $this->PageSizes[$l[0]][1] : $hPt; // $annots.=sprintf('/Dest [%d 0 R /XYZ 0 %.2F null]>>',1+2*$l[0],$h-$l[1]*$this->k); // } // } // $this->_out($annots.']'); //} this->writer->writef("/Contents %i 0 R>>\n", this->writer->getObjectId()); this->writer->write("endobj\n"); //Page content this->writer->writeObj(); this->writer->startStream(); addPopplerDocument(doc->getPdfDocument()); currentPdfDoc = doc->getPdfDocument(); if (page->getBackgroundType() == BACKGROUND_TYPE_PDF) { XojPopplerPage* pdf = doc->getPdfPage(page->getPdfPageNr()); if (!addPopplerPage(pdf, currentPdfDoc)) { return false; } } currentPdfDoc = cPdf.getDocument(); if (!addPopplerPage(cPdf.getPage(pageNr), currentPdfDoc)) { return false; } this->writer->endStream(); this->writer->write("endobj\n"); return true; }
void PdfBookmarks::writeOutlines(Document * doc, PdfWriter * writer, int * outlineRoot, GList * pageIds) { XOJ_CHECK_TYPE(PdfBookmarks); GtkTreeModel * model = doc->getContentsModel(); if (!model) { return; } GList * bookmarkList = exportBookmarksFromTreeModel(model, doc); int bookmarksLenght = g_list_length(bookmarkList); if (bookmarksLenght == 0) { return; } Bookmark ** bookmarks = new Bookmark *[bookmarksLenght]; int maxLevel = 0; int i = 0; for (GList * l = bookmarkList; l != NULL; l = l->next) { Bookmark * b = (Bookmark *) l->data; if (maxLevel < b->level) { maxLevel = b->level; } bookmarks[i++] = b; } int * levels = new int[maxLevel + 1]; for (int u = 0; u < maxLevel + 1; u++) { levels[u] = 0; } int level = 0; for (i = 0; i < bookmarksLenght; i++) { Bookmark * b = bookmarks[i]; if (b->level > 0) { int parent = levels[b->level - 1]; //Set parent and last pointers b->parent = parent; bookmarks[parent]->last = i; if (b->level > level) { //Level increasing: set first pointer bookmarks[parent]->first = i; } } else { bookmarks[i]->parent = bookmarksLenght; } if (b->level <= level && i > 0) { //Set prev and next pointers int prev = levels[b->level]; bookmarks[prev]->next = i; bookmarks[i]->prev = prev; } levels[b->level] = i; level = b->level; } int n = writer->getObjectId(); for (i = 0; i < bookmarksLenght; i++) { Bookmark * b = bookmarks[i]; writer->writeObj(); writer->write("<<\n/Title "); writer->writeTxt(b->name.c_str()); writer->write("\n"); writer->write("/Parent "); writer->write(n + b->parent); writer->write(" 0 R\n"); if (b->prev != -1) { writer->write("/Prev "); writer->write(n + b->prev); writer->write(" 0 R\n"); } if (b->next != -1) { writer->write("/Next "); writer->write(n + b->next); writer->write(" 0 R\n"); } if (b->first != -1) { writer->write("/First "); writer->write(n + b->first); writer->write(" 0 R\n"); } if (b->last != -1) { writer->write("/Last "); writer->write(n + b->last); writer->write(" 0 R\n"); } PageRef p = doc->getPage(b->page); float top = 0; if (p.isValid()) { top = (p.getHeight() - b->top) * 72; } //Outline items char buffer[256]; int pObjId = 0; int * pObjIdPtr = (int *)g_list_nth_data(pageIds, b->page); if (pObjIdPtr) { pObjId = *pObjIdPtr; } sprintf(buffer, "/Dest [%d 0 R /XYZ 0 %.2f null]\n", pObjId, top /*($this->h-$o['y'])*$this->k*/); writer->write(buffer); writer->write("/Count 0\n>>\n"); writer->write("endobj\n"); } //Outline root writer->writeObj(); *outlineRoot = writer->getObjectId() - 1; writer->write("<<\n/Type /Outlines /First "); writer->write(n); writer->write(" 0 R\n"); writer->write("/Last "); writer->write(n + levels[0]); writer->write(" 0 R\n>>\n"); writer->write("endobj\n"); for (i = 0; i < bookmarksLenght; i++) { delete bookmarks[i]; } delete[] bookmarks; delete[] levels; return; }