Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DrawTextLayout alignment #368

Open
mischnic opened this issue May 20, 2018 · 3 comments · May be fixed by #407
Open

DrawTextLayout alignment #368

mischnic opened this issue May 20, 2018 · 3 comments · May be fixed by #407
Milestone

Comments

@mischnic
Copy link
Contributor

mischnic commented May 20, 2018

On macOS, the other alignment types don't really respect uiDrawTextLayoutParams.Width, but rather the longest line:

bildschirmfoto 2018-05-20 um 23 28 46
bildschirmfoto 2018-05-20 um 23 28 49

@mischnic
Copy link
Contributor Author

The problem is that

libui/darwin/drawtext.m

Lines 67 to 75 in 2f0e6e9

cgwidth = (CGFloat) (p->Width);
if (cgwidth < 0)
cgwidth = CGFLOAT_MAX;
self->size = CTFramesetterSuggestFrameSizeWithConstraints(self->framesetter,
range,
// TODO kCTFramePathWidthAttributeName?
NULL,
CGSizeMake(cgwidth, CGFLOAT_MAX),
&unused); // not documented as accepting NULL (TODO really?)

creates a frame which is smaller than p->Width and the aligned paragraphs use that smaller frame.

Fix (not very clean):

diff --git a/darwin/drawtext.m b/darwin/drawtext.m
index c04b402b..22de269c 100644
--- a/darwin/drawtext.m
+++ b/darwin/drawtext.m
@@ -76,6 +76,7 @@
		cgwidth = (CGFloat) (p->Width);
		if (cgwidth < 0)
			cgwidth = CGFLOAT_MAX;
		self->size = CTFramesetterSuggestFrameSizeWithConstraints(self->framesetter,
			range,
			// TODO kCTFramePathWidthAttributeName?
			NULL,
			CGSizeMake(cgwidth, CGFLOAT_MAX),
			&unused);			// not documented as accepting NULL (TODO really?)

                rect.origin = CGPointZero;
                rect.size = self->size;
+               rect.size.width = cgwidth;
                self->path = CGPathCreateWithRect(rect, NULL);
                self->frame = CTFramesetterCreateFrame(self->framesetter,
                        range,
			self->path,
			// TODO kCTFramePathWidthAttributeName?
			NULL);

@andlabs
Copy link
Owner

andlabs commented May 31, 2018

I am also going to add a tiny string option to that example program, temporarily to test things like this while I don't have a more "proper" test framework (and the tester program is getting to be quite much). Not sure if I will use that exact fix or not; I forget what my previous drawtext code did.

@mischnic
Copy link
Contributor Author

I forget what my previous drawtext code did.

libui/darwin/drawtext.m

Lines 511 to 532 in 7891cd8

static void mkFramesetter(uiDrawTextLayout *layout, struct framesetter *fs)
{
CFRange fitRange;
CGFloat width;
fs->fs = CTFramesetterCreateWithAttributedString(layout->mas);
if (fs->fs == NULL)
complain("error creating CTFramesetter object in mkFramesetter()");
// TODO kCTFramePathWidthAttributeName?
fs->frameAttrib = NULL;
width = layout->width;
if (layout->width < 0)
width = CGFLOAT_MAX;
// TODO these seem to be floor()'d or truncated?
fs->extents = CTFramesetterSuggestFrameSizeWithConstraints(fs->fs,
CFRangeMake(0, 0),
fs->frameAttrib,
CGSizeMake(width, CGFLOAT_MAX),
&fitRange); // not documented as accepting NULL
}

libui/darwin/drawtext.m

Lines 569 to 600 in 7891cd8

void doDrawText(CGContextRef c, CGFloat cheight, double x, double y, uiDrawTextLayout *layout)
{
struct framesetter fs;
CGRect rect;
CGPathRef path;
CTFrameRef frame;
prepareContextForText(c, cheight, &y);
mkFramesetter(layout, &fs);
// oh, and since we're flipped, y is the bottom-left coordinate of the rectangle, not the top-left
// since we are flipped, we subtract
y -= fs.extents.height;
rect.origin = CGPointMake(x, y);
rect.size = fs.extents;
path = CGPathCreateWithRect(rect, NULL);
frame = CTFramesetterCreateFrame(fs.fs,
CFRangeMake(0, 0),
path,
fs.frameAttrib);
if (frame == NULL)
complain("error creating CTFrame object in doDrawText()");
CTFrameDraw(frame, c);
CFRelease(frame);
CFRelease(path);
freeFramesetter(&fs);
CGContextRestoreGState(c);
}

@mischnic mischnic linked a pull request Aug 9, 2018 that will close this issue
@andlabs andlabs added this to the Alpha 5 milestone Dec 31, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants