Search in sources :

Example 6 with Size2f

use of com.xenoage.utils.math.geom.Size2f in project Zong by Xenoage.

the class Target method targetA4.

/**
 * Creates a target for a complete layout with A4 paper size (2 cm margins).
 */
public static Target targetA4() {
    float m = 20;
    Size2f s = new Size2f(210 - 2 * m, 297 - 2 * m);
    return completeLayoutTarget(new ScoreLayoutArea(s));
}
Also used : Size2f(com.xenoage.utils.math.geom.Size2f)

Example 7 with Size2f

use of com.xenoage.utils.math.geom.Size2f in project Zong by Xenoage.

the class AwtLayoutRenderer method paintToImage.

/**
 * Returns a {@link BufferedImage} with the given page of the given {@link Layout}
 * which is rendered at the given zoom level.
 */
public static BufferedImage paintToImage(Layout layout, int pageIndex, float zoom) {
    Page page = layout.getPages().get(pageIndex);
    Size2f pageSize = page.getFormat().getSize();
    int width = Units.mmToPxInt(pageSize.width, zoom);
    int height = Units.mmToPxInt(pageSize.height, zoom);
    BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    Graphics2D g2d = img.createGraphics();
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    g2d.setColor(Color.WHITE);
    g2d.fillRect(0, 0, width, height);
    LayoutRenderer.paintToCanvas(layout, pageIndex, zoom, origin, new AwtCanvas(g2d, pageSize, CanvasFormat.Raster, CanvasDecoration.Interactive, CanvasIntegrity.Perfect));
    g2d.dispose();
    return img;
}
Also used : Size2f(com.xenoage.utils.math.geom.Size2f) AwtCanvas(com.xenoage.zong.renderer.awt.canvas.AwtCanvas) Page(com.xenoage.zong.layout.Page) BufferedImage(java.awt.image.BufferedImage) Graphics2D(java.awt.Graphics2D)

Example 8 with Size2f

use of com.xenoage.utils.math.geom.Size2f in project Zong by Xenoage.

the class OpenAction method perform.

