Skip to content

Commit

Permalink
TextBlob::getBlockBounds
Browse files Browse the repository at this point in the history
  • Loading branch information
tonsky committed Dec 18, 2020
1 parent b004ff9 commit 4fa2bb5
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public void drawSelection(Canvas canvas, float dx, float dy) {
TextStyle largeTs = new TextStyle().setFontSize(36).setColor(0xFF000000);
TextStyle smallTs = new TextStyle().setFontSize(12).setColor(0xFF000000);
TextStyle ligaTs = new TextStyle().setFontSize(24).setColor(0xFF000000).setFontFamilies(new String[] { "Interface" });
TextStyle zapfinoTs = new TextStyle().setFontSize(24).setColor(0xFF000000).setFontFamilies(new String[] { "Zapfino" });
ParagraphStyle ps = new ParagraphStyle();
ParagraphBuilder pb = new ParagraphBuilder(ps, fc);
ParagraphStyle ps2 = new ParagraphStyle().setAlignment(Alignment.RIGHT);)
Expand Down Expand Up @@ -71,7 +72,12 @@ public void drawSelection(Canvas canvas, float dx, float dy) {
pb.pushStyle(defaultTs);
pb.addText("— Vicious circularity, \n");
pb.pushStyle(smallTs);
pb.addText(" or infinite regress");
pb.addText(" or infinite regress\n");
pb.popStyle();

pb.addText("hello мир дружба fi fl 👃 one two ثلاثة 12 👂 34 خمسة\n");
pb.pushStyle(zapfinoTs);
pb.addText("fiz officiad\n");
pb.popStyle();

try (Paragraph p = pb.build();) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class TextBlobBoundsScene extends Scene {
private Font zapfino18 = new Font(FontMgr.getDefault().matchFamilyStyle("Zapfino", FontStyle.NORMAL), 18);

public TextBlobBoundsScene() {
_variants = new String[] { "Tight", "Loose" };
_variants = new String[] { "Block", "Tight", "Loose" };
}

public void drawLine(Canvas canvas, String text, Font font) {
Expand All @@ -33,7 +33,13 @@ public void drawLine(Canvas canvas, String[] texts, Font font, float width) {
try (var shaper = Shaper.makeShapeThenWrap();
var blob = shaper.shape(text, font, width);)
{
var bounds = "Tight".equals(variantTitle()) ? blob.getTightBounds() : blob.getBounds();
Rect bounds;
if ("Block".equals(variantTitle()))
bounds = blob.getBlockBounds();
else if ("Tight".equals(variantTitle()))
bounds = blob.getTightBounds();
else // if ("Loose".equals(variantTitle()))
bounds = blob.getBounds();
canvas.drawCircle(0, 0, 3, stroke);
canvas.drawRect(bounds, stroke);
canvas.drawTextBlob(blob, 0, 0, font, fill);
Expand All @@ -54,6 +60,6 @@ public void draw(Canvas canvas, int width, int height, float dpi, int xpos, int
drawLine(canvas, "multiple different lines", inter18, 50);
drawLine(canvas, new String[] { "ace", "الخطوط", "🧛", "ace الخطوط 🧛" }, inter18);
drawLine(canvas, "واحد اثنين ثلاثة", inter18);
drawLine(canvas, "fiz", zapfino18);
drawLine(canvas, new String[] { "fiz", "officiad", "fiz officiad"}, zapfino18);
}
}
26 changes: 26 additions & 0 deletions native/src/TextBlob.cc
Original file line number Diff line number Diff line change
Expand Up @@ -247,4 +247,30 @@ extern "C" JNIEXPORT jobject JNICALL Java_org_jetbrains_skija_TextBlob__1nGetTig
bounds.join(tmpBounds);
}
return skija::Rect::fromSkRect(env, bounds);
}

extern "C" JNIEXPORT jobject JNICALL Java_org_jetbrains_skija_TextBlob__1nGetBlockBounds
(JNIEnv* env, jclass jclass, jlong ptr) {
SkTextBlob* instance = reinterpret_cast<SkTextBlob*>(static_cast<uintptr_t>(ptr));
SkTextBlob::Iter iter(*instance);
SkTextBlob::Iter::Run run;
SkScalar right = 0;
SkScalar bottom = 0;
SkFontMetrics metrics;
SkGlyphID glyph;
SkScalar width;
while (iter.next(&run)) {
// run.fGlyphIndices points directly to runRecord.glyphBuffer(), which comes directly after RunRecord itself
auto runRecord = reinterpret_cast<const RunRecordClone*>(run.fGlyphIndices) - 1;
if (runRecord->positioning() != 2) // kFull_Positioning
return nullptr;

const SkFont& font = runRecord->fFont;
font.getMetrics(&metrics);
bottom = std::max(bottom, runRecord->posBuffer()[1] + metrics.fDescent);

font.getWidths(&runRecord->glyphBuffer()[runRecord->fCount - 1], 1, &width);
right = std::max(right, runRecord->posBuffer()[runRecord->fCount * 2 - 2] + width);
}
return skija::Rect::fromSkRect(env, SkRect {0, 0, right, bottom});
}
20 changes: 20 additions & 0 deletions shared/src/main/java/org/jetbrains/skija/TextBlob.java
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,25 @@ public Rect getTightBounds() {
}
}

/**
* Only works on TextBlobs that come from TextBlobBuilderRunHandler/Shaper default handler.
*
* @return tight bounds around all the glyphs in the TextBlob
* @throws IllegalArgumentException if TextBlob doesn’t have this information
*/
@NotNull
public Rect getBlockBounds() {
try {
Stats.onNativeCall();
Rect res = _nGetBlockBounds(_ptr);
if (res == null)
throw new IllegalArgumentException();
return res;
} finally {
Reference.reachabilityFence(this);
}
}

@ApiStatus.Internal
public static class _FinalizerHolder {
public static final long PTR = _nGetFinalizer();
Expand All @@ -241,4 +260,5 @@ public static class _FinalizerHolder {
@ApiStatus.Internal public static native float[] _nGetPositions(long ptr);
@ApiStatus.Internal public static native int[] _nGetClusters(long ptr);
@ApiStatus.Internal public static native Rect _nGetTightBounds(long ptr);
@ApiStatus.Internal public static native Rect _nGetBlockBounds(long ptr);
}

0 comments on commit 4fa2bb5

Please sign in to comment.