diff options
author | Minh Nguyễn <mxn@1ec5.org> | 2020-04-20 16:51:21 -0700 |
---|---|---|
committer | Minh Nguyễn <mxn@1ec5.org> | 2020-04-22 21:28:30 -0700 |
commit | 1c93b8622d3bc2800086d89c549c91bde445497b (patch) | |
tree | 0101e369b7d5acd7d936f2b1d936671e0b7253d1 | |
parent | 98427268c5f2b6e669b7e564cf450e79d374cca7 (diff) | |
download | qtlocation-mapboxgl-1c93b8622d3bc2800086d89c549c91bde445497b.tar.gz |
[ios, macos] Fixed bounding boxes
-rw-r--r-- | platform/darwin/src/local_glyph_rasterizer.mm | 18 | ||||
-rw-r--r-- | platform/darwin/src/shaping.mm | 25 |
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; |