@Override
public void perform(Request request, Webserver server, HttpServletResponse response) throws SQLException, IOException {
    OpenRequest openRequest = getAs(OpenRequest.class, request);
    INSTANCE.log(Companion.remark("OpenAction started for URL " + openRequest.url));
    final Connection db = server.getDBConnection();
    // cleanup: delete documents which were not used during a defined period
    PreparedStatement stmtDelete = stmt(db, "SELECT id FROM docs WHERE last_access < ?", unixTime() - Integer.parseInt(server.getSetting("cachetime")));
    ResultSet resDelete = stmtDelete.executeQuery();
    while (resDelete.next()) {
        // TODO: automatically cascade
        int deleteID = resDelete.getInt(1);
        delete(db, "audio", "doc_id = ?", deleteID);
        delete(db, "cursors", "doc_id = ?", deleteID);
        delete(db, "pages", "doc_id = ?", deleteID);
        delete(db, "pageinfos", "doc_id = ?", deleteID);
        delete(db, "scaledpageinfos", "doc_id = ?", deleteID);
        delete(db, "docs", "id = ?", deleteID);
    }
    stmtDelete.close();
    // test
    // long startTime = System.currentTimeMillis();
    // see if document is already in database. if not, load it from the URL.
    ScoreDoc scoreDoc = null;
    Doc doc = null;
    PreparedStatement stmtDoc = stmt(db, "SELECT id FROM docs WHERE url = ?", openRequest.url);
    ResultSet resDoc = stmtDoc.executeQuery();
    if (resDoc.next()) {
        // the document already exists in the database
        INSTANCE.log(Companion.remark("Requested document is still in cache. Using it."));
        doc = Doc.fromDB(db, openRequest.url);
    } else {
        // the document is unknown. load it.
        INSTANCE.log(Companion.remark("Requested document is not in cache. Loading it."));
        Tuple2<ScoreDoc, Doc> t = loadDocument(openRequest.url, openRequest.requestedID);
        scoreDoc = t.get1();
        doc = t.get2();
    }
    stmtDoc.close();
    // load size of first page
    PreparedStatement stmtFirstPageSize = stmt(db, "SELECT width, height FROM pageinfos WHERE doc_id = ? AND page = 0", doc.id);
    ResultSet resFirstPageSize = stmtFirstPageSize.executeQuery();
    resFirstPageSize.next();
    Size2f firstPageSize = new Size2f(resFirstPageSize.getFloat(1), resFirstPageSize.getFloat(2));
    stmtFirstPageSize.close();
    // scalings are saved as value*72dpi/10000 in the database.
    // convert all requested scalings to this format
    final LinkedList<Integer> requestedScalings = llist();
    for (Scaling scaling : openRequest.scalings) {
        requestedScalings.add(scaling.convertTo10000(firstPageSize));
    }
    // find all requested scalings, that are not already available in the database
    final LinkedList<Integer> scalingsToRender = llist();
    for (int scaling : requestedScalings) {
        boolean scalingExists = (ScaledPage.fromDB(db, doc.id, 0, scaling) != null);
        if (!scalingExists) {
            scalingsToRender.add(scaling);
            // if ScoreDoc was not loaded yet, load it now
            if (scoreDoc == null)
                scoreDoc = loadDocument(openRequest.url, openRequest.requestedID).get1();
            // save information about scaled pages
            List<com.xenoage.zong.layout.Page> pages = scoreDoc.getLayout().getPages();
            for (int iPage : range(pages)) {
                com.xenoage.zong.layout.Page page = pages.get(iPage);
                Size2f pageSize = page.getFormat().getSize();
                ScaledPage scaledPage = new ScaledPage(doc.id, iPage, scaling, Units.mmToPxInt(pageSize.width, scaling / 10000f), Units.mmToPxInt(pageSize.height, scaling / 10000f));
                scaledPage.insertIntoDB(db);
            }
        }
    }
    // decide, if we have something to do
    final boolean renderPages = (scalingsToRender.size() > 0);
    final boolean renderAudio = !exists(db, "audio", "doc_id = ?", doc.id);
    final boolean renderCursor = !exists(db, "cursors", "doc_id = ?", doc.id);
    if (renderPages || renderAudio || renderCursor) {
        // if ScoreDoc was not loaded yet, load it now
        if (scoreDoc == null)
            scoreDoc = loadDocument(openRequest.url, openRequest.requestedID).get1();
    }
    // from here on, try to do things in parallel
    // first thread: render pages and save them in the database
    final ScoreDoc scoreDocFinal = scoreDoc;
    final Doc docFinal = doc;
    final ArrayList<Page> pages = alist();
    final ArrayList<ArrayList<ScaledPage>> scaledPages = alist();
    Thread threadPages = new WorkerThread() {

        @Override
        public void runTry() throws Exception {
            if (renderPages) {
                // render the pages
                for (int scaling : scalingsToRender) {
                    List<BufferedImage> pages = renderTiles(scoreDocFinal.getLayout(), scaling / 10000f);
                    for (int iPage : range(pages)) {
                        BufferedImage page = pages.get(iPage);
                        // write page
                        ByteArrayOutputStream imageData = new ByteArrayOutputStream();
                        ImageIO.write(page, "png", imageData);
                        insert(db, "pages", "doc_id, page, scaling, image", docFinal.id, iPage, scaling, imageData.toByteArray());
                    }
                }
                INSTANCE.log(Companion.remark("Rendered " + scoreDocFinal.getLayout().getPages().size() + " pages at " + scalingsToRender + " scalings"));
            }
            // collect pages for response
            for (int iPage : range(docFinal.pages)) {
                pages.add(Page.fromDB(db, docFinal.id, iPage));
            }
            // collect scaled pages for response
            for (int iPage : range(docFinal.pages)) {
                ArrayList<ScaledPage> sp = alist();
                for (int scaling : requestedScalings) {
                    sp.add(ScaledPage.fromDB(db, docFinal.id, iPage, scaling));
                }
                scaledPages.add(sp);
            }
            // TEST
            System.out.println("pages finished");
        }
    };
    threadPages.start();
    // second and third thread: render audio files, if not already in the cache
    Thread threadOgg = new WorkerThread() {

        @Override
        public void runTry() throws Exception {
            // render OGG file
            if (renderAudio)
                renderAndSaveAudioFile(db, docFinal, scoreDocFinal, "OGG", new OggScoreFileOutput());
            // TEST
            System.out.println("ogg finished");
        }
    };
    threadOgg.start();
    Thread threadMp3 = new WorkerThread() {

        @Override
        public void runTry() throws Exception {
            // render MP3 file
            if (renderAudio)
                renderAndSaveAudioFile(db, docFinal, scoreDocFinal, "MP3", new Mp3ScoreFileOutput());
            // TEST
            System.out.println("mp3 finished");
        }
    };
    threadMp3.start();
    // fourth thread: render cursor file, if not already in the cache
    Thread threadCursor = new WorkerThread() {

        @Override
        public void runTry() throws Exception {
            // create cursor data
            if (renderCursor) {
                INSTANCE.log(Companion.remark("Creating cursor data"));
                JsonObject jsonCursor = new CursorOutput().write(scoreDocFinal);
                insert(db, "cursors", "doc_id, cursors", docFinal.id, jsonCursor.toString());
                // TEST
                System.out.println("cursors finished");
            }
        }
    };
    threadCursor.start();
    // wait until all threads are finished
    try {
        threadPages.join();
        threadOgg.join();
        threadMp3.join();
        threadCursor.join();
    } catch (InterruptedException e) {
        throw new RuntimeException("interrupted");
    }
    // create response message
    JsonObject jsonResponse = new JsonObject();
    jsonResponse.addProperty("id", "" + doc.publicID);
    JsonArray jsonPages = new JsonArray();
    for (int iPage : range(pages)) {
        Page page = pages.get(iPage);
        JsonObject jsonPage = new JsonObject();
        jsonPage.addProperty("width", page.width);
        jsonPage.addProperty("height", page.height);
        JsonArray jsonScalesPages = new JsonArray();
        for (ScaledPage sp : scaledPages.get(iPage)) jsonScalesPages.add(Webserver.instance.getGson().toJsonTree(sp));
        jsonPage.add("scaledPages", jsonScalesPages);
        jsonPages.add(jsonPage);
    }
    jsonResponse.add("pages", jsonPages);
    // test
    // long endTime = System.currentTimeMillis();
    // System.out.println("total time: " + (endTime - startTime));
    // send success response
    writeSuccess(response, jsonResponse);
}
Also used : CursorOutput(com.xenoage.zong.webserver.io.CursorOutput) ArrayList(java.util.ArrayList) JsonObject(com.google.gson.JsonObject) Page(com.xenoage.zong.webserver.model.Page) ScaledPage(com.xenoage.zong.webserver.model.ScaledPage) BufferedImage(java.awt.image.BufferedImage) ScoreDoc(com.xenoage.zong.documents.ScoreDoc) ScaledPage(com.xenoage.zong.webserver.model.ScaledPage) ResultSet(java.sql.ResultSet) Doc(com.xenoage.zong.webserver.model.Doc) ScoreDoc(com.xenoage.zong.documents.ScoreDoc) Mp3ScoreFileOutput(com.xenoage.zong.desktop.io.mp3.out.Mp3ScoreFileOutput) Connection(java.sql.Connection) PreparedStatement(java.sql.PreparedStatement) ByteArrayOutputStream(java.io.ByteArrayOutputStream) OggScoreFileOutput(com.xenoage.zong.desktop.io.ogg.out.OggScoreFileOutput) WorkerThread(com.xenoage.zong.webserver.util.WorkerThread) JsonArray(com.google.gson.JsonArray) WorkerThread(com.xenoage.zong.webserver.util.WorkerThread) Size2f(com.xenoage.utils.math.geom.Size2f) OpenRequest(com.xenoage.zong.webserver.model.requests.OpenRequest) Scaling(com.xenoage.zong.webserver.model.Scaling)

