Skip to content

Commit 0f7a1c6

Browse files
committed
Issue #932: [cocoa] implementation for StyledText.setFixedLineMetrics
Signed-off-by: Alexandr Miloslavskiy <[email protected]>
1 parent ce84c3c commit 0f7a1c6

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/FontMetrics.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,19 @@ public final class FontMetrics {
3131
FontMetrics() {
3232
}
3333

34+
/**
35+
* Convenience method to make a copy of receiver.
36+
*/
37+
FontMetrics makeCopy () {
38+
FontMetrics fontMetrics = new FontMetrics();
39+
fontMetrics.ascent = this.ascent;
40+
fontMetrics.descent = this.descent;
41+
fontMetrics.averageCharWidth = this.averageCharWidth;
42+
fontMetrics.leading = this.leading;
43+
fontMetrics.height = this.height;
44+
return fontMetrics;
45+
}
46+
3447
public static FontMetrics cocoa_new (int ascent, int descent, int averageCharWidth, int leading, int height) {
3548
FontMetrics fontMetrics = new FontMetrics();
3649
fontMetrics.ascent = ascent;

bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/TextLayout.java

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ public final class TextLayout extends Resource {
5454
int wrapWidth;
5555
int orientation;
5656
private double defaultTabWidth;
57+
private FontMetrics fixedLineMetrics;
58+
private double fixedLineMetricsDy;
5759

5860
int[] lineOffsets;
5961
NSRect[] lineBounds;
@@ -349,6 +351,16 @@ void computeRuns() {
349351
OS.memmove(lineRange, rangePtr, NSRange.sizeof);
350352
offsets[numberOfLines] = (int)lineRange.location;
351353
index = lineRange.location + lineRange.length;
354+
if (fixedLineMetrics != null) {
355+
// Preserve baseline location for best visual results
356+
final int lineOffset = untranslateOffset(offsets[numberOfLines]);
357+
final double realHeight = bounds[numberOfLines].height;
358+
final double realDescent = layoutManager.typesetter().baselineOffsetInLayoutManager(layoutManager, lineOffset);
359+
final double realAscent = realHeight - realDescent;
360+
final double wantAscent = fixedLineMetrics.ascent;
361+
fixedLineMetricsDy = wantAscent - realAscent;
362+
bounds[numberOfLines].height = fixedLineMetrics.height;
363+
}
352364
}
353365
if (numberOfLines == 0) {
354366
Font font = this.font != null ? this.font : device.systemFont;
@@ -484,6 +496,7 @@ public void draw(GC gc, int x, int y, int selectionStart, int selectionEnd, Colo
484496
fixRect(rect);
485497
rect.x += pt.x;
486498
rect.y += pt.y;
499+
if (fixedLineMetrics != null) rect.height = fixedLineMetrics.height;
487500
rect.height = Math.max(rect.height, ascent + descent);
488501
path.appendBezierPathWithRect(rect);
489502
}
@@ -515,9 +528,13 @@ public void draw(GC gc, int x, int y, int selectionStart, int selectionEnd, Colo
515528
layoutManager.addTemporaryAttribute(OS.NSForegroundColorAttributeName, gc.data.fg, range);
516529
}
517530
}
531+
NSPoint ptGlyphs = new NSPoint();
532+
ptGlyphs.x = pt.x;
533+
ptGlyphs.y = pt.y;
534+
if (fixedLineMetrics != null) ptGlyphs.y += fixedLineMetricsDy;
518535
range.location = 0;
519536
range.length = numberOfGlyphs;
520-
layoutManager.drawGlyphsForGlyphRange(range, pt);
537+
layoutManager.drawGlyphsForGlyphRange(range, ptGlyphs);
521538
if (!defaultFg) {
522539
range.location = 0;
523540
range.length = length;
@@ -754,6 +771,7 @@ public Rectangle getBounds() {
754771
NSFont nsFont = font.handle;
755772
rect.height = layoutManager.defaultLineHeightForFont(nsFont);
756773
}
774+
if (fixedLineMetrics != null) rect.height = fixedLineMetrics.height;
757775
rect.height = Math.max(rect.height, ascent + descent) + spacing;
758776
return new Rectangle(0, 0, (int)Math.ceil(rect.width), (int)Math.ceil(rect.height) + getVerticalIndent());
759777
} finally {
@@ -804,6 +822,7 @@ public Rectangle getBounds(int start, int end) {
804822
top = Math.min(top, (int)rect.y);
805823
bottom = Math.max(bottom, (int)Math.ceil(rect.y + rect.height));
806824
}
825+
if (fixedLineMetrics != null) bottom = top + fixedLineMetrics.height;
807826
return new Rectangle(left, top, right - left, bottom - top + getVerticalIndent());
808827
} finally {
809828
if (pool != null) pool.release();
@@ -1043,6 +1062,7 @@ public FontMetrics getLineMetrics (int lineIndex) {
10431062
computeRuns();
10441063
int lineCount = getLineCount();
10451064
if (!(0 <= lineIndex && lineIndex < lineCount)) SWT.error(SWT.ERROR_INVALID_RANGE);
1065+
if (fixedLineMetrics != null) return fixedLineMetrics.makeCopy();
10461066
int length = text.length();
10471067
if (length == 0) {
10481068
Font font = this.font != null ? this.font : device.systemFont;
@@ -1798,8 +1818,12 @@ public void setDescent (int descent) {
17981818
* @since 3.125
17991819
*/
18001820
public void setFixedLineMetrics (FontMetrics metrics) {
1801-
if (metrics == null) return;
1802-
SWT.error(SWT.ERROR_NOT_IMPLEMENTED);
1821+
if (metrics == null) {
1822+
fixedLineMetrics = null;
1823+
return;
1824+
}
1825+
1826+
fixedLineMetrics = metrics.makeCopy();
18031827
}
18041828

18051829
/**

0 commit comments

Comments
 (0)