Upload the chosen font to the server
This commit is contained in:
parent
3fcd4d472b
commit
5b84b052a0
|
@ -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",
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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),
|
||||
}))
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue