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));
}
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;
}
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);
}
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()));
}
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;
}
Aggregations