summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinh Nguyễn <mxn@1ec5.org>2020-04-20 16:51:21 -0700
committerMinh Nguyễn <mxn@1ec5.org>2020-04-22 21:28:30 -0700
commit1c93b8622d3bc2800086d89c549c91bde445497b (patch)
tree0101e369b7d5acd7d936f2b1d936671e0b7253d1
parent98427268c5f2b6e669b7e564cf450e79d374cca7 (diff)
downloadqtlocation-mapboxgl-1c93b8622d3bc2800086d89c549c91bde445497b.tar.gz
[ios, macos] Fixed bounding boxes
-rw-r--r--platform/darwin/src/local_glyph_rasterizer.mm18
-rw-r--r--platform/darwin/src/shaping.mm25
2 files changed, 29 insertions, 14 deletions
diff --git a/platform/darwin/src/local_glyph_rasterizer.mm b/platform/darwin/src/local_glyph_rasterizer.mm
index c83a06ac83..fe5a5218a4 100644
--- a/platform/darwin/src/local_glyph_rasterizer.mm
+++ b/platform/darwin/src/local_glyph_rasterizer.mm
@@ -153,11 +153,17 @@ PremultipliedImage drawGlyphBitmap(GlyphID glyphID, CTFontRef font, Size size) {
throw std::runtime_error("CGBitmapContextCreate failed");
}
- // Move the text upward to avoid clipping off descenders.
+ CGContextSetShouldSubpixelPositionFonts(*context, false);
+ CGContextSetShouldSubpixelQuantizeFonts(*context, false);
+
CGPoint positions[1];
- positions[0] = CGPointMake(0.0, 5.0);
+ positions[0] = CGPointMake(0.0, 0.0);
CTFontDrawGlyphs(font, glyphs, positions, 1, *context);
+ const CGFloat *black = CGColorGetComponents(CGColorGetConstantColor(kCGColorBlack));
+ CGContextSetFillColor(*context, black);
+ CGContextFillRect(*context, CGRectMake(0, 0, size.width, size.height));
+
return rgbaBitmap;
}
@@ -187,17 +193,17 @@ Glyph LocalGlyphRasterizer::rasterizeGlyph(const FontStack& fontStack, GlyphID g
if (CGRectIsNull(boundingRect)) {
throw std::runtime_error("CTFontGetBoundingRectsForGlyphs failed");
}
+ manufacturedGlyph.metrics.left = std::round(CGRectGetMinX(boundingRects[0]));
+ manufacturedGlyph.metrics.top = std::round(CGRectGetMinY(boundingRects[0]));
// Mimic glyph PBF metrics.
- manufacturedGlyph.metrics.left = 3;
- manufacturedGlyph.metrics.top = -1;
manufacturedGlyph.metrics.width = 35;
manufacturedGlyph.metrics.height = 35;
CGSize advances[1];
CTFontGetAdvancesForGlyphs(*font, orientation, glyphs, advances, 1);
- manufacturedGlyph.metrics.advance = 24;
+ manufacturedGlyph.metrics.advance = std::ceil(advances[0].width);
- Size size(manufacturedGlyph.metrics.width, manufacturedGlyph.metrics.height);
+ Size size(MAX(manufacturedGlyph.metrics.width, 1), MAX(manufacturedGlyph.metrics.height, 1));
PremultipliedImage rgbaBitmap = drawGlyphBitmap(glyphID, *font, size);
// Copy alpha values from RGBA bitmap into the AlphaImage output
diff --git a/platform/darwin/src/shaping.mm b/platform/darwin/src/shaping.mm
index 0ecf93c0cc..753bb2b386 100644
--- a/platform/darwin/src/shaping.mm
+++ b/platform/darwin/src/shaping.mm
@@ -160,8 +160,9 @@ Shaping getShaping(const TaggedString& formattedString,
float layoutTextSize,
float layoutTextSizeAtBucketZoomLevel,
bool allowVerticalPlacement) {
-// const float maxHeight = 200; // TODO: What’s a big enough height to not constrain any label?
- const bool vertical = writingMode != WritingModeType::Horizontal && allowVerticalPlacement;
+ // TODO: Vertical text.
+// const bool vertical = writingMode != WritingModeType::Horizontal && allowVerticalPlacement;
+ const bool vertical = false;
CTFontOrientation orientation = vertical ? kCTFontOrientationVertical : kCTFontOrientationHorizontal;
CTTextAlignment textAlignment;
@@ -179,9 +180,10 @@ Shaping getShaping(const TaggedString& formattedString,
textAlignment = kCTTextAlignmentRight;
break;
}
+ CGFloat lineHeightInEms = lineHeight / util::ONE_EM;
CTParagraphStyleSetting paragraphSettings[] = {
{ kCTParagraphStyleSpecifierAlignment, sizeof(CTTextAlignment), &textAlignment },
- { kCTParagraphStyleSpecifierLineHeightMultiple, sizeof(float), &lineHeight },
+ { kCTParagraphStyleSpecifierLineHeightMultiple, sizeof(float), &lineHeightInEms },
};
CTParagraphStyleRefHandle paragraphStyle(CTParagraphStyleCreate(paragraphSettings, sizeof(paragraphSettings) / sizeof(paragraphSettings[0])));
@@ -207,11 +209,18 @@ Shaping getShaping(const TaggedString& formattedString,
}
Shaping shaping(translate[0], translate[1], writingMode);
+ shaping.verticalizable = true;
CTFramesetterRefHandle framesetter(CTFramesetterCreateWithAttributedString(*mutableAttrString));
-// CFRange wholeStringRange = CFRangeMake(0, CFAttributedStringGetLength(*mutableAttrString));
- CGPathRefHandle path(CGPathCreateWithRect(CGRectMake(0, 0, maxWidth, CGFLOAT_MAX), NULL));
- CTFrameRefHandle frame(CTFramesetterCreateFrame(*framesetter, CFRangeMake(0, 0), *path, NULL));
+ CFRange fittingRange;
+ CGSize suggestedSize = CTFramesetterSuggestFrameSizeWithConstraints(*framesetter, CFRangeMake(0, 0), NULL, CGSizeMake(maxWidth, CGFLOAT_MAX), &fittingRange);
+ shaping.top = 0;
+ shaping.left = 0;
+ shaping.bottom = shaping.top + suggestedSize.height;
+ shaping.right = shaping.left + suggestedSize.width;
+
+ CGPathRefHandle path(CGPathCreateWithRect(CGRectMake(0, 0, suggestedSize.width, suggestedSize.height), NULL));
+ CTFrameRefHandle frame(CTFramesetterCreateFrame(*framesetter, fittingRange, *path, NULL));
CFArrayRef lines = CTFrameGetLines(*frame);
for (CFIndex i = 0; i < CFArrayGetCount(lines); i++) {
CTLineRef line = (CTLineRef)CFArrayGetValueAtIndex(lines, i);
@@ -248,14 +257,14 @@ Shaping getShaping(const TaggedString& formattedString,
Rect<uint16_t> rect = {
static_cast<unsigned short>(CGRectGetMinX(boundingRects[k])),
- static_cast<unsigned short>(CGFLOAT_MAX - CGRectGetMinY(boundingRects[k])),
+ static_cast<unsigned short>(CGRectGetMinY(boundingRects[k])),
static_cast<unsigned short>(CGRectGetWidth(boundingRects[k])),
static_cast<unsigned short>(CGRectGetHeight(boundingRects[k])),
};
GlyphMetrics metrics;
metrics.left = CGRectGetMinX(boundingRects[k]);
- metrics.top = CGFLOAT_MAX - CGRectGetMinY(boundingRects[k]);
+ metrics.top = CGRectGetMinY(boundingRects[k]);
metrics.width = CGRectGetWidth(boundingRects[k]);
metrics.height = CGRectGetHeight(boundingRects[k]);
metrics.advance = advances[k].width;