Changeset 1208
- Timestamp:
- 11/23/09 23:25:15 (9 months ago)
- Location:
- trunk/Subtitles
- Files:
-
- 3 modified
-
SubATSUIRenderer.m (modified) (17 diffs)
-
SubContext.h (modified) (1 diff)
-
SubContext.m (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Subtitles/SubATSUIRenderer.m
r1204 r1208 30 30 static float GetWinFontSizeScale(ATSFontRef font); 31 31 static void FindAllPossibleLineBreaks(TextBreakLocatorRef breakLocator, const unichar *uline, UniCharArrayOffset lineLen, unsigned char *breakOpportunities); 32 static ATSUFontID GetFontIDForSSAName(NSString *name); 32 33 33 34 #define declare_bitfield(name, bits) unsigned char name[bits / 8 + 1]; bzero(name, sizeof(name)); … … 40 41 CGColorRef primaryColor, outlineColor, shadowColor; 41 42 Float32 outlineRadius, shadowDist, scaleX, scaleY, primaryAlpha, outlineAlpha, angle, platformSizeScale, fontSize; 42 BOOL blurEdges ;43 BOOL blurEdges, vertical; 43 44 ATSUFontID font; 44 ATSUVerticalCharacterType fontVertical;45 45 } 46 46 -(SubATSUISpanEx*)initWithStyle:(ATSUStyle)style_ subStyle:(SubStyle*)sstyle colorSpace:(CGColorSpaceRef)cs; … … 89 89 90 90 -(SubATSUISpanEx*)initWithStyle:(ATSUStyle)style_ subStyle:(SubStyle*)sstyle colorSpace:(CGColorSpaceRef)cs 91 { 92 ByteCount unused; 93 91 { 94 92 if (self = [super init]) { 95 93 ATSUCreateAndCopyStyle(style_, &style); … … 107 105 platformSizeScale = sstyle->platformSizeScale; 108 106 fontSize = sstyle->size; 109 ATSUGetAttribute(style, kATSUFontTag, sizeof(ATSUFontID), &font, &unused);110 ATSUGetAttribute(style, kATSUVerticalCharacterTag, sizeof(ATSUVerticalCharacterType), &fontVertical, &unused);107 vertical = sstyle->vertical; 108 font = GetFontIDForSSAName(sstyle->fontname); 111 109 } 112 110 … … 132 130 ret->fontSize = fontSize; 133 131 ret->font = font; 134 ret->fontVertical = fontVertical; 132 ret->blurEdges = blurEdges; 133 ret->vertical = vertical; 135 134 136 135 return ret; … … 342 341 -(void*)completedStyleParsing:(SubStyle*)s 343 342 { 344 const ATSUAttributeTag tags[] = {kATSUStyleRenderingOptionsTag, kATSUSizeTag, kATSUQDBoldfaceTag, kATSUQDItalicTag, kATSUQDUnderlineTag, kATSUStyleStrikeThroughTag, kATSUFontTag , kATSUVerticalCharacterTag};345 const ByteCount sizes[] = {sizeof(ATSStyleRenderingOptions), sizeof(Fixed), sizeof(Boolean), sizeof(Boolean), sizeof(Boolean), sizeof(Boolean), sizeof(ATSUFontID) , sizeof(ATSUVerticalCharacterType)};343 const ATSUAttributeTag tags[] = {kATSUStyleRenderingOptionsTag, kATSUSizeTag, kATSUQDBoldfaceTag, kATSUQDItalicTag, kATSUQDUnderlineTag, kATSUStyleStrikeThroughTag, kATSUFontTag}; 344 const ByteCount sizes[] = {sizeof(ATSStyleRenderingOptions), sizeof(Fixed), sizeof(Boolean), sizeof(Boolean), sizeof(Boolean), sizeof(Boolean), sizeof(ATSUFontID)}; 346 345 347 346 NSString *fn = s->fontname; 348 ATSUVerticalCharacterType vertical = ParseFontVerticality(&fn) ? kATSUStronglyVertical : kATSUStronglyHorizontal;349 347 ATSUFontID font = GetFontIDForSSAName(fn); 350 348 ATSFontRef fontRef = font; … … 354 352 ATSUStyle style; 355 353 356 const ATSUAttributeValuePtr vals[] = {&opt, &size, &b, &i, &u, &st, &font , &vertical};354 const ATSUAttributeValuePtr vals[] = {&opt, &size, &b, &i, &u, &st, &font}; 357 355 358 356 if (!s->platformSizeScale) s->platformSizeScale = GetWinFontSizeScale(fontRef); … … 413 411 Fixed fSize = FloatToFixed(spanEx->fontSize * spanEx->platformSizeScale * screenScale); 414 412 SetATSUStyleOther(spanEx->style, kATSUFontTag, sizeof(ATSUFontID), &spanEx->font); 415 SetATSUStyleOther(spanEx->style, kATSUVerticalCharacterTag, sizeof(ATSUVerticalCharacterType), &spanEx->fontVertical);416 413 SetATSUStyleOther(spanEx->style, kATSUSizeTag, sizeof(Fixed), &fSize); 417 414 } … … 471 468 sv(); 472 469 oldFont = spanEx->font; 473 spanEx-> fontVertical = ParseFontVerticality(&sval) ? kATSUStronglyVertical : kATSUStronglyHorizontal;470 spanEx->vertical = ParseFontVerticality(&sval); 474 471 spanEx->font = GetFontIDForSSAName(sval); 475 472 if (oldFont != spanEx->font) spanEx->platformSizeScale = GetWinFontSizeScale(spanEx->font); … … 695 692 } 696 693 697 static void SetStyleSpanRuns(ATSUTextLayout layout, SubRenderDiv *div) 694 static void MakeRunVertical(ATSUTextLayout layout, UniCharArrayOffset spanOffset, UniCharArrayOffset length) 695 { 696 ATSUStyle style, vStyle; 697 ATSUVerticalCharacterType vertical = kATSUStronglyVertical; 698 699 ATSUGetRunStyle(layout, spanOffset, &style, NULL, NULL); 700 ATSUCreateAndCopyStyle(style, &vStyle); 701 SetATSUStyleOther(vStyle, kATSUVerticalCharacterTag, sizeof(vertical), &vertical); 702 ATSUSetRunStyle(layout, vStyle, spanOffset, length); 703 ATSUDisposeStyle(vStyle); 704 } 705 706 static void EnableVerticalForSpan(ATSUTextLayout layout, SubRenderDiv *div, const unichar *ubuffer, UniCharArrayOffset spanOffset, UniCharArrayOffset length) 707 { 708 const unichar tategakiLowerBound = 0x02F1; // copied from http://source.winehq.org/source/dlls/gdi32/freetype.c 709 int runStart, runAboveBound, i; 710 711 runStart = spanOffset; 712 runAboveBound = ubuffer[spanOffset] >= tategakiLowerBound; 713 714 for (i = spanOffset+1; i < spanOffset + length; i++) { 715 int isAboveBound = ubuffer[i] >= tategakiLowerBound; 716 717 if (isAboveBound != runAboveBound) { 718 if (runAboveBound) 719 MakeRunVertical(layout, runStart, i - runStart); 720 runStart = i; 721 isAboveBound = runAboveBound; 722 } 723 } 724 725 if (runAboveBound) 726 MakeRunVertical(layout, runStart, i - runStart); 727 } 728 729 static void SetStyleSpanRuns(ATSUTextLayout layout, SubRenderDiv *div, const unichar *ubuffer) 698 730 { 699 731 unsigned span_count = [div->spans count]; … … 702 734 for (i = 0; i < span_count; i++) { 703 735 SubRenderSpan *span = [div->spans objectAtIndex:i]; 704 UniCharArrayOffset next = (i == span_count-1) ? [div->text length] : ((SubRenderSpan*)[div->spans objectAtIndex:i+1])->offset; 705 ATSUSetRunStyle(layout, span_ex(span)->style, span->offset, next - span->offset); 736 UniCharArrayOffset next = (i == span_count-1) ? [div->text length] : ((SubRenderSpan*)[div->spans objectAtIndex:i+1])->offset, spanLen = next - span->offset; 737 SubATSUISpanEx *ex = span->ex; 738 739 ATSUSetRunStyle(layout, ex->style, span->offset, spanLen); 740 741 if (ex->vertical) { 742 EnableVerticalForSpan(layout, div, ubuffer, span->offset, spanLen); 743 } 706 744 } 707 745 } … … 1052 1090 unsigned textLen = [div->text length]; 1053 1091 if (!textLen || ![div->spans count]) continue; 1054 BOOL resetPens = NO ;1092 BOOL resetPens = NO, resetGState = NO; 1055 1093 NSData *ubufferData; 1056 1094 const unichar *ubuffer = STUnicodeForString(div->text, &ubufferData); … … 1062 1100 1063 1101 //NSLog(@"%@", div); 1064 1102 1065 1103 NSRect marginRect = NSMakeRect(div->marginL, div->marginV, context->resX - div->marginL - div->marginR, context->resY - div->marginV - div->marginV); 1066 1104 … … 1077 1115 1078 1116 SetLayoutPositioning(layout, breakingWidth, div->alignH); 1079 SetStyleSpanRuns(layout, div );1117 SetStyleSpanRuns(layout, div, ubuffer); 1080 1118 1081 1119 breakbuffer = FindLineBreaks(layout, div, breakLocator, breakbuffer, &breakCount, breakingWidth, ubuffer, textLen); … … 1114 1152 case kSubAlignmentMiddle: 1115 1153 if (!centerPen || resetPens) { 1116 penY = (FloatToFixed(NSMidY(marginRect)) / 2) + (imageHeight / 2);1154 penY = FloatToFixed(NSMidY(marginRect)) - (imageHeight / 2) + descent; 1117 1155 } else penY = centerPen; 1118 1156 … … 1147 1185 } 1148 1186 1149 { 1150 SubATSUISpanEx *firstspan = ((SubRenderSpan*)[div->spans objectAtIndex:0])->ex; 1187 SubATSUISpanEx *firstspan = ((SubRenderSpan*)[div->spans objectAtIndex:0])->ex; 1188 1189 // FIXME: we can only rotate an entire line at once 1190 if (firstspan->angle) { 1151 1191 Fixed fangle = FloatToFixed(firstspan->angle); 1192 SetATSULayoutOther(layout, kATSULineRotationTag, sizeof(Fixed), &fangle); 1152 1193 1153 SetATSULayoutOther(layout, kATSULineRotationTag, sizeof(Fixed), &fangle); 1194 // FIXME: awful hack for SSA vertical text idiom 1195 // instead it needs to rotate text by hand or actually fix ATSUI's rotation origin 1196 if (firstspan->vertical && 1197 div->alignV == kSubAlignmentMiddle && div->alignH == kSubAlignmentCenter) { 1198 CGContextSaveGState(c); 1199 CGContextTranslateCTM(c, FixedToFloat(imageWidth)/2, FixedToFloat(imageWidth)/2); 1200 resetGState = YES; 1201 } 1154 1202 } 1155 1203 … … 1161 1209 1162 1210 penY = DrawOneTextDiv(c, layout, div, breakc, penX, penY); 1211 1212 if (resetGState) 1213 CGContextRestoreGState(c); 1163 1214 1164 1215 [ubufferData release]; -
trunk/Subtitles/SubContext.h
r1140 r1208 45 45 unsigned marginL, marginR, marginV; 46 46 Float32 weight; // 0/1 = not bold/bold, > 1 is a font weight 47 BOOL italic, underline, strikeout ;47 BOOL italic, underline, strikeout, vertical; 48 48 UInt8 alignH, alignV, borderStyle; 49 49 __strong void* ex; -
trunk/Subtitles/SubContext.m
r1206 r1208 83 83 if ([*fontname characterAtIndex:0] == '@') { 84 84 *fontname = [*fontname substringFromIndex:1]; 85 //return YES; // XXX vertical85 return YES; 86 86 } 87 87 return NO; … … 160 160 ParseASSAlignment(align, &alignH, &alignV); 161 161 162 tmp = fontname; 163 vertical = ParseFontVerticality(&tmp); 164 if (vertical) 165 fontname = [tmp retain]; 166 162 167 platformSizeScale = 0; 163 168 ex = [delegate completedStyleParsing:self];
