Changeset 1013

Show
Ignore:
Timestamp:
01/17/09 16:07:06 (1 year ago)
Author:
astrange
Message:

- Workaround ATS bug where newlines in the rendered text show up as other characters
- Adjust \ escape handling so I understand it
- Comment some parts of subtitles
- Fix NSArray exception on sub parse error
- Don't malloc() the breaks array every time

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/Subtitles/SubATSUIRenderer.h

    r887 r1013  
    1919        SubContext *context; 
    2020        unichar *ubuffer; 
     21        UniCharArrayOffset *breakbuffer; 
    2122        ATSUTextLayout layout; 
    2223        float screenScaleX, screenScaleY, videoWidth, videoHeight; 
  • trunk/Subtitles/SubATSUIRenderer.m

    r940 r1013  
    216216                ATSUCreateTextLayout(&layout); 
    217217                ubuffer = malloc(sizeof(unichar) * 128); 
     218                breakbuffer = malloc(sizeof(UniCharArrayOffset) * 2); 
     219                 
    218220                srgbCSpace = GetSRGBColorSpace(); 
    219221                 
     
    243245                 
    244246                ubuffer = malloc(sizeof(unichar) * 128); 
     247                breakbuffer = malloc(sizeof(UniCharArrayOffset) * 2); 
    245248                 
    246249                videoWidth = width; 
     
    260263{ 
    261264        [context release]; 
     265        free(breakbuffer); 
    262266        free(ubuffer); 
    263267        CGColorSpaceRelease(srgbCSpace); 
     
    269273-(void)finalize 
    270274{ 
     275        free(breakbuffer); 
    271276        free(ubuffer); 
    272277        UCDisposeTextBreakLocator(&breakLocator); 
     
    315320        ATSUFontID font; 
    316321         
     322        // should be kFontMicrosoftPlatform for the platform code 
     323        // but isn't for bug workarounds 
    317324        ATSUFindFontFromName(uname, nlen * sizeof(unichar), kFontFamilyName, kFontNoPlatformCode, kFontNoScript, kFontNoLanguage, &font); 
    318325         
     
    381388                SetATSUStyleOther(style, kATSUFontMatrixTag, sizeof(CGAffineTransform), &mat); 
    382389        } 
    383          
     390 
    384391        const ATSUFontFeatureType ftypes[] = {kLigaturesType, kTypographicExtrasType, kTypographicExtrasType, kTypographicExtrasType}; 
    385392        const ATSUFontFeatureSelector fsels[] = {kCommonLigaturesOnSelector, kSmartQuotesOnSelector, kPeriodsToEllipsisOnSelector, kHyphenToEnDashOnSelector}; 
    386393         
    387394        ATSUSetFontFeatures(style, sizeof(ftypes) / sizeof(ATSUFontFeatureType), ftypes, fsels); 
    388          
     395 
    389396        return style; 
    390397} 
     
    785792} 
    786793 
    787 static UniCharArrayOffset *FindLineBreaks(ATSUTextLayout layout, SubRenderDiv *div, TextBreakLocatorRef breakLocator, ItemCount *nbreaks, Fixed breakingWidth, unichar *utext, unsigned textLen) 
    788 
    789         UniCharArrayOffset *breaks; 
     794static UniCharArrayOffset *FindLineBreaks(ATSUTextLayout layout, SubRenderDiv *div, TextBreakLocatorRef breakLocator, UniCharArrayOffset *breaks, ItemCount *nbreaks, Fixed breakingWidth, unichar *utext, unsigned textLen) 
     795
    790796        ItemCount breakCount=0; 
    791797         
     
    807813        } 
    808814                 
    809         breaks = malloc(sizeof(UniCharArrayOffset) * (breakCount+2)); 
     815        breaks = realloc(breaks, sizeof(UniCharArrayOffset) * (breakCount+2)); 
    810816        ATSUGetSoftLineBreaks(layout, kATSUFromTextBeginning, kATSUToTextEnd, breakCount, &breaks[1], NULL); 
    811817         
    812818        breaks[0] = 0; 
    813819        breaks[breakCount+1] = textLen; 
    814                 
     820         
    815821        *nbreaks = breakCount; 
    816822        return breaks; 
     
    878884 
    879885static void RenderActualLine(ATSUTextLayout layout, UniCharArrayOffset thisBreak, UniCharArrayOffset lineLen, Fixed penX, Fixed penY, CGContextRef c, SubRenderDiv *div, SubATSUISpanEx *spanEx, int textType) 
    880 {        
     886
     887        //ATS bug(?) with some fonts: 
     888        //drawing \n draws some random other character, so skip them 
     889        //XXX maybe don't store newlines in div->text at all 
     890        if ([div->text characterAtIndex:thisBreak+lineLen-1] == '\n') { 
     891                lineLen--; 
     892                if (!lineLen) return; 
     893        } 
     894         
    881895        if (textType == kTextLayerOutline && div->styleLine->borderStyle == kSubBorderStyleBox) { 
    882896                ATSUTextMeasurement lineWidth, lineHeight, lineX, lineY; 
     
    917931                } else { 
    918932                        int j, spans = [div->spans count]; 
     933                         
     934                        //linear search for the next span to draw 
    919935                        for (j = 0; j < spans; j++) { 
    920936                                SubRenderSpan *span = [div->spans objectAtIndex:j]; 
     
    928944                                 
    929945                                if (spanLen == 0) continue; 
    930                                 if ((span->offset + spanLen) < thisBreak) continue; 
    931                                 if (span->offset >= nextBreak) break; 
     946                                if ((span->offset + spanLen) < thisBreak) continue; // too early 
     947                                if (span->offset >= nextBreak) break; // too far ahead 
    932948                                 
    933                                 if (span->offset < thisBreak) { 
     949                                if (span->offset < thisBreak) { // text spans a newline 
    934950                                        drawStart = thisBreak; 
    935951                                        drawLen = spanLen - (thisBreak - span->offset); 
     
    938954                                        drawLen = spanLen; 
    939955                                } 
    940                                  
     956 
    941957                                endLayer = SetupCGForSpan(c, spanEx, lastSpanEx, div, textType, endLayer); 
    942958                                RenderActualLine(layout, drawStart, drawLen, (textType == kTextLayerShadow) ? (penX + FloatToFixed(spanEx->shadowDist)) : penX,  
     
    10051021                unsigned textLen = [div->text length]; 
    10061022                BOOL resetPens = NO; 
    1007                 if (!textLen) continue; 
    1008                  
     1023                if (!textLen || ![div->spans count]) continue; 
     1024                                                
    10091025                if (div->layer != lastLayer) { 
    10101026                        resetPens = YES; 
     
    10191035                marginRect.size.height *= screenScaleY; 
    10201036 
    1021                 Fixed penY, penX, breakingWidth = FloatToFixed(marginRect.size.width); BreakContext breakc = {0}; 
     1037                Fixed penY, penX, breakingWidth = FloatToFixed(marginRect.size.width); 
     1038                BreakContext breakc = {0}; ItemCount breakCount; 
    10221039 
    10231040                [div->text getCharacters:ubuffer]; 
     
    10291046                SetStyleSpanRuns(layout, div); 
    10301047                 
    1031                 ItemCount breakCount
    1032                 UniCharArrayOffset *breaks = FindLineBreaks(layout, div, breakLocator, &breakCount, breakingWidth, ubuffer, textLen); 
     1048                breakbuffer = FindLineBreaks(layout, div, breakLocator, breakbuffer, &breakCount, breakingWidth, ubuffer, textLen)
     1049 
    10331050                ATSUTextMeasurement imageWidth, imageHeight; 
    1034  
    1035                 if (div->positioned || div->alignV == kSubAlignmentMiddle) GetTypographicRectangleForLayout(layout, breaks, breakCount, FloatToFixed(div->styleLine->outlineRadius), NULL, NULL, &imageHeight, &imageWidth); 
     1051                UniCharArrayOffset *breaks = breakbuffer; 
     1052 
     1053                if (div->positioned || div->alignV == kSubAlignmentMiddle) 
     1054                        GetTypographicRectangleForLayout(layout, breaks, breakCount, FloatToFixed(div->styleLine->outlineRadius), NULL, NULL, &imageHeight, &imageWidth); 
    10361055 
    10371056                if (!div->positioned) { 
     
    10991118                 
    11001119                if (storePen) *storePen = penY; 
    1101                  
    1102                 free(breaks); 
    11031120        } 
    11041121         
  • trunk/Subtitles/SubParsing.m.rl

    r988 r1013  
    397397 
    398398                                action backslash_handler { 
    399                                         [div->text appendString:send()];                                         
     399                                        p--; 
     400                                        [div->text appendString:send()]; 
    400401                                        unichar c = *(p+1), o=c; 
    401402                                         
     
    408409                                                                o = 0xA0; //non-breaking space 
    409410                                                                break; 
    410                                                         default: 
    411                                                                 o = c; 
    412411                                                } 
    413                                         } 
    414                                          
    415                                         [div->text appendFormat:@"%C",o]; 
     412                                                
     413                                               [div->text appendFormat:@"%C",o]; 
     414                                        } 
    416415                                         
    417416                                        chars_deleted++; 
    418417                                         
    419                                         outputbegin = p+2; 
     418                                        p++; 
     419                                        outputbegin = p+1; 
    420420                                } 
    421421                                 
     
    449449                                } 
    450450                                                                 
    451                                 special = ("\\" any) >backslash_handler | tag >enter_tag @exit_tag; 
     451                                special = ("\\" :> any) @backslash_handler | tag >enter_tag @exit_tag; 
    452452                                sub_text_char = [^\\{]; 
    453453                                sub_text = sub_text_char*;