Skip to content

Commit

Permalink
Added ShapingOptions, renamed AnimationDisposalMethod -> AnimationDis…
Browse files Browse the repository at this point in the history
…posalMode, JWM example upgraded from 0.1.2 to 0.1.170
  • Loading branch information
tonsky committed Aug 11, 2021
1 parent 712a440 commit 5fb057b
Show file tree
Hide file tree
Showing 25 changed files with 334 additions and 120 deletions.
36 changes: 36 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,39 @@
# 0.93.1 - Aug 11, 2021

Added:

- ShapingOptions
- Groups together FontMgr, FontFeature[], leftToRight
- Adds approximateSpaces and approximatePunctuation
- FontMgrRunIterator(String, Font)
- Shaper::shapeLine(String, Font)

Changed:

- AnimationDisposalMethod -> AnimationDisposalMode

Signature updated from:

- TextLine::make(String, Font, FontFeature[], boolean)
- FontMgrRunIterator(ManagedString, boolean, Font, FontMgr)
- FontMgrRunIterator(String, Font, FontMgr)
- Shaper::shape(String, Font, boolean, float, Point)
- Shaper::shape(String, Font, FontMgr, FontFeature[], boolean, float, RunHandler)
- Shaper::shape(String, Iterator<FontRun>, Iterator<BidiRun>, Iterator<ScriptRun>, Iterator<LanguageRun>, FontFeature[], float width, RunHandler)
- Shaper::shape(ManagedString, Iterator<FontRun>, Iterator<BidiRun>, Iterator<ScriptRun>, Iterator<LanguageRun>, FontFeature[], float width, RunHandler)
- Shaper::shapeLine(String, Font, FontFeature[], boolean)

to:

- TextLine::make(String, Font, ShapingOptions)
- FontMgrRunIterator(ManagedString, boolean, Font, ShapingOptions)
- FontMgrRunIterator(String, Font, ShapingOptions)
- Shaper::shape(String, Font, ShapingOptions, float, Point)
- Shaper::shape(String, Font, FontMgr, ShapingOptions, float, RunHandler)
- Shaper::shape(String, Iterator<FontRun>, Iterator<BidiRun>, Iterator<ScriptRun>, Iterator<LanguageRun>, ShapingOptions, float width, RunHandler)
- Shaper::shape(ManagedString, Iterator<FontRun>, Iterator<BidiRun>, Iterator<ScriptRun>, Iterator<LanguageRun>, ShapingOptions, float width, RunHandler)
- Shaper::shapeLine(String, Font, ShapingOptions)

# 0.93.0 - Aug 10, 2021

Changed:
Expand Down
5 changes: 3 additions & 2 deletions examples/jwm/script/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--skija-version')
parser.add_argument('--jwm-version', default='0.1.3')
parser.add_argument('--jwm-version', default='0.1.170')
parser.add_argument('--jwm-dir', default=None)
(args, _) = parser.parse_known_args()

Expand Down Expand Up @@ -46,14 +46,15 @@ def main():
os.chdir(common.root + '/examples/jwm')

sources = common.glob('src', '*.java') + common.glob('../scenes/src', '*.java')
common.javac(sources, 'target/classes', classpath = classpath)
common.javac(sources, 'target/classes', classpath = classpath, release = '15', opts = ['--enable-preview'])

