Changeset 1098

Show
Ignore:
Timestamp:
07/09/09 23:22:14 (13 months ago)
Author:
astrange
Message:

SSA:
- Fix the font size scale when \fn changes it.
- Slightly quicker lookup for nonexistant fonts.
- Add a debug hook to draw text bounds.

Location:
trunk/Subtitles
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • trunk/Subtitles/SubATSUIRenderer.h

    r1046 r1098  
    3434        ATSUTextLayout layout; 
    3535        float screenScaleX, screenScaleY, videoWidth, videoHeight; 
     36        BOOL drawTextBounds; 
    3637        @public; 
    3738        CGColorSpaceRef srgbCSpace; 
  • trunk/Subtitles/SubATSUIRenderer.m

    r1086 r1098  
    2525#import "SubUtilities.h" 
    2626#import "Codecprintf.h" 
     27#import "CommonUtils.h" 
    2728 
    2829static float GetWinFontSizeScale(ATSFontRef font); 
     
    254255                UCCreateTextBreakLocator(NULL, 0, kUCTextBreakLineMask, &breakLocator); 
    255256                context = [[SubContext alloc] initWithNonSSAType:kSubTypeSRT delegate:self]; 
     257                 
     258                drawTextBounds = CFPreferencesGetAppBooleanValue(CFSTR("DrawSubTextBounds"), PERIAN_PREF_DOMAIN, NULL); 
    256259        } 
    257260         
     
    278281                UCCreateTextBreakLocator(NULL, 0, kUCTextBreakLineMask, &breakLocator); 
    279282                context = [[SubContext alloc] initWithHeaders:headers styles:styles delegate:self]; 
     283                 
     284                drawTextBounds = CFPreferencesGetAppBooleanValue(CFSTR("DrawSubTextBounds"), PERIAN_PREF_DOMAIN, NULL); 
    280285        } 
    281286         
     
    365370                                break; 
    366371                        } 
    367                 } 
    368                  
    369                 if (font == kATSUInvalidFontID) font = ATSFontFindFromName((CFStringRef)@"Helvetica",kATSOptionFlagsDefault); // final fallback 
    370         } 
     372                }                
     373        } 
     374         
     375        if (font == kATSUInvalidFontID && ![name isEqualToString:@"Helvetica"]) 
     376                font = GetFontIDForSSAName(@"Helvetica"); // final fallback 
    371377         
    372378        [fontIDCache setValue:[NSNumber numberWithInt:font] forKey:[name lowercaseString]]; 
     
    467473        CGColorRef color; 
    468474        CGAffineTransform mat; 
     475        ATSFontRef oldFont; 
    469476         
    470477#define bv() bval = *(int*)p; 
     
    504511                case tag_fn: 
    505512                        sv(); 
     513                        oldFont = spanEx->font; 
    506514                        spanEx->fontVertical = ParseFontVerticality(&sval) ? kATSUStronglyVertical : kATSUStronglyHorizontal; 
    507515                        spanEx->font = GetFontIDForSSAName(sval); 
     516                        if (oldFont != spanEx->font) spanEx->platformSizeScale = GetWinFontSizeScale(spanEx->font); 
    508517                        UpdateFontNameSize(spanEx, screenScaleY); 
    509518                        break; 
     
    600609#pragma mark Rendering Helper Functions 
    601610 
     611// XXX see comment for GetTypographicRectangleForLayout 
    602612static ATSUTextMeasurement GetLineHeight(ATSUTextLayout layout, UniCharArrayOffset lpos) 
    603613{ 
     
    618628} 
    619629 
     630// XXX some broken fonts have very wrong typographic values set, and so this occasionally gives nonsense 
     631// it should be checked against the real pixel box (see #if 0 below), but for correct fonts it looks much better 
    620632static void GetTypographicRectangleForLayout(ATSUTextLayout layout, UniCharArrayOffset *breaks, ItemCount breakCount, Fixed extraHeight, Fixed *lX, Fixed *lY, Fixed *height, Fixed *width) 
    621633{ 
     
    653665} 
    654666 
     667// Draw the text bounds on screen under the actual text 
     668// Note that it almost never appears where it's supposed to be, and I'm not sure if that's my fault or ATSUI's 
     669static void VisualizeLayoutLineHeights(CGContextRef c, ATSUTextLayout layout, UniCharArrayOffset *breaks, ItemCount breakCount, Fixed extraHeight, Fixed penX, Fixed penY, float screenHeight) 
     670{ 
     671        ATSTrapezoid trap = {0}; 
     672        Rect pixRect = {0}; 
     673        ItemCount trapCount; 
     674        int i; 
     675         
     676        CGContextSetLineWidth(c, 3.0); 
     677         
     678        for (i = breakCount; i >= 0; i--) { 
     679                UniCharArrayOffset end = breaks[i+1]; 
     680 
     681                ATSUMeasureTextImage(layout, breaks[i], end-breaks[i], 0, 0, &pixRect); 
     682                ATSUGetGlyphBounds(layout, 0, 0, breaks[i], end-breaks[i], kATSUseDeviceOrigins, 1, &trap, &trapCount); 
     683                 
     684                CGContextSetRGBStrokeColor(c, 1,0,0,1); 
     685                CGContextBeginPath(c); 
     686                CGContextMoveToPoint(c, FixedToFloat(penX + trap.upperLeft.x),  FixedToFloat(penY + trap.lowerLeft.y)); 
     687                CGContextAddLineToPoint(c, FixedToFloat(penX + trap.upperRight.x),  FixedToFloat(penY + trap.lowerRight.y)); 
     688                CGContextAddLineToPoint(c, FixedToFloat(penX + trap.lowerRight.x),  FixedToFloat(penY + trap.upperRight.y)); 
     689                CGContextAddLineToPoint(c, FixedToFloat(penX + trap.lowerLeft.x),  FixedToFloat(penY + trap.upperLeft.y)); 
     690                CGContextClosePath(c); 
     691                CGContextStrokePath(c); 
     692                CGContextSetRGBStrokeColor(c, 0, 0, 1, 1); 
     693                CGContextStrokeRect(c, CGRectMake(FixedToFloat(penX) + pixRect.left, FixedToFloat(penY) + pixRect.top, pixRect.right - pixRect.left, pixRect.bottom - pixRect.top)); 
     694                 
     695                penY += GetLineHeight(layout, breaks[i]) + extraHeight; 
     696        } 
     697} 
     698 
    655699#if 0 
    656700static void GetImageBoundingBoxForLayout(ATSUTextLayout layout, UniCharArrayOffset *breaks, ItemCount breakCount, Fixed extraHeight, Fixed *lX, Fixed *lY, Fixed *height, Fixed *width) 
     
    674718                largeRect.top = MIN(largeRect.top, rect.top); 
    675719                largeRect.right = MAX(largeRect.right, rect.right); 
    676                         } 
     720        } 
    677721         
    678722         
     
    10751119                breakbuffer = FindLineBreaks(layout, div, breakLocator, breakbuffer, &breakCount, breakingWidth, ubuffer, textLen); 
    10761120 
    1077                 ATSUTextMeasurement imageWidth, imageHeight; 
     1121                ATSUTextMeasurement imageWidth, imageHeight, descent; 
    10781122                UniCharArrayOffset *breaks = breakbuffer; 
    1079  
     1123                 
    10801124                if (div->positioned || div->alignV == kSubAlignmentMiddle) 
    10811125                        GetTypographicRectangleForLayout(layout, breaks, breakCount, FloatToFixed(div->styleLine->outlineRadius), NULL, NULL, &imageHeight, &imageWidth); 
    1082  
     1126                 
     1127                if (div->positioned || div->alignV == kSubAlignmentBottom) 
     1128                        ATSUGetLineControl(layout, kATSUFromTextBeginning, kATSULineDescentTag, sizeof(ATSUTextMeasurement), &descent, NULL); 
     1129                 
     1130#if 0 
     1131                { 
     1132                        ATSUTextMeasurement ascent, descent; 
     1133                         
     1134                        ATSUGetLineControl(layout, kATSUFromTextBeginning, kATSULineAscentTag,  sizeof(ATSUTextMeasurement), &ascent,  NULL); 
     1135                        ATSUGetLineControl(layout, kATSUFromTextBeginning, kATSULineDescentTag, sizeof(ATSUTextMeasurement), &descent, NULL); 
     1136                         
     1137                        NSLog(@"\"%@\" descent %f ascent %f\n", div->text, FixedToFloat(descent), FixedToFloat(ascent)); 
     1138                } 
     1139#endif 
     1140                 
    10831141                if (!div->positioned) { 
    10841142                        penX = FloatToFixed(NSMinX(marginRect)); 
     
    10871145                                case kSubAlignmentBottom: default: 
    10881146                                        if (!bottomPen || resetPens) { 
    1089                                                 ATSUTextMeasurement bottomLineDescent; 
    1090                                                 ATSUGetLineControl(layout, kATSUFromTextBeginning, kATSULineDescentTag, sizeof(ATSUTextMeasurement), &bottomLineDescent, NULL); 
    1091                                                 penY = FloatToFixed(NSMinY(marginRect)) + bottomLineDescent; 
     1147                                                penY = FloatToFixed(NSMinY(marginRect)) + descent; 
    10921148                                        } else penY = bottomPen; 
    10931149                                         
     
    11101166                        } 
    11111167                } else { 
    1112                         ATSUTextMeasurement descent; 
    11131168                        penX = FloatToFixed(div->posX * screenScaleX); 
    11141169                        penY = FloatToFixed((context->resY - div->posY) * screenScaleY); 
     
    11191174                        } 
    11201175                         
    1121                         ATSUGetLineControl(layout, kATSUFromTextBeginning, kATSULineDescentTag, sizeof(ATSUTextMeasurement), &descent, NULL); 
    1122  
    11231176                        switch (div->alignV) { 
    11241177                                case kSubAlignmentMiddle: penY -= imageHeight / 2; break; 
     
    11391192                } 
    11401193                 
     1194                if (drawTextBounds) 
     1195                        VisualizeLayoutLineHeights(c, layout, breaks, breakCount, FloatToFixed(div->styleLine->outlineRadius), penX, penY, cHeight); 
     1196 
    11411197                breakc.breakCount = breakCount; 
    11421198                breakc.breaks = breaks; 
     
    13061362 
    13071363// Windows and OS X use different TrueType fields to measure text. 
    1308 // Some Windows fonts have one field set incorrectly, so we have to compensate. 
     1364// Some Windows fonts have one field set incorrectly(?), so we have to compensate. 
    13091365// XXX This function doesn't read from the right fonts; if we're using italic variant, it should get the ATSFontRef for that 
     1366// XXX^2 This should be cached 
    13101367static float GetWinFontSizeScale(ATSFontRef font) 
    13111368{