Upload the chosen font to the server

This commit is contained in:
Patrick Walton 2017-08-10 18:38:54 -07:00
parent 3fcd4d472b
commit 5b84b052a0
3 changed files with 73 additions and 18 deletions

View File

@ -10,6 +10,7 @@
"license": "MIT OR Apache-2.0",
"dependencies": {
"@types/node": "^8.0.19",
"base64-js": "^1.2.1",
"bootstrap": "^4.0.0-alpha.6",
"opentype.js": "^0.7.3",
"ts-loader": "^2.3.2",

View File

@ -1,11 +1,30 @@
// pathfinder/demo/src/index.ts
const base64js = require('base64-js');
const opentype = require('opentype.js');
class AppController {
constructor() {
const TEXT: string = "A";
const FONT_SIZE: number = 16.0;
const PARTITION_FONT_ENDPOINT_URL: string = "/partition-font";
class PathfinderMeshes {
constructor(encodedResponse: string) {
const response = JSON.parse(encodedResponse);
if (!('Ok' in response))
throw new Error("Failed to partition the font!");
const meshes = response.Ok;
this.bQuads = base64js.toByteArray(meshes.bQuads);
this.bVertices = base64js.toByteArray(meshes.bVertices);
}
bQuads: ArrayBuffer;
bVertices: ArrayBuffer;
}
class AppController {
constructor() {}
start() {
this.view = new PathfinderView(document.getElementById('pf-canvas') as HTMLCanvasElement);
@ -15,16 +34,49 @@ class AppController {
loadFont() {
const file = this.loadFontButton.files[0];
const fileURL = window.URL.createObjectURL(file);
opentype.load(fileURL, (err, font) => this.fontLoaded(font));
const reader = new FileReader;
reader.addEventListener('loadend', () => {
this.fontData = reader.result;
this.fontLoaded();
}, false);
reader.readAsArrayBuffer(file);
}
fontLoaded(font) {
fontLoaded() {
this.font = opentype.parse(this.fontData);
if (!this.font.supported) {
window.alert("The font type is unsupported.");
return;
}
const glyphIDs = this.font.stringToGlyphs(TEXT).map(glyph => glyph.index);
const request = {
otf: base64js.fromByteArray(new Uint8Array(this.fontData)),
fontIndex: 0,
glyphIDs: glyphIDs,
pointSize: FONT_SIZE,
};
const xhr = new XMLHttpRequest();
xhr.addEventListener('load', () => {
this.meshes = new PathfinderMeshes(xhr.responseText);
this.meshesReceived();
}, false);
xhr.open('POST', PARTITION_FONT_ENDPOINT_URL, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify(request));
}
meshesReceived() {
// TODO(pcwalton)
}
view: PathfinderView;
loadFontButton: HTMLInputElement;
fontData: ArrayBuffer;
font: any;
meshes: PathfinderMeshes;
}
class PathfinderView {

View File

@ -52,13 +52,14 @@ impl IndexRange {
}
}
#[allow(non_snake_case)]
#[derive(Clone, Serialize, Deserialize)]
struct PartitionFontRequest {
// Base64 encoded.
otf: String,
font_index: u32,
glyph_ids: Vec<u32>,
point_size: f64,
fontIndex: u32,
glyphIDs: Vec<u32>,
pointSize: f64,
}
#[derive(Clone, Copy, Serialize, Deserialize)]
@ -83,13 +84,14 @@ struct PartitionGlyphInfo {
b_vertex_indices: IndexRange,
}
#[allow(non_snake_case)]
#[derive(Clone, Serialize, Deserialize)]
struct PartitionFontResponse {
glyph_info: Vec<PartitionGlyphInfo>,
glyphInfo: Vec<PartitionGlyphInfo>,
// Base64-encoded `bincode`-encoded `BQuad`s.
b_quads: String,
bQuads: String,
// Base64-encoded `bincode`-encoded `BVertex`es.
b_vertices: String,
bVertices: String,
}
#[derive(Clone, Copy, Serialize, Deserialize)]
@ -119,16 +121,16 @@ fn partition_font(request: Json<PartitionFontRequest>)
let font_key = FontKey::new();
let font_instance_key = FontInstanceKey {
font_key: font_key,
size: Au::from_f64_px(request.point_size),
size: Au::from_f64_px(request.pointSize),
};
let mut font_context = FontContext::new();
if font_context.add_font_from_memory(&font_key, otf_data, request.font_index).is_err() {
if font_context.add_font_from_memory(&font_key, otf_data, request.fontIndex).is_err() {
return Json(Err(PartitionFontError::FontLoadingFailed))
}
// Read glyph info.
let mut outline_buffer = GlyphOutlineBuffer::new();
let decoded_outline_indices: Vec<_> = request.glyph_ids.iter().map(|&glyph_id| {
let decoded_outline_indices: Vec<_> = request.glyphIDs.iter().map(|&glyph_id| {
let glyph_key = GlyphKey::new(glyph_id);
let first_endpoint_index = outline_buffer.endpoints.len();
@ -159,7 +161,7 @@ fn partition_font(request: Json<PartitionFontRequest>)
&outline_buffer.subpaths);
let mut glyph_info = vec![];
for (path_index, (&glyph_id, decoded_outline_indices)) in
request.glyph_ids.iter().zip(decoded_outline_indices.iter()).enumerate() {
request.glyphIDs.iter().zip(decoded_outline_indices.iter()).enumerate() {
let glyph_key = GlyphKey::new(glyph_id);
let dimensions = match font_context.glyph_dimensions(&font_instance_key, &glyph_key) {
@ -212,9 +214,9 @@ fn partition_font(request: Json<PartitionFontRequest>)
// Return the response.
Json(Ok(PartitionFontResponse {
glyph_info: glyph_info,
b_quads: base64::encode(&b_quads),
b_vertices: base64::encode(&b_vertices),
glyphInfo: glyph_info,
bQuads: base64::encode(&b_quads),
bVertices: base64::encode(&b_vertices),
}))
}