Updates to GlyphRuns[]
1. Fold "origin" into the positions (simplification) 2. Extend positions and offset arrays by 1, to include 1-past last glyph 3. Add flags field to run (with just WS flag for now) Change-Id: I93e38df808a5e9e4e5bcedbc62bc5a7aa433ef2e Reviewed-on: https://skia-review.googlesource.com/c/skia/+/399876 Commit-Queue: Mike Reed <reed@google.com> Reviewed-by: Julia Lavrova <jlavrova@google.com> Reviewed-by: Yegor Jbanov <yjbanov@google.com>
This commit is contained in:
parent
3386533c20
commit
ae33954b49
@ -51,6 +51,7 @@
|
||||
#include "include/private/SkShadowFlags.h"
|
||||
#include "include/utils/SkParsePath.h"
|
||||
#include "include/utils/SkShadowUtils.h"
|
||||
#include "modules/skparagraph/include/Paragraph.h"
|
||||
#include "modules/skshaper/include/SkShaper.h"
|
||||
#include "src/core/SkFontMgrPriv.h"
|
||||
#include "src/core/SkImagePriv.h"
|
||||
@ -2045,4 +2046,6 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
||||
constant("ShadowTransparentOccluder", (int)SkShadowFlags::kTransparentOccluder_ShadowFlag);
|
||||
constant("ShadowGeometricOnly", (int)SkShadowFlags::kGeometricOnly_ShadowFlag);
|
||||
constant("ShadowDirectionalLight", (int)SkShadowFlags::kDirectionalLight_ShadowFlag);
|
||||
|
||||
constant("WhiteSpace_GlyphRunFlag", (int)skia::textlayout::Paragraph::kWhiteSpace_VisitorFlag);
|
||||
}
|
||||
|
@ -583,8 +583,8 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
};
|
||||
|
||||
CanvasKit.Canvas.prototype.drawGlyphs = function(glyphs, positions, x, y, font, paint) {
|
||||
if (!(glyphs.length*2 == positions.length)) {
|
||||
throw 'Need glyphs and positions array to agree on the length';
|
||||
if (!(glyphs.length*2 <= positions.length)) {
|
||||
throw 'Not enough positions for the array of gyphs';
|
||||
}
|
||||
|
||||
const glyphs_ptr = copy1dArray(glyphs, 'HEAPU16');
|
||||
|
@ -258,13 +258,6 @@
|
||||
|
||||
canvas.drawLine(wrapTo, 0, wrapTo, 400, fontPaint);
|
||||
|
||||
const offset = function(array, dx, dy) {
|
||||
array[0] += dx;
|
||||
array[1] += dy;
|
||||
array[2] += dx;
|
||||
array[3] += dy;
|
||||
}
|
||||
|
||||
{
|
||||
const p = new CanvasKit.Paint();
|
||||
let runs = paragraph.getShapedRuns();
|
||||
@ -278,17 +271,16 @@
|
||||
let bounds = [
|
||||
r.positions[0],
|
||||
r.positions[1] + fm.ascent,
|
||||
r.positions[r.positions.length-2] + font.getGlyphWidths(r.glyphs.slice(-1))[0],
|
||||
r.positions[r.positions.length-2],
|
||||
r.positions[r.positions.length-1] + fm.descent
|
||||
];
|
||||
offset(bounds, r.origin_x, r.origin_y);
|
||||
canvas.drawRect(bounds, p);
|
||||
}
|
||||
p.delete();
|
||||
|
||||
fontPaint.setColor(CanvasKit.BLUE);
|
||||
for (let r of runs) {
|
||||
canvas.drawGlyphs(r.glyphs, r.positions, r.origin_x, r.origin_y, font, fontPaint);
|
||||
canvas.drawGlyphs(r.glyphs, r.positions, 0, 0, font, fontPaint);
|
||||
}
|
||||
fontPaint.setColor(CanvasKit.BLACK);
|
||||
}
|
||||
|
15
modules/canvaskit/npm_build/types/index.d.ts
vendored
15
modules/canvaskit/npm_build/types/index.d.ts
vendored
@ -649,12 +649,23 @@ export interface LineMetrics {
|
||||
lineNumber: number;
|
||||
}
|
||||
|
||||
readonly WhiteSpace_GlyphRunFlag: number; // the entire run is made up of whitespace(s)
|
||||
|
||||
/**
|
||||
* Information for a run of shaped text. See Paragraph.getShapedRuns()
|
||||
*
|
||||
* Notes:
|
||||
* positions is documented as Float32, but it holds twice as many as you expect, and they
|
||||
* are treated logically as pairs of floats: {x0, y0}, {x1, y1}, ... for each glyph.
|
||||
*
|
||||
* positions and offsets arrays have 1 extra slot (actually 2 for positions)
|
||||
* to describe the location "after" the last glyph in the glyphs array.
|
||||
*/
|
||||
export interface GlyphRun {
|
||||
glyphs: Uint16Array;
|
||||
positions: Float32Array; // alternating x0, y0, x1, y1, ...
|
||||
offsets: Uint32Array;
|
||||
origin_x: number;
|
||||
origin_y: number;
|
||||
flags: number; // see ..._GlyphRunFlag values
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -314,49 +314,34 @@ JSArray GetLineMetrics(para::Paragraph& self) {
|
||||
/*
|
||||
* Returns Runs[K]
|
||||
*
|
||||
* Run --> { font: ???, glyphs[N], positions[N*2], offsets[N], origin: x,y }
|
||||
* Run --> { font: ???, glyphs[N], positions[N*2], offsets[N], flags }
|
||||
*
|
||||
* K = number of runs
|
||||
* N = number of glyphs in a given run
|
||||
*/
|
||||
JSArray GetShapedRuns(para::Paragraph& self) {
|
||||
struct Run {
|
||||
SkFont font;
|
||||
SkPoint origin;
|
||||
int index;
|
||||
int count;
|
||||
};
|
||||
std::vector<Run> runs;
|
||||
std::vector<uint16_t> glyphs;
|
||||
std::vector<SkPoint> positions;
|
||||
std::vector<uint32_t> offsets;
|
||||
|
||||
self.visit([&](const para::Paragraph::VisitorInfo& info) {
|
||||
// add 1 Run
|
||||
runs.push_back({info.font, info.origin, (int)glyphs.size(), info.count});
|
||||
// append the arrays
|
||||
glyphs.insert(glyphs.end(), info.glyphs, info.glyphs + info.count);
|
||||
positions.insert(positions.end(), info.positions, info.positions + info.count);
|
||||
offsets.insert(offsets.end(), info.utf8Starts, info.utf8Starts + info.count);
|
||||
});
|
||||
|
||||
// where we accumulate our js output
|
||||
JSArray jruns = emscripten::val::array();
|
||||
|
||||
for (const auto& crun : runs) {
|
||||
const int N = crun.count;
|
||||
const int I = crun.index;
|
||||
self.visit([&](const para::Paragraph::VisitorInfo& info) {
|
||||
const int N = info.count; // glyphs
|
||||
const int N1 = N + 1; // positions, offsets have 1 extra (trailing) slot
|
||||
|
||||
JSObject jrun = emscripten::val::object();
|
||||
|
||||
jrun.set("glyphs" , MakeTypedArray(N, &glyphs[I], "Uint16Array"));
|
||||
jrun.set("positions", MakeTypedArray(N*2, &positions[I].fX, "Float32Array"));
|
||||
jrun.set("offsets" , MakeTypedArray(N, &offsets[I], "Uint32Array"));
|
||||
jrun.set("origin_x" , crun.origin.fX);
|
||||
jrun.set("origin_y" , crun.origin.fY);
|
||||
jrun.set("flags", info.flags);
|
||||
jrun.set("glyphs", MakeTypedArray(N, info.glyphs, "Uint16Array"));
|
||||
jrun.set("offsets", MakeTypedArray(N1, info.utf8Starts, "Uint32Array"));
|
||||
|
||||
// we need to modify the positions, so make a temp copy
|
||||
SkAutoSTMalloc<32, SkPoint> positions(N);
|
||||
for (int i = 0; i < N; ++i) {
|
||||
positions.get()[i] = info.positions[i] + info.origin;
|
||||
}
|
||||
jrun.set("positions", MakeTypedArray(N1*2, (const float*)positions.get(), "Float32Array"));
|
||||
|
||||
jruns.call<void>("push", jrun);
|
||||
|
||||
}
|
||||
});
|
||||
return jruns;
|
||||
}
|
||||
|
||||
|
@ -73,13 +73,17 @@ public:
|
||||
virtual void updateForegroundPaint(size_t from, size_t to, SkPaint paint) = 0;
|
||||
virtual void updateBackgroundPaint(size_t from, size_t to, SkPaint paint) = 0;
|
||||
|
||||
enum VisitorFlags {
|
||||
kWhiteSpace_VisitorFlag = 1 << 0,
|
||||
};
|
||||
struct VisitorInfo {
|
||||
const SkFont& font;
|
||||
SkPoint origin;
|
||||
int count;
|
||||
const uint16_t* glyphs;
|
||||
const SkPoint* positions;
|
||||
const uint32_t* utf8Starts;
|
||||
const uint16_t* glyphs; // count values
|
||||
const SkPoint* positions; // count+1 values
|
||||
const uint32_t* utf8Starts; // count+1 values
|
||||
unsigned flags;
|
||||
};
|
||||
using Visitor = std::function<void(const VisitorInfo&)>;
|
||||
virtual void visit(const Visitor&) = 0;
|
||||
|
@ -1075,6 +1075,7 @@ void ParagraphImpl::visit(const Visitor& visitor) {
|
||||
run.glyphs,
|
||||
run.positions,
|
||||
clusterPtr,
|
||||
0, // flags
|
||||
});
|
||||
clusterPtr += run.count;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user