@@ -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 */
18001820public 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