# Java
common.check_call([
'java',
'--class-path', common.classpath_separator.join(['target/classes'] + classpath)]
+ (['-XstartOnFirstThread'] if 'macos' == common.system else [])
+ ['-Djava.awt.headless=true',
'--enable-preview',
'-enableassertions',
'-enablesystemassertions',
'-Xcheck:jni',
Expand Down
69 changes: 39 additions & 30 deletions examples/jwm/src/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,17 @@ public class Main implements Consumer<Event> {

public Main() {
Stats.enabled = true;
_window = App.makeWindow();
_window.setEventListener(this);
changeLayer();
var scale = _window.getScale();
_window.resize((int) (1440 * scale), (int) (810 * scale));
_window.move((int) (240 * scale), (int) (135 * scale));
_window.show();
accept(EventReconfigure.INSTANCE);
_window.requestFrame();
App.makeWindow((window) -> {
_window = window;
_window.setEventListener(this);
changeLayer();
var scale = _window.getScale();
_window.resize((int) (1440 * scale), (int) (810 * scale));
_window.move((int) (240 * scale), (int) (135 * scale));
_window.show();
accept(EventReconfigure.INSTANCE);
_window.requestFrame();
});
}

public void paint() {
Expand Down Expand Up @@ -78,28 +80,35 @@ public void accept(Event e) {
} else if (e instanceof EventMouseMove) {
_xpos = (int) (((EventMouseMove) e).getX() / _window.getScale());
_ypos = (int) (((EventMouseMove) e).getY() / _window.getScale());
} else if (e instanceof EventKeyboard) {
EventKeyboard eventKeyboard = (EventKeyboard) e;
} else if (e instanceof EventKeyboard eventKeyboard) {
if (eventKeyboard.isPressed() == true) {
if (eventKeyboard.getKeyCode() == 1) { // s
Scenes.stats = !Scenes.stats;
Stats.enabled = Scenes.stats;
} else if (eventKeyboard.getKeyCode() == 5) { // g
System.out.println("Before GC " + Stats.allocated);
System.gc();
} else if (eventKeyboard.getKeyCode() == 37) { // l
_layerIdx = (_layerIdx + _layers.length - 1) % _layers.length;
changeLayer();
} else if (eventKeyboard.getKeyCode() == 123) { // ←
Scenes.prevScene();
} else if (eventKeyboard.getKeyCode() == 124) { // →
Scenes.nextScene();
} else if (eventKeyboard.getKeyCode() == 125) { // ↓
Scenes.currentScene().changeVariant(1);
} else if (eventKeyboard.getKeyCode() == 126) { // ↑
Scenes.currentScene().changeVariant(-1);
} else
System.out.println("Key pressed: " + eventKeyboard.getKeyCode());
switch (eventKeyboard.getKey()) {
case S -> {
Scenes.stats = !Scenes.stats;
Stats.enabled = Scenes.stats;
}
case G -> {
System.out.println("Before GC " + Stats.allocated);
System.gc();
}
case L -> {
_layerIdx = (_layerIdx + _layers.length - 1) % _layers.length;
changeLayer();
}
case LEFT ->
Scenes.prevScene();

case RIGHT ->
Scenes.nextScene();

case DOWN ->
Scenes.currentScene().changeVariant(1);

case UP ->
Scenes.currentScene().changeVariant(-1);
default ->
System.out.println("Key pressed: " + eventKeyboard.getKey());
}
}
} else if (e instanceof EventFrame) {
paint();
Expand Down
19 changes: 16 additions & 3 deletions examples/scenes/src/RunHandlerScene.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ public class RunHandlerScene extends Scene {
public RunHandlerScene() {
lato36 = new Font(Typeface.makeFromFile(file("fonts/Lato-Regular.ttf")), 36);
inter9 = new Font(inter, 9);

_variants = new String[] {
"Approximate All",
"Approximate Spaces",
"Approximate Punctuation",
"Approximate None",
};
}

@Override
Expand All @@ -26,15 +33,22 @@ public void draw(Canvas canvas, int width, int height, float dpi, int xpos, int
var tbHandler = new TextBlobBuilderRunHandler(text, new Point(0, 0));
var handler = new DebugTextBlobHandler().withRuns();)
{
var opts = switch (_variants[_variantIdx]) {
case "Approximate Spaces" -> ShapingOptions.DEFAULT.withApproximatePunctuation(false);
case "Approximate Punctuation" -> ShapingOptions.DEFAULT.withApproximateSpaces(false);
case "Approximate None" -> ShapingOptions.DEFAULT.withApproximateSpaces(false).withApproximatePunctuation(false);
default -> ShapingOptions.DEFAULT;
};

// TextBlobBuilderRunHandler
shaper.shape(text, lato36, FontMgr.getDefault(), null, true, width - 40, tbHandler);
shaper.shape(text, lato36, opts, width - 40, tbHandler);
try (var blob = tbHandler.makeBlob()) {
canvas.drawTextBlob(blob, 0, 0, textFill);
canvas.translate(0, blob.getBounds().getBottom() + 20);
}

// DebugTextBlobHandler
shaper.shape(text, lato36, FontMgr.getDefault(), null, true, width - 40, handler);
shaper.shape(text, lato36, opts, width - 40, handler);

try (var blob = handler.makeBlob()) {
canvas.drawTextBlob(blob, 0, 0, textFill);
Expand Down Expand Up @@ -69,7 +83,6 @@ public void draw(Canvas canvas, int width, int height, float dpi, int xpos, int
builder.appendRun(inter9, "clusters " + Arrays.toString(run.getClusters()), 0, yPos + lh * 7);

try (var detailsBlob = builder.build(); ) {

// try to fit in
var detailsWidth = detailsBlob.getBounds().getWidth();
var detailsHeight = detailsBlob.getBounds().getHeight();
Expand Down
18 changes: 9 additions & 9 deletions examples/scenes/src/RunIteratorScene.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,17 @@ public void draw(Canvas canvas, int width, int height, float dpi, int xpos, int
var bidiIter = new TrivialBidiRunIterator(text, Bidi.DIRECTION_LEFT_TO_RIGHT);
var scriptIter = new TrivialScriptRunIterator(text, "latn");
var langIter = new TrivialLanguageRunIterator(text, "en-US");
shaper.shape(text, fontIter, bidiIter, scriptIter, langIter, null, width - 40, handler);
shaper.shape(text, fontIter, bidiIter, scriptIter, langIter, ShapingOptions.DEFAULT, width - 40, handler);
drawBlob(canvas, handler, "All trivial");
}

try (var handler = new DebugTextBlobHandler().withRuns();
var fontIter = new FontMgrRunIterator(text, lato36, null);)
var fontIter = new FontMgrRunIterator(text, lato36);)
{
var bidiIter = new TrivialBidiRunIterator(text, Bidi.DIRECTION_LEFT_TO_RIGHT);
var scriptIter = new TrivialScriptRunIterator(text, "latn");
var langIter = new TrivialLanguageRunIterator(text, "en-US");
shaper.shape(text, fontIter, bidiIter, scriptIter, langIter, null, width - 40, handler);
shaper.shape(text, fontIter, bidiIter, scriptIter, langIter, ShapingOptions.DEFAULT, width - 40, handler);
drawBlob(canvas, handler, "FontMgrRunIterator");
}

Expand All @@ -69,7 +69,7 @@ public void draw(Canvas canvas, int width, int height, float dpi, int xpos, int
var bidiIter = new TrivialBidiRunIterator(text, Bidi.DIRECTION_LEFT_TO_RIGHT);
var scriptIter = new TrivialScriptRunIterator(text, "latn");
var langIter = new TrivialLanguageRunIterator(text, "en-US");
shaper.shape(text, fontIter, bidiIter, scriptIter, langIter, null, width - 40, handler);
shaper.shape(text, fontIter, bidiIter, scriptIter, langIter, ShapingOptions.DEFAULT, width - 40, handler);
drawBlob(canvas, handler, "CustomFontRunIterator");
}

Expand All @@ -79,7 +79,7 @@ public void draw(Canvas canvas, int width, int height, float dpi, int xpos, int
var fontIter = new TrivialFontRunIterator(text, lato36);
var scriptIter = new TrivialScriptRunIterator(text, "latn");
var langIter = new TrivialLanguageRunIterator(text, "en-US");
shaper.shape(text, fontIter, bidiIter, scriptIter, langIter, null, width - 40, handler);
shaper.shape(text, fontIter, bidiIter, scriptIter, langIter, ShapingOptions.DEFAULT, width - 40, handler);
drawBlob(canvas, handler, "IcuBidiRunIterator");
}

Expand All @@ -89,7 +89,7 @@ public void draw(Canvas canvas, int width, int height, float dpi, int xpos, int
var bidiIter = new JavaTextBidiRunIterator(text);
var scriptIter = new TrivialScriptRunIterator(text, "latn");
var langIter = new TrivialLanguageRunIterator(text, "en-US");
shaper.shape(text, fontIter, bidiIter, scriptIter, langIter, null, width - 40, handler);
shaper.shape(text, fontIter, bidiIter, scriptIter, langIter, ShapingOptions.DEFAULT, width - 40, handler);
drawBlob(canvas, handler, "JavaTextBidiRunIterator");
}

Expand All @@ -99,17 +99,17 @@ public void draw(Canvas canvas, int width, int height, float dpi, int xpos, int
var fontIter = new TrivialFontRunIterator(text, lato36);
var bidiIter = new TrivialBidiRunIterator(text, Bidi.DIRECTION_LEFT_TO_RIGHT);
var langIter = new TrivialLanguageRunIterator(text, "en-US");
shaper.shape(text, fontIter, bidiIter, scriptIter, langIter, null, width - 40, handler);
shaper.shape(text, fontIter, bidiIter, scriptIter, langIter, ShapingOptions.DEFAULT, width - 40, handler);
drawBlob(canvas, handler, "HbIcuScriptRunIterator");
}

try (var handler = new DebugTextBlobHandler().withRuns();
var fontIter = new FontMgrRunIterator(text, lato36, null);
var fontIter = new FontMgrRunIterator(text, lato36);
var bidiIter = new IcuBidiRunIterator(text, Bidi.DIRECTION_LEFT_TO_RIGHT);
var scriptIter = new HbIcuScriptRunIterator(text);)
{
var langIter = new TrivialLanguageRunIterator(text, "en-US");
shaper.shape(text, fontIter, bidiIter, scriptIter, langIter, null, width - 40, handler);
shaper.shape(text, fontIter, bidiIter, scriptIter, langIter, ShapingOptions.DEFAULT, width - 40, handler);
drawBlob(canvas, handler, "All native");
}
}
Expand Down
2 changes: 1 addition & 1 deletion examples/scenes/src/Scenes.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

public class Scenes {
public static TreeMap<String, Scene> scenes;
public static String currentScene = "Runtime Effect";
public static String currentScene = "Run Handler";
public static HUD hud = new HUD();
public static boolean stats = true;

Expand Down
10 changes: 5 additions & 5 deletions examples/scenes/src/ShapersScene.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,31 @@ public void drawWithShaper(Canvas canvas, float maxWidth, int color, String name
fill.setColor(color);
String text = "Incomprehensibilities word word word word ararar123456 +++ <-> *** c̝̣̱̲͈̝ͨ͐̈ͪͨ̃ͥͅh̙̬̿̂a̯͎͍̜͐͌͂̚o̬s͉̰͊̀ " + name;

try (var blob = shaper.shape(text, firaCode11, null, true, maxWidth, new Point(0, 0)); ) {
try (var blob = shaper.shape(text, firaCode11, ShapingOptions.DEFAULT, maxWidth, new Point(0, 0)); ) {
canvas.drawTextBlob(blob, 0, 0, fill);
canvas.translate(0, blob.getBounds().getHeight());
}

try (var blob = shaper.shape(text + " RTL", firaCode11, null, false, maxWidth, new Point(0, 0)); ) {
try (var blob = shaper.shape(text + " RTL", firaCode11, ShapingOptions.DEFAULT.withLeftToRight(false), maxWidth, new Point(0, 0)); ) {
canvas.drawTextBlob(blob, 0, 0, fill);
canvas.translate(0, blob.getBounds().getHeight());
}

String features = "ss01 cv01 onum -calt";
try (var blob = shaper.shape(text + " " + features, firaCode11, FontFeature.parse(features), true, maxWidth, new Point(0, 0)); ) {
try (var blob = shaper.shape(text + " " + features, firaCode11, ShapingOptions.DEFAULT.withFeatures(features), maxWidth, new Point(0, 0)); ) {
canvas.drawTextBlob(blob, 0, 0, fill);
canvas.translate(0, blob.getBounds().getHeight());
}

features = "ss01[42:45] cv01[42:45] onum[48:51] calt[59:60]=0";
try (var blob = shaper.shape(text + " " + features, firaCode11, FontFeature.parse(features), true, maxWidth, new Point(0, 0)); ) {
try (var blob = shaper.shape(text + " " + features, firaCode11, ShapingOptions.DEFAULT.withFeatures(features), maxWidth, new Point(0, 0)); ) {
canvas.drawTextBlob(blob, 0, 0, fill);
canvas.translate(0, blob.getBounds().getHeight());
}

float height = 0;

try (var blob = shaper.shape(text, firaCode11, null, true, 75, new Point(0, 0)); ) {
try (var blob = shaper.shape(text, firaCode11, ShapingOptions.DEFAULT, 75, new Point(0, 0)); ) {
canvas.drawTextBlob(blob, 0, 0, fill);
Rect bounds = blob.getBounds();
canvas.drawRect(Rect.makeXYWH(0, 0, 75, bounds.getHeight()), stroke);
Expand Down
11 changes: 7 additions & 4 deletions examples/scenes/src/TextShapeBenchScene.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ public TextShapeBenchScene() {
_variants = new String[] {
"Tabs Paragraph", "Tabs Paragraph No-Cache", "Tabs TextLine",
"Emoji Paragraph", "Emoji Paragraph No-Cache", "Emoji TextLine",
"Greek Paragraph", "Greek Paragraph No-Cache", "Greek TextLine",
"Greek Paragraph", "Greek Paragraph No-Cache", "Greek TextLine", "Greek TextLine No-Approx",
"Notdef Paragraph", "Notdef Paragraph No-Cache", "Notdef TextLine",
"English Paragraph", "English Paragraph No-Cache", "English TextLine",
};
_variantIdx = 5;
_variantIdx = 9;

font = new Font(jbMono, fontSize).setSubpixel(true);
metrics = font.getMetrics();
Expand Down Expand Up @@ -67,12 +67,15 @@ else if ("English".equals(variant[0]))
}
}
}
} else {
} else { // TextLine
try (var shaper = Shaper.makeShapeDontWrapOrReorder();) {
for (int i = 1; true; ++i) {
float y = i * padding;
if (y > height - padding) break;
try (var line = shaper.shapeLine(i + " [" + text + "]", font, null, true);) {
try (var line = variant.length > 2 // No-Approx
? shaper.shapeLine(i + " [" + text + "]", font, ShapingOptions.DEFAULT.withApproximateSpaces(false).withApproximatePunctuation(false))
: shaper.shapeLine(i + " [" + text + "]", font))
{
canvas.drawTextLine(line, padding, y - metrics.getAscent(), blackFill);
canvas.drawRect(Rect.makeXYWH(padding, y, line.getWidth(), metrics.getHeight()), redStroke);
for (float x: TextLine._nGetRunPositions(line._ptr))
Expand Down
2 changes: 1 addition & 1 deletion examples/scenes/src/WallOfTextScene.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ void drawParagraph(Canvas canvas, float fontSize, float padding, float textWidth
TextBlob makeBlob(String text, Shaper shaper, float textWidth) {
if (_variants[_variantIdx].startsWith("JVM RunHandler")) {
try (var handler = new DebugTextBlobHandler();) {
shaper.shape(text, font, FontMgr.getDefault(), null, true, textWidth, handler);
shaper.shape(text, font, ShapingOptions.DEFAULT, textWidth, handler);
return handler.makeBlob();
}
} else
Expand Down
13 changes: 13 additions & 0 deletions platform/cc/interop.cc
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,19 @@ namespace skija {
}
}

namespace FontMgr {
jclass cls;

void onLoad(JNIEnv* env) {
jclass local = env->FindClass("org/jetbrains/skija/FontMgr");
cls = static_cast<jclass>(env->NewGlobalRef(local));
}

void onUnload(JNIEnv* env) {
env->DeleteGlobalRef(cls);
}
}

namespace FontStyle {
SkFontStyle fromJava(jint style) {
return SkFontStyle(style & 0xFFFF, (style >> 16) & 0xFF, static_cast<SkFontStyle::Slant>((style >> 24) & 0xFF));
Expand Down
6 changes: 6 additions & 0 deletions platform/cc/interop.hh
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,12 @@ namespace skija {
jobject toJava(JNIEnv* env, const SkFontMetrics& m);
}

namespace FontMgr {
extern jclass cls;
void onLoad(JNIEnv* env);
void onUnload(JNIEnv* env);
}

namespace FontStyle {
SkFontStyle fromJava(jint style);
jint toJava(const SkFontStyle& fs);
Expand Down

0 comments on commit 5fb057b

Please sign in to comment.