Bladeren bron

Refactoring, implement renderRectangle

Andrea Condoluci 9 jaren geleden
bovenliggende
commit
696f2a052d

+ 43 - 11
src/MusicSheetAPI.ts

@@ -9,7 +9,7 @@ import {VexFlowTextMeasurer} from "./MusicalScore/Graphical/VexFlow/VexFlowTextM
 
 export class MusicSheetAPI {
     constructor() {
-        return;
+        this.free();
     }
 
     private canvas: HTMLCanvasElement;
@@ -18,22 +18,51 @@ export class MusicSheetAPI {
     private graphic: GraphicalMusicSheet;
     private width: number;
     private zoom: number = 1.0;
-    private unit: number = 10;
+    private unit: number = 10.0;
 
-    public load(sheet: Element): void {
-        let score: IXmlElement = new IXmlElement(sheet.getElementsByTagName("score-partwise")[0]);
+    /**
+     * Initialize this object to default values
+     */
+    public free(): void {
+        this.width = undefined;
+        this.canvas = undefined;
+        this.sheet = undefined;
+        this.drawer = undefined;
+        this.graphic = undefined;
+        this.zoom = 1.0;
+        this.unit = 10.0;
+    }
+
+    /**
+     * Load a MusicXML file
+     * @param doc is the root node of a MusicXML document
+     */
+    public load(doc: Document): void {
+        let elem: Element = doc.getElementsByTagName("score-partwise")[0];
+        if (elem === undefined) {
+            throw new Error("Invalid partwise MusicXML document");
+        }
+        let score: IXmlElement = new IXmlElement(elem);
         let calc: MusicSheetCalculator = new VexFlowMusicSheetCalculator();
         let reader: MusicSheetReader = new MusicSheetReader();
-        this.sheet = reader.createMusicSheet(score, "path missing");
+        this.sheet = reader.createMusicSheet(score, "*** unknown path ***");
         this.graphic = new GraphicalMusicSheet(this.sheet, calc);
         this.display();
     }
 
+    /**
+     * Set the drawing canvas
+     * @param canvas
+     */
     public setCanvas(canvas: HTMLCanvasElement): void {
         this.canvas = canvas;
         this.drawer = new VexFlowMusicSheetDrawer(canvas, new VexFlowTextMeasurer());
     }
 
+    /**
+     * Set the canvas width
+     * @param width
+     */
     public setWidth(width: number): void {
         if (width === this.width) {
             return;
@@ -42,11 +71,16 @@ export class MusicSheetAPI {
         this.display();
     }
 
+    /**
+     * Set the zoom
+     * @param k
+     */
     public scale(k: number): void {
         this.zoom = k;
         this.display();
     }
 
+    // FIXME: make the following private!
     public display(): void {
         if (this.width === undefined) {
             return;
@@ -57,7 +91,9 @@ export class MusicSheetAPI {
         if (this.sheet === undefined) {
             return;
         }
+        // Set page width
         this.sheet.pageWidth = this.width / this.zoom / this.unit;
+        // Calculate again
         this.graphic.reCalculate();
         // Update Sheet Page
         let height: number = this.graphic.MusicPages[0].PositionAndShape.BorderBottom * this.unit * this.zoom;
@@ -66,16 +102,12 @@ export class MusicSheetAPI {
             height
         );
         // Fix the label problem
-        this.drawer.translate(0, 100);
+        // this.drawer.translate(0, 100);
         this.drawer.scale(this.zoom);
+        // Finally, draw
         this.drawer.drawSheet(this.graphic);
     }
 
-    public free(): void {
-        this.canvas = undefined;
-        this.sheet = undefined;
-        return;
-    }
 }
 
 (<any>window).osmd = {

+ 42 - 0
src/MusicalScore/Graphical/VexFlow/VexFlowConverter.ts

@@ -12,6 +12,9 @@ import {NoteEnum} from "../../../Common/DataObjects/pitch";
 import {VexFlowGraphicalNote} from "./VexFlowGraphicalNote";
 import {GraphicalNote} from "../GraphicalNote";
 import {SystemLinesEnum} from "../SystemLinesEnum";
+import {FontStyles} from "../../../Common/Enums/FontStyles";
+import {Fonts} from "../../../Common/Enums/Fonts";
+import {OutlineAndFillStyleEnum} from "../DrawingEnums";
 
 export class VexFlowConverter {
     private static majorMap: {[_: number]: string; } = {
@@ -201,4 +204,43 @@ export class VexFlowConverter {
             default:
         }
     }
+
+    public static font(fontSize: number, fontStyle: FontStyles = FontStyles.Regular, font: Fonts = Fonts.TimesNewRoman): string {
+        let style: string = "normal";
+        let weight: string = "normal";
+        let family: string = "'Times New Roman'";
+
+        switch (fontStyle) {
+            case FontStyles.Bold:
+                weight = "bold";
+                break;
+            case FontStyles.Italic:
+                style = "italic";
+                break;
+            case FontStyles.BoldItalic:
+                style = "italic";
+                weight = "bold";
+                break;
+            case FontStyles.Underlined:
+                // TODO
+                break;
+            default:
+                break;
+        }
+
+        switch (font) {
+            case Fonts.Kokila:
+                // TODO Not Supported
+                break;
+            default:
+        }
+
+
+        return  style + " " + weight + " " + Math.floor(fontSize) + "px " + family;
+    }
+
+    public static style(styleId: OutlineAndFillStyleEnum): string {
+        // TODO
+        return "black";
+    }
 }

+ 2 - 2
src/MusicalScore/Graphical/VexFlow/VexFlowMusicSheetCalculator.ts

@@ -142,9 +142,9 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
                         y += 10;
                     }
                     // set y positions of systems using the previous system and a fixed distance.
-                    musicSystem.PositionAndShape.BorderBottom = y + 10;
+                    musicSystem.PositionAndShape.BorderBottom = y + 0;
                     musicSystem.PositionAndShape.RelativePosition.y = globalY;
-                    globalY += y + 10;
+                    globalY += y + 0;
                 }
             }
         }

+ 36 - 19
src/MusicalScore/Graphical/VexFlow/VexFlowMusicSheetDrawer.ts

@@ -5,30 +5,42 @@ import {VexFlowMeasure} from "./VexFlowMeasure";
 import {ITextMeasurer} from "../../Interfaces/ITextMeasurer";
 import {PointF2D} from "../../../Common/DataObjects/PointF2D";
 import {GraphicalLabel} from "../GraphicalLabel";
-/**
- * Created by Matthias on 22.06.2016.
- */
+import {VexFlowConverter} from "./VexFlowConverter";
+
 export class VexFlowMusicSheetDrawer extends MusicSheetDrawer {
     private renderer: Vex.Flow.Renderer;
-    private ctx: Vex.Flow.CanvasContext;
+    private vfctx: Vex.Flow.CanvasContext;
+    private ctx: CanvasRenderingContext2D;
 
     constructor(canvas: HTMLCanvasElement, textMeasurer: ITextMeasurer, isPreviewImageDrawer: boolean = false) {
         super(textMeasurer, isPreviewImageDrawer);
         this.renderer = new Vex.Flow.Renderer(canvas, Vex.Flow.Renderer.Backends.CANVAS);
-        this.ctx = this.renderer.getContext();
+        this.vfctx = this.renderer.getContext();
+        // The following is a hack to retrieve the actual canvas' drawing context
+        // Not supposed to work forever....
+        this.ctx = (this.vfctx as any).vexFlowCanvasContext;
     }
 
+    /**
+     * Zoom the rendering areas
+     * @param k is the zoom factor
+     */
     public scale(k: number): void {
-        this.ctx.scale(k, k);
+        this.vfctx.scale(k, k);
     }
 
+    /**
+     * Resize the rendering areas
+     * @param x
+     * @param y
+     */
     public resize(x: number, y: number): void {
         this.renderer.resize(x, y);
     }
 
     public translate(x: number, y: number): void {
-        // FIXME
-        //(this.ctx as any).vexFlowCanvasContext.translate(x, y);
+        // Translation seems not supported by VexFlow
+        this.ctx.translate(x, y);
     }
 
     /**
@@ -37,16 +49,15 @@ export class VexFlowMusicSheetDrawer extends MusicSheetDrawer {
      * @returns {number} the distance in pixels
      */
     public calculatePixelDistance(unitDistance: number): number {
-        // ToDo: implement!
         return unitDistance * 10.0;
     }
 
     protected drawMeasure(measure: VexFlowMeasure): void {
         measure.setAbsoluteCoordinates(
-            measure.PositionAndShape.AbsolutePosition.x * (measure as VexFlowMeasure).unit,
-            measure.PositionAndShape.AbsolutePosition.y * (measure as VexFlowMeasure).unit
+            measure.PositionAndShape.AbsolutePosition.x * 10.0,
+            measure.PositionAndShape.AbsolutePosition.y * 10.0
         );
-        return measure.draw(this.ctx);
+        return measure.draw(this.vfctx);
     }
 
     /**
@@ -60,10 +71,15 @@ export class VexFlowMusicSheetDrawer extends MusicSheetDrawer {
      */
     protected renderLabel(graphicalLabel: GraphicalLabel, layer: number, bitmapWidth: number,
                           bitmapHeight: number, heightInPixel: number, screenPosition: PointF2D): void {
-        // ToDo: implement!
-        let ctx: CanvasRenderingContext2D = (this.ctx as any).vexFlowCanvasContext;
-        ctx.font = Math.floor(graphicalLabel.Label.fontHeight * 10) + "px 'Times New Roman'";
+        let ctx: CanvasRenderingContext2D = (this.vfctx as any).vexFlowCanvasContext;
+        let old: string = ctx.font;
+        ctx.font = VexFlowConverter.font(
+            graphicalLabel.Label.fontHeight * 10.0,
+            graphicalLabel.Label.fontStyle,
+            graphicalLabel.Label.font
+        );
         ctx.fillText(graphicalLabel.Label.text, screenPosition.x, screenPosition.y + heightInPixel);
+        ctx.font = old;
     }
 
     /**
@@ -74,7 +90,10 @@ export class VexFlowMusicSheetDrawer extends MusicSheetDrawer {
      * @param styleId the style id
      */
     protected renderRectangle(rectangle: RectangleF2D, layer: number, styleId: number): void {
-        // ToDo: implement!
+        let old: string|CanvasGradient|CanvasPattern = this.ctx.fillStyle;
+        this.ctx.fillStyle = VexFlowConverter.style(styleId);
+        this.ctx.fillRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
+        this.ctx.fillStyle = old;
     }
 
     /**
@@ -83,7 +102,6 @@ export class VexFlowMusicSheetDrawer extends MusicSheetDrawer {
      * @returns {PointF2D}
      */
     protected applyScreenTransformation(point: PointF2D): PointF2D {
-        // ToDo: implement!
         return new PointF2D(point.x * 10.0, point.y * 10.0);
     }
 
@@ -93,7 +111,6 @@ export class VexFlowMusicSheetDrawer extends MusicSheetDrawer {
      * @returns {RectangleF2D}
      */
     protected applyScreenTransformationForRect(rectangle: RectangleF2D): RectangleF2D {
-        // FIXME Check if correct
-        return new RectangleF2D(rectangle.x * 10, rectangle.y * 10, rectangle.width * 10, rectangle.height * 10);
+        return new RectangleF2D(rectangle.x * 10.0, rectangle.y * 10.0, rectangle.width * 10.0, rectangle.height * 10.0);
     }
 }

+ 3 - 3
src/MusicalScore/Graphical/VexFlow/VexFlowTextMeasurer.ts

@@ -1,6 +1,7 @@
 import {ITextMeasurer} from "../../Interfaces/ITextMeasurer";
 import {Fonts} from "../../../Common/Enums/Fonts";
 import {FontStyles} from "../../../Common/Enums/FontStyles";
+import {VexFlowConverter} from "./VexFlowConverter";
 /**
  * Created by Matthias on 21.06.2016.
  */
@@ -9,12 +10,11 @@ export class VexFlowTextMeasurer implements ITextMeasurer {
     constructor() {
         let canvas: HTMLCanvasElement = document.createElement("canvas");
         this.context = canvas.getContext("2d");
-        this.context.font = "20px 'Times New Roman'";
     }
     private context: CanvasRenderingContext2D;
 
     public computeTextWidthToHeightRatio(text: string, font: Fonts, style: FontStyles): number {
-        let size: any = this.context.measureText(text);
-        return size.width / 20;
+        this.context.font = VexFlowConverter.font(20, style, font);
+        return this.context.measureText(text).width / 20;
     }
 }