Example 9 with Size2f

use of com.xenoage.utils.math.geom.Size2f in project Zong by Xenoage.

the class WebApp method openFile.

private void openFile(String filePath) {
    // show loading, hide score
    if (loadingPanel != null)
        loadingPanel.getStyle().setDisplay(BLOCK);
    canvas.setVisible(false);
    // load score
    platformUtils().openFileAsync(filePath).thenAsync(scoreStream -> new MusicXmlScoreDocFileReader(scoreStream, null).read()).thenAsync(scoreDoc -> {
        WebApp.this.scoreDoc = scoreDoc;
        return platformUtils().openFileAsync("data/layout/default.xml");
    }).thenDo(testXmlStream -> {
        LayoutSettings layoutSettings;
        try {
            layoutSettings = LayoutSettingsReader.read(testXmlStream);
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
        Size2f areaSize = new Size2f(150, 10000);
        SymbolPool symbolPool = zongPlatformUtils().getSymbolPool();
        Context context = new Context(scoreDoc.getScore(), symbolPool, layoutSettings);
        Target target = Target.completeLayoutTarget(new ScoreLayoutArea(areaSize));
        paintLayout();
        // show score, hide loading
        canvas.setVisible(true);
        if (loadingPanel != null)
            loadingPanel.getStyle().setDisplay(NONE);
    }).onError(ex -> consoleLog("Error: " + ex.toString()));
}
Also used : NONE(com.google.gwt.dom.client.Style.Display.NONE) GwtLogProcessing(com.xenoage.utils.gwt.log.GwtLogProcessing) Report.fatal(com.xenoage.utils.log.Report.fatal) EntryPoint(com.google.gwt.core.client.EntryPoint) LayoutSettings(com.xenoage.zong.musiclayout.settings.LayoutSettings) SymbolPool(com.xenoage.zong.symbols.SymbolPool) LayoutSettingsReader(com.xenoage.zong.io.musiclayout.LayoutSettingsReader) GwtErrorProcessing(com.xenoage.utils.gwt.error.GwtErrorProcessing) Size2i(com.xenoage.utils.math.geom.Size2i) Size2f(com.xenoage.utils.math.geom.Size2f) ScoreDoc(com.xenoage.zong.documents.ScoreDoc) MathUtils.clamp(com.xenoage.utils.math.MathUtils.clamp) Log(com.xenoage.utils.log.Log) Label(com.google.gwt.user.client.ui.Label) BLOCK(com.google.gwt.dom.client.Style.Display.BLOCK) PlatformUtils.platformUtils(com.xenoage.utils.PlatformUtils.platformUtils) PX(com.google.gwt.dom.client.Style.Unit.PX) Log.log(com.xenoage.utils.log.Log.log) GwtCanvasLayoutRenderer(com.xenoage.zong.renderer.gwtcanvas.GwtCanvasLayoutRenderer) Window(com.google.gwt.user.client.Window) Canvas(com.google.gwt.canvas.client.Canvas) Err(com.xenoage.utils.error.Err) Context(com.xenoage.zong.musiclayout.layouter.Context) ScoreLayoutArea(com.xenoage.zong.musiclayout.layouter.ScoreLayoutArea) ZongPlatformUtils.zongPlatformUtils(com.xenoage.zong.util.ZongPlatformUtils.zongPlatformUtils) DOM(com.google.gwt.user.client.DOM) MusicXmlScoreDocFileReader(com.xenoage.zong.io.musicxml.in.MusicXmlScoreDocFileReader) Zong(com.xenoage.zong.Zong) Target(com.xenoage.zong.musiclayout.layouter.Target) IOException(java.io.IOException) AsyncCallback(com.xenoage.utils.async.AsyncCallback) RootPanel(com.google.gwt.user.client.ui.RootPanel) Context2d(com.google.gwt.canvas.dom.client.Context2d) GwtZongPlatformUtils(com.xenoage.zong.webapp.utils.GwtZongPlatformUtils) Element(com.google.gwt.dom.client.Element) GwtPlatformUtils.consoleLog(com.xenoage.utils.gwt.GwtPlatformUtils.consoleLog) Context(com.xenoage.zong.musiclayout.layouter.Context) Target(com.xenoage.zong.musiclayout.layouter.Target) LayoutSettings(com.xenoage.zong.musiclayout.settings.LayoutSettings) Size2f(com.xenoage.utils.math.geom.Size2f) SymbolPool(com.xenoage.zong.symbols.SymbolPool) MusicXmlScoreDocFileReader(com.xenoage.zong.io.musicxml.in.MusicXmlScoreDocFileReader) IOException(java.io.IOException) ScoreLayoutArea(com.xenoage.zong.musiclayout.layouter.ScoreLayoutArea)

Example 10 with Size2f

use of com.xenoage.utils.math.geom.Size2f in project Zong by Xenoage.

the class PageTest method createPageWithUnrotatedFrames.

/**
 * Creates a layout with a page with some unrotated frames for testing.
 */
private Layout createPageWithUnrotatedFrames() {
    Layout layout = new Layout(null);
    PageFormat pf = new PageFormat(new Size2f(200, 200), new PageMargins(10, 10, 10, 10));
    Page page = new Page(pf);
    layout.addPage(page);
    // Frame 1
    frm1 = new ScoreFrame();
    frm1.setPosition(p(120, 120));
    frm1.setSize(s(60, 80));
    page.addFrame(frm1);
    // Frame 2
    frm2 = new GroupFrame();
    frm2.setPosition(p(90, 110));
    frm2.setSize(s(60, 40));
    page.addFrame(frm2);
    // Childframe 2a
    frm2a = new ScoreFrame();
    frm2a.setPosition(p(30, 0));
    frm2a.setSize(s(10, 10));
    frm2.addChildFrame(frm2a);
    // Childframe 2b
    frm2b = new ScoreFrame();
    frm2b.setPosition(p(-10, -20));
    frm2b.setSize(s(10, 10));
    frm2.addChildFrame(frm2b);
    // Frame 3
    frm3 = new ScoreFrame();
    frm3.setPosition(p(30, 80));
    frm3.setSize(s(30, 60));
    page.addFrame(frm3);
    return layout;
}
Also used : PageMargins(com.xenoage.zong.core.format.PageMargins) PageFormat(com.xenoage.zong.core.format.PageFormat) ScoreFrame(com.xenoage.zong.layout.frames.ScoreFrame) Size2f(com.xenoage.utils.math.geom.Size2f) GroupFrame(com.xenoage.zong.layout.frames.GroupFrame)

Aggregations

Size2f (com.xenoage.utils.math.geom.Size2f)27 Page (com.xenoage.zong.layout.Page)10 PageFormat (com.xenoage.zong.core.format.PageFormat)6 PageMargins (com.xenoage.zong.core.format.PageMargins)5 ScoreFrame (com.xenoage.zong.layout.frames.ScoreFrame)5 Point2f (com.xenoage.utils.math.geom.Point2f)4 Score (com.xenoage.zong.core.Score)4 ScoreDoc (com.xenoage.zong.documents.ScoreDoc)4 Layout (com.xenoage.zong.layout.Layout)4 ScoreLayout (com.xenoage.zong.musiclayout.ScoreLayout)3 ScoreLayoutArea (com.xenoage.zong.musiclayout.layouter.ScoreLayoutArea)3 Target (com.xenoage.zong.musiclayout.layouter.Target)3 LayoutSettings (com.xenoage.zong.musiclayout.settings.LayoutSettings)3 SystemSpacing (com.xenoage.zong.musiclayout.spacing.SystemSpacing)3 AwtCanvas (com.xenoage.zong.renderer.awt.canvas.AwtCanvas)3 SymbolPool (com.xenoage.zong.symbols.SymbolPool)3 Graphics2D (java.awt.Graphics2D)3 JsonArray (com.google.gson.JsonArray)2 JsonObject (com.google.gson.JsonObject)2 Context2d (com.google.gwt.canvas.dom.client.Context2